Path: blob/main/sys/contrib/dev/mediatek/mt76/mt7915/mmio.c
108088 views
// SPDX-License-Identifier: BSD-3-Clause-Clear1/* Copyright (C) 2020 MediaTek Inc. */23#if defined(__FreeBSD__)4#define LINUXKPI_PARAM_PREFIX mt7915_5#endif67#include <linux/kernel.h>8#include <linux/module.h>9#include <linux/platform_device.h>10#include <linux/rtnetlink.h>11#include <linux/pci.h>1213#include "mt7915.h"14#include "mac.h"15#include "mcu.h"16#include "../trace.h"17#include "../dma.h"1819static bool wed_enable;20module_param(wed_enable, bool, 0644);21MODULE_PARM_DESC(wed_enable, "Enable Wireless Ethernet Dispatch support");2223static const u32 mt7915_reg[] = {24[INT_SOURCE_CSR] = 0xd7010,25[INT_MASK_CSR] = 0xd7014,26[INT1_SOURCE_CSR] = 0xd7088,27[INT1_MASK_CSR] = 0xd708c,28[INT_MCU_CMD_SOURCE] = 0xd51f0,29[INT_MCU_CMD_EVENT] = 0x3108,30[WFDMA0_ADDR] = 0xd4000,31[WFDMA0_PCIE1_ADDR] = 0xd8000,32[WFDMA_EXT_CSR_ADDR] = 0xd7000,33[CBTOP1_PHY_END] = 0x77ffffff,34[INFRA_MCU_ADDR_END] = 0x7c3fffff,35[FW_ASSERT_STAT_ADDR] = 0x219848,36[FW_EXCEPT_TYPE_ADDR] = 0x21987c,37[FW_EXCEPT_COUNT_ADDR] = 0x219848,38[FW_CIRQ_COUNT_ADDR] = 0x216f94,39[FW_CIRQ_IDX_ADDR] = 0x216ef8,40[FW_CIRQ_LISR_ADDR] = 0x2170ac,41[FW_TASK_ID_ADDR] = 0x216f90,42[FW_TASK_IDX_ADDR] = 0x216f9c,43[FW_TASK_QID1_ADDR] = 0x219680,44[FW_TASK_QID2_ADDR] = 0x219760,45[FW_TASK_START_ADDR] = 0x219558,46[FW_TASK_END_ADDR] = 0x219554,47[FW_TASK_SIZE_ADDR] = 0x219560,48[FW_LAST_MSG_ID_ADDR] = 0x216f70,49[FW_EINT_INFO_ADDR] = 0x219818,50[FW_SCHED_INFO_ADDR] = 0x219828,51[SWDEF_BASE_ADDR] = 0x41f200,52[TXQ_WED_RING_BASE] = 0xd7300,53[RXQ_WED_RING_BASE] = 0xd7410,54[RXQ_WED_DATA_RING_BASE] = 0xd4500,55};5657static const u32 mt7916_reg[] = {58[INT_SOURCE_CSR] = 0xd4200,59[INT_MASK_CSR] = 0xd4204,60[INT1_SOURCE_CSR] = 0xd8200,61[INT1_MASK_CSR] = 0xd8204,62[INT_MCU_CMD_SOURCE] = 0xd41f0,63[INT_MCU_CMD_EVENT] = 0x2108,64[WFDMA0_ADDR] = 0xd4000,65[WFDMA0_PCIE1_ADDR] = 0xd8000,66[WFDMA_EXT_CSR_ADDR] = 0xd7000,67[CBTOP1_PHY_END] = 0x7fffffff,68[INFRA_MCU_ADDR_END] = 0x7c085fff,69[FW_ASSERT_STAT_ADDR] = 0x02204c14,70[FW_EXCEPT_TYPE_ADDR] = 0x022051a4,71[FW_EXCEPT_COUNT_ADDR] = 0x022050bc,72[FW_CIRQ_COUNT_ADDR] = 0x022001ac,73[FW_CIRQ_IDX_ADDR] = 0x02204f84,74[FW_CIRQ_LISR_ADDR] = 0x022050d0,75[FW_TASK_ID_ADDR] = 0x0220406c,76[FW_TASK_IDX_ADDR] = 0x0220500c,77[FW_TASK_QID1_ADDR] = 0x022028c8,78[FW_TASK_QID2_ADDR] = 0x02202a38,79[FW_TASK_START_ADDR] = 0x0220286c,80[FW_TASK_END_ADDR] = 0x02202870,81[FW_TASK_SIZE_ADDR] = 0x02202878,82[FW_LAST_MSG_ID_ADDR] = 0x02204fe8,83[FW_EINT_INFO_ADDR] = 0x0220525c,84[FW_SCHED_INFO_ADDR] = 0x0220516c,85[SWDEF_BASE_ADDR] = 0x411400,86[TXQ_WED_RING_BASE] = 0xd7300,87[RXQ_WED_RING_BASE] = 0xd7410,88[RXQ_WED_DATA_RING_BASE] = 0xd4540,89};9091static const u32 mt7986_reg[] = {92[INT_SOURCE_CSR] = 0x24200,93[INT_MASK_CSR] = 0x24204,94[INT1_SOURCE_CSR] = 0x28200,95[INT1_MASK_CSR] = 0x28204,96[INT_MCU_CMD_SOURCE] = 0x241f0,97[INT_MCU_CMD_EVENT] = 0x54000108,98[WFDMA0_ADDR] = 0x24000,99[WFDMA0_PCIE1_ADDR] = 0x28000,100[WFDMA_EXT_CSR_ADDR] = 0x27000,101[CBTOP1_PHY_END] = 0x7fffffff,102[INFRA_MCU_ADDR_END] = 0x7c085fff,103[FW_ASSERT_STAT_ADDR] = 0x02204b54,104[FW_EXCEPT_TYPE_ADDR] = 0x022050dc,105[FW_EXCEPT_COUNT_ADDR] = 0x02204ffc,106[FW_CIRQ_COUNT_ADDR] = 0x022001ac,107[FW_CIRQ_IDX_ADDR] = 0x02204ec4,108[FW_CIRQ_LISR_ADDR] = 0x02205010,109[FW_TASK_ID_ADDR] = 0x02204fac,110[FW_TASK_IDX_ADDR] = 0x02204f4c,111[FW_TASK_QID1_ADDR] = 0x02202814,112[FW_TASK_QID2_ADDR] = 0x02202984,113[FW_TASK_START_ADDR] = 0x022027b8,114[FW_TASK_END_ADDR] = 0x022027bc,115[FW_TASK_SIZE_ADDR] = 0x022027c4,116[FW_LAST_MSG_ID_ADDR] = 0x02204f28,117[FW_EINT_INFO_ADDR] = 0x02205194,118[FW_SCHED_INFO_ADDR] = 0x022051a4,119[SWDEF_BASE_ADDR] = 0x411400,120[TXQ_WED_RING_BASE] = 0x24420,121[RXQ_WED_RING_BASE] = 0x24520,122[RXQ_WED_DATA_RING_BASE] = 0x24540,123};124125static const u32 mt7915_offs[] = {126[TMAC_CDTR] = 0x090,127[TMAC_ODTR] = 0x094,128[TMAC_ATCR] = 0x098,129[TMAC_TRCR0] = 0x09c,130[TMAC_ICR0] = 0x0a4,131[TMAC_ICR1] = 0x0b4,132[TMAC_CTCR0] = 0x0f4,133[TMAC_TFCR0] = 0x1e0,134[MDP_BNRCFR0] = 0x070,135[MDP_BNRCFR1] = 0x074,136[ARB_DRNGR0] = 0x194,137[ARB_SCR] = 0x080,138[RMAC_MIB_AIRTIME14] = 0x3b8,139[AGG_AWSCR0] = 0x05c,140[AGG_PCR0] = 0x06c,141[AGG_ACR0] = 0x084,142[AGG_ACR4] = 0x08c,143[AGG_MRCR] = 0x098,144[AGG_ATCR0] = 0x0ec,145[AGG_ATCR1] = 0x0f0,146[AGG_ATCR3] = 0x0f4,147[LPON_UTTR0] = 0x080,148[LPON_UTTR1] = 0x084,149[LPON_FRCR] = 0x314,150[MIB_SDR3] = 0x014,151[MIB_SDR4] = 0x018,152[MIB_SDR5] = 0x01c,153[MIB_SDR7] = 0x024,154[MIB_SDR8] = 0x028,155[MIB_SDR9] = 0x02c,156[MIB_SDR10] = 0x030,157[MIB_SDR11] = 0x034,158[MIB_SDR12] = 0x038,159[MIB_SDR13] = 0x03c,160[MIB_SDR14] = 0x040,161[MIB_SDR15] = 0x044,162[MIB_SDR16] = 0x048,163[MIB_SDR17] = 0x04c,164[MIB_SDR18] = 0x050,165[MIB_SDR19] = 0x054,166[MIB_SDR20] = 0x058,167[MIB_SDR21] = 0x05c,168[MIB_SDR22] = 0x060,169[MIB_SDR23] = 0x064,170[MIB_SDR24] = 0x068,171[MIB_SDR25] = 0x06c,172[MIB_SDR27] = 0x074,173[MIB_SDR28] = 0x078,174[MIB_SDR29] = 0x07c,175[MIB_SDRVEC] = 0x080,176[MIB_SDR31] = 0x084,177[MIB_SDR32] = 0x088,178[MIB_SDRMUBF] = 0x090,179[MIB_DR8] = 0x0c0,180[MIB_DR9] = 0x0c4,181[MIB_DR11] = 0x0cc,182[MIB_MB_SDR0] = 0x100,183[MIB_MB_SDR1] = 0x104,184[TX_AGG_CNT] = 0x0a8,185[TX_AGG_CNT2] = 0x164,186[MIB_ARNG] = 0x4b8,187[WTBLON_TOP_WDUCR] = 0x0,188[WTBL_UPDATE] = 0x030,189[PLE_FL_Q_EMPTY] = 0x0b0,190[PLE_FL_Q_CTRL] = 0x1b0,191[PLE_AC_QEMPTY] = 0x500,192[PLE_FREEPG_CNT] = 0x100,193[PLE_FREEPG_HEAD_TAIL] = 0x104,194[PLE_PG_HIF_GROUP] = 0x110,195[PLE_HIF_PG_INFO] = 0x114,196[AC_OFFSET] = 0x040,197[ETBF_PAR_RPT0] = 0x068,198};199200static const u32 mt7916_offs[] = {201[TMAC_CDTR] = 0x0c8,202[TMAC_ODTR] = 0x0cc,203[TMAC_ATCR] = 0x00c,204[TMAC_TRCR0] = 0x010,205[TMAC_ICR0] = 0x014,206[TMAC_ICR1] = 0x018,207[TMAC_CTCR0] = 0x114,208[TMAC_TFCR0] = 0x0e4,209[MDP_BNRCFR0] = 0x090,210[MDP_BNRCFR1] = 0x094,211[ARB_DRNGR0] = 0x1e0,212[ARB_SCR] = 0x000,213[RMAC_MIB_AIRTIME14] = 0x0398,214[AGG_AWSCR0] = 0x030,215[AGG_PCR0] = 0x040,216[AGG_ACR0] = 0x054,217[AGG_ACR4] = 0x05c,218[AGG_MRCR] = 0x068,219[AGG_ATCR0] = 0x1a4,220[AGG_ATCR1] = 0x1a8,221[AGG_ATCR3] = 0x080,222[LPON_UTTR0] = 0x360,223[LPON_UTTR1] = 0x364,224[LPON_FRCR] = 0x37c,225[MIB_SDR3] = 0x698,226[MIB_SDR4] = 0x788,227[MIB_SDR5] = 0x780,228[MIB_SDR7] = 0x5a8,229[MIB_SDR8] = 0x78c,230[MIB_SDR9] = 0x024,231[MIB_SDR10] = 0x76c,232[MIB_SDR11] = 0x790,233[MIB_SDR12] = 0x558,234[MIB_SDR13] = 0x560,235[MIB_SDR14] = 0x564,236[MIB_SDR15] = 0x568,237[MIB_SDR16] = 0x7fc,238[MIB_SDR17] = 0x800,239[MIB_SDR18] = 0x030,240[MIB_SDR19] = 0x5ac,241[MIB_SDR20] = 0x5b0,242[MIB_SDR21] = 0x5b4,243[MIB_SDR22] = 0x770,244[MIB_SDR23] = 0x774,245[MIB_SDR24] = 0x778,246[MIB_SDR25] = 0x77c,247[MIB_SDR27] = 0x080,248[MIB_SDR28] = 0x084,249[MIB_SDR29] = 0x650,250[MIB_SDRVEC] = 0x5a8,251[MIB_SDR31] = 0x55c,252[MIB_SDR32] = 0x7a8,253[MIB_SDRMUBF] = 0x7ac,254[MIB_DR8] = 0x56c,255[MIB_DR9] = 0x570,256[MIB_DR11] = 0x574,257[MIB_MB_SDR0] = 0x688,258[MIB_MB_SDR1] = 0x690,259[TX_AGG_CNT] = 0x7dc,260[TX_AGG_CNT2] = 0x7ec,261[MIB_ARNG] = 0x0b0,262[WTBLON_TOP_WDUCR] = 0x200,263[WTBL_UPDATE] = 0x230,264[PLE_FL_Q_EMPTY] = 0x360,265[PLE_FL_Q_CTRL] = 0x3e0,266[PLE_AC_QEMPTY] = 0x600,267[PLE_FREEPG_CNT] = 0x380,268[PLE_FREEPG_HEAD_TAIL] = 0x384,269[PLE_PG_HIF_GROUP] = 0x00c,270[PLE_HIF_PG_INFO] = 0x388,271[AC_OFFSET] = 0x080,272[ETBF_PAR_RPT0] = 0x100,273};274275static const struct mt76_connac_reg_map mt7915_reg_map[] = {276{ 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */277{ 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure regs) */278{ 0x40000000, 0x70000, 0x10000 }, /* WF_UMAC_SYSRAM */279{ 0x54000000, 0x02000, 0x01000 }, /* WFDMA PCIE0 MCU DMA0 */280{ 0x55000000, 0x03000, 0x01000 }, /* WFDMA PCIE0 MCU DMA1 */281{ 0x58000000, 0x06000, 0x01000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */282{ 0x59000000, 0x07000, 0x01000 }, /* WFDMA PCIE1 MCU DMA1 */283{ 0x7c000000, 0xf0000, 0x10000 }, /* CONN_INFRA */284{ 0x7c020000, 0xd0000, 0x10000 }, /* CONN_INFRA, WFDMA */285{ 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */286{ 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */287{ 0x820c0000, 0x08000, 0x04000 }, /* WF_UMAC_TOP (PLE) */288{ 0x820c8000, 0x0c000, 0x02000 }, /* WF_UMAC_TOP (PSE) */289{ 0x820cc000, 0x0e000, 0x02000 }, /* WF_UMAC_TOP (PP) */290{ 0x820ce000, 0x21c00, 0x00200 }, /* WF_LMAC_TOP (WF_SEC) */291{ 0x820cf000, 0x22000, 0x01000 }, /* WF_LMAC_TOP (WF_PF) */292{ 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */293{ 0x820e0000, 0x20000, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */294{ 0x820e1000, 0x20400, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */295{ 0x820e2000, 0x20800, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */296{ 0x820e3000, 0x20c00, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */297{ 0x820e4000, 0x21000, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */298{ 0x820e5000, 0x21400, 0x00800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */299{ 0x820e7000, 0x21e00, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */300{ 0x820e9000, 0x23400, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */301{ 0x820ea000, 0x24000, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */302{ 0x820eb000, 0x24200, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */303{ 0x820ec000, 0x24600, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_INT) */304{ 0x820ed000, 0x24800, 0x00800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */305{ 0x820f0000, 0xa0000, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */306{ 0x820f1000, 0xa0600, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */307{ 0x820f2000, 0xa0800, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */308{ 0x820f3000, 0xa0c00, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */309{ 0x820f4000, 0xa1000, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */310{ 0x820f5000, 0xa1400, 0x00800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */311{ 0x820f7000, 0xa1e00, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */312{ 0x820f9000, 0xa3400, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */313{ 0x820fa000, 0xa4000, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */314{ 0x820fb000, 0xa4200, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */315{ 0x820fc000, 0xa4600, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_INT) */316{ 0x820fd000, 0xa4800, 0x00800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */317{ 0x0, 0x0, 0x0 }, /* imply end of search */318};319320static const struct mt76_connac_reg_map mt7916_reg_map[] = {321{ 0x54000000, 0x02000, 0x01000 }, /* WFDMA_0 (PCIE0 MCU DMA0) */322{ 0x55000000, 0x03000, 0x01000 }, /* WFDMA_1 (PCIE0 MCU DMA1) */323{ 0x56000000, 0x04000, 0x01000 }, /* WFDMA_2 (Reserved) */324{ 0x57000000, 0x05000, 0x01000 }, /* WFDMA_3 (MCU wrap CR) */325{ 0x58000000, 0x06000, 0x01000 }, /* WFDMA_4 (PCIE1 MCU DMA0) */326{ 0x59000000, 0x07000, 0x01000 }, /* WFDMA_5 (PCIE1 MCU DMA1) */327{ 0x820c0000, 0x08000, 0x04000 }, /* WF_UMAC_TOP (PLE) */328{ 0x820c8000, 0x0c000, 0x02000 }, /* WF_UMAC_TOP (PSE) */329{ 0x820cc000, 0x0e000, 0x02000 }, /* WF_UMAC_TOP (PP) */330{ 0x820e0000, 0x20000, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */331{ 0x820e1000, 0x20400, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */332{ 0x820e2000, 0x20800, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */333{ 0x820e3000, 0x20c00, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */334{ 0x820e4000, 0x21000, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */335{ 0x820e5000, 0x21400, 0x00800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */336{ 0x820ce000, 0x21c00, 0x00200 }, /* WF_LMAC_TOP (WF_SEC) */337{ 0x820e7000, 0x21e00, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */338{ 0x820cf000, 0x22000, 0x01000 }, /* WF_LMAC_TOP (WF_PF) */339{ 0x820e9000, 0x23400, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */340{ 0x820ea000, 0x24000, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */341{ 0x820eb000, 0x24200, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */342{ 0x820ec000, 0x24600, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_INT) */343{ 0x820ed000, 0x24800, 0x00800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */344{ 0x820ca000, 0x26000, 0x02000 }, /* WF_LMAC_TOP BN0 (WF_MUCOP) */345{ 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */346{ 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */347{ 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure cr) */348{ 0x820f0000, 0xa0000, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */349{ 0x820f1000, 0xa0600, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */350{ 0x820f2000, 0xa0800, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */351{ 0x820f3000, 0xa0c00, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */352{ 0x820f4000, 0xa1000, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */353{ 0x820f5000, 0xa1400, 0x00800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */354{ 0x820f7000, 0xa1e00, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */355{ 0x820f9000, 0xa3400, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */356{ 0x820fa000, 0xa4000, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */357{ 0x820fb000, 0xa4200, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */358{ 0x820fc000, 0xa4600, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_INT) */359{ 0x820fd000, 0xa4800, 0x00800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */360{ 0x820c4000, 0xa8000, 0x01000 }, /* WF_LMAC_TOP (WF_UWTBL ) */361{ 0x820b0000, 0xae000, 0x01000 }, /* [APB2] WFSYS_ON */362{ 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */363{ 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */364{ 0x0, 0x0, 0x0 }, /* imply end of search */365};366367static const struct mt76_connac_reg_map mt7986_reg_map[] = {368{ 0x54000000, 0x402000, 0x01000 }, /* WFDMA_0 (PCIE0 MCU DMA0) */369{ 0x55000000, 0x403000, 0x01000 }, /* WFDMA_1 (PCIE0 MCU DMA1) */370{ 0x56000000, 0x404000, 0x01000 }, /* WFDMA_2 (Reserved) */371{ 0x57000000, 0x405000, 0x01000 }, /* WFDMA_3 (MCU wrap CR) */372{ 0x58000000, 0x406000, 0x01000 }, /* WFDMA_4 (PCIE1 MCU DMA0) */373{ 0x59000000, 0x407000, 0x01000 }, /* WFDMA_5 (PCIE1 MCU DMA1) */374{ 0x820c0000, 0x408000, 0x04000 }, /* WF_UMAC_TOP (PLE) */375{ 0x820c8000, 0x40c000, 0x02000 }, /* WF_UMAC_TOP (PSE) */376{ 0x820cc000, 0x40e000, 0x02000 }, /* WF_UMAC_TOP (PP) */377{ 0x820e0000, 0x420000, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */378{ 0x820e1000, 0x420400, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */379{ 0x820e2000, 0x420800, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */380{ 0x820e3000, 0x420c00, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */381{ 0x820e4000, 0x421000, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */382{ 0x820e5000, 0x421400, 0x00800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */383{ 0x820ce000, 0x421c00, 0x00200 }, /* WF_LMAC_TOP (WF_SEC) */384{ 0x820e7000, 0x421e00, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */385{ 0x820cf000, 0x422000, 0x01000 }, /* WF_LMAC_TOP (WF_PF) */386{ 0x820e9000, 0x423400, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */387{ 0x820ea000, 0x424000, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */388{ 0x820eb000, 0x424200, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */389{ 0x820ec000, 0x424600, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_INT) */390{ 0x820ed000, 0x424800, 0x00800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */391{ 0x820ca000, 0x426000, 0x02000 }, /* WF_LMAC_TOP BN0 (WF_MUCOP) */392{ 0x820d0000, 0x430000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */393{ 0x00400000, 0x480000, 0x10000 }, /* WF_MCU_SYSRAM */394{ 0x00410000, 0x490000, 0x10000 }, /* WF_MCU_SYSRAM */395{ 0x820f0000, 0x4a0000, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */396{ 0x820f1000, 0x4a0600, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */397{ 0x820f2000, 0x4a0800, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */398{ 0x820f3000, 0x4a0c00, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */399{ 0x820f4000, 0x4a1000, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */400{ 0x820f5000, 0x4a1400, 0x00800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */401{ 0x820f7000, 0x4a1e00, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */402{ 0x820f9000, 0x4a3400, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */403{ 0x820fa000, 0x4a4000, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */404{ 0x820fb000, 0x4a4200, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */405{ 0x820fc000, 0x4a4600, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_INT) */406{ 0x820fd000, 0x4a4800, 0x00800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */407{ 0x820c4000, 0x4a8000, 0x01000 }, /* WF_LMAC_TOP (WF_UWTBL ) */408{ 0x820b0000, 0x4ae000, 0x01000 }, /* [APB2] WFSYS_ON */409{ 0x80020000, 0x4b0000, 0x10000 }, /* WF_TOP_MISC_OFF */410{ 0x81020000, 0x4c0000, 0x10000 }, /* WF_TOP_MISC_ON */411{ 0x89000000, 0x4d0000, 0x01000 }, /* WF_MCU_CFG_ON */412{ 0x89010000, 0x4d1000, 0x01000 }, /* WF_MCU_CIRQ */413{ 0x89020000, 0x4d2000, 0x01000 }, /* WF_MCU_GPT */414{ 0x89030000, 0x4d3000, 0x01000 }, /* WF_MCU_WDT */415{ 0x80010000, 0x4d4000, 0x01000 }, /* WF_AXIDMA */416{ 0x0, 0x0, 0x0 }, /* imply end of search */417};418419static u32 mt7915_reg_map_l1(struct mt7915_dev *dev, u32 addr)420{421u32 offset = FIELD_GET(MT_HIF_REMAP_L1_OFFSET, addr);422u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr);423u32 l1_remap;424425if (is_mt798x(&dev->mt76))426return MT_CONN_INFRA_OFFSET(addr);427428l1_remap = is_mt7915(&dev->mt76) ?429MT_HIF_REMAP_L1 : MT_HIF_REMAP_L1_MT7916;430431dev->bus_ops->rmw(&dev->mt76, l1_remap,432MT_HIF_REMAP_L1_MASK,433FIELD_PREP(MT_HIF_REMAP_L1_MASK, base));434/* use read to push write */435dev->bus_ops->rr(&dev->mt76, l1_remap);436437return MT_HIF_REMAP_BASE_L1 + offset;438}439440static u32 mt7915_reg_map_l2(struct mt7915_dev *dev, u32 addr)441{442u32 offset, base;443444if (is_mt7915(&dev->mt76)) {445offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET, addr);446base = FIELD_GET(MT_HIF_REMAP_L2_BASE, addr);447448dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L2,449MT_HIF_REMAP_L2_MASK,450FIELD_PREP(MT_HIF_REMAP_L2_MASK, base));451452/* use read to push write */453dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2);454} else {455u32 ofs = is_mt798x(&dev->mt76) ? 0x400000 : 0;456457offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET_MT7916, addr);458base = FIELD_GET(MT_HIF_REMAP_L2_BASE_MT7916, addr);459460dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L2_MT7916 + ofs,461MT_HIF_REMAP_L2_MASK_MT7916,462FIELD_PREP(MT_HIF_REMAP_L2_MASK_MT7916, base));463464/* use read to push write */465dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2_MT7916 + ofs);466467offset += (MT_HIF_REMAP_BASE_L2_MT7916 + ofs);468}469470return offset;471}472473static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr)474{475int i;476477if (addr < 0x100000)478return addr;479480if (!dev->reg.map) {481dev_err(dev->mt76.dev, "err: reg_map is null\n");482return addr;483}484485for (i = 0; i < dev->reg.map_size; i++) {486u32 ofs;487488if (addr < dev->reg.map[i].phys)489continue;490491ofs = addr - dev->reg.map[i].phys;492if (ofs >= dev->reg.map[i].size)493continue;494495return dev->reg.map[i].maps + ofs;496}497498return 0;499}500501static u32 __mt7915_reg_remap_addr(struct mt7915_dev *dev, u32 addr)502{503if ((addr >= MT_INFRA_BASE && addr < MT_WFSYS0_PHY_START) ||504(addr >= MT_WFSYS0_PHY_START && addr < MT_WFSYS1_PHY_START) ||505(addr >= MT_WFSYS1_PHY_START && addr <= MT_WFSYS1_PHY_END))506return mt7915_reg_map_l1(dev, addr);507508if (dev_is_pci(dev->mt76.dev) &&509((addr >= MT_CBTOP1_PHY_START && addr <= MT_CBTOP1_PHY_END) ||510addr >= MT_CBTOP2_PHY_START))511return mt7915_reg_map_l1(dev, addr);512513/* CONN_INFRA: covert to phyiscal addr and use layer 1 remap */514if (addr >= MT_INFRA_MCU_START && addr <= MT_INFRA_MCU_END) {515addr = addr - MT_INFRA_MCU_START + MT_INFRA_BASE;516return mt7915_reg_map_l1(dev, addr);517}518519return mt7915_reg_map_l2(dev, addr);520}521522void mt7915_memcpy_fromio(struct mt7915_dev *dev, void *buf, u32 offset,523size_t len)524{525u32 addr = __mt7915_reg_addr(dev, offset);526527if (addr) {528#if defined(__linux__)529memcpy_fromio(buf, dev->mt76.mmio.regs + addr, len);530#elif defined(__FreeBSD__)531memcpy_fromio(buf, (u8 *)dev->mt76.mmio.regs + addr, len);532#endif533return;534}535536spin_lock_bh(&dev->reg_lock);537#if defined(__linux__)538memcpy_fromio(buf, dev->mt76.mmio.regs +539#elif defined(__FreeBSD__)540memcpy_fromio(buf, (u8 *)dev->mt76.mmio.regs +541#endif542__mt7915_reg_remap_addr(dev, offset), len);543spin_unlock_bh(&dev->reg_lock);544}545546static u32 mt7915_rr(struct mt76_dev *mdev, u32 offset)547{548struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);549u32 addr = __mt7915_reg_addr(dev, offset), val;550551if (addr)552return dev->bus_ops->rr(mdev, addr);553554spin_lock_bh(&dev->reg_lock);555val = dev->bus_ops->rr(mdev, __mt7915_reg_remap_addr(dev, offset));556spin_unlock_bh(&dev->reg_lock);557558return val;559}560561static void mt7915_wr(struct mt76_dev *mdev, u32 offset, u32 val)562{563struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);564u32 addr = __mt7915_reg_addr(dev, offset);565566if (addr) {567dev->bus_ops->wr(mdev, addr, val);568return;569}570571spin_lock_bh(&dev->reg_lock);572dev->bus_ops->wr(mdev, __mt7915_reg_remap_addr(dev, offset), val);573spin_unlock_bh(&dev->reg_lock);574}575576static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)577{578struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);579u32 addr = __mt7915_reg_addr(dev, offset);580581if (addr)582return dev->bus_ops->rmw(mdev, addr, mask, val);583584spin_lock_bh(&dev->reg_lock);585val = dev->bus_ops->rmw(mdev, __mt7915_reg_remap_addr(dev, offset), mask, val);586spin_unlock_bh(&dev->reg_lock);587588return val;589}590591#ifdef CONFIG_NET_MEDIATEK_SOC_WED592static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,593struct mtk_wed_wo_rx_stats *stats)594{595int idx = le16_to_cpu(stats->wlan_idx);596struct mt7915_dev *dev;597struct mt76_wcid *wcid;598599dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);600601rcu_read_lock();602603wcid = mt76_wcid_ptr(dev, idx);604if (wcid) {605wcid->stats.rx_bytes += le32_to_cpu(stats->rx_byte_cnt);606wcid->stats.rx_packets += le32_to_cpu(stats->rx_pkt_cnt);607wcid->stats.rx_errors += le32_to_cpu(stats->rx_err_cnt);608wcid->stats.rx_drops += le32_to_cpu(stats->rx_drop_cnt);609}610611rcu_read_unlock();612}613614static int mt7915_mmio_wed_reset(struct mtk_wed_device *wed)615{616struct mt76_dev *mdev = container_of(wed, struct mt76_dev, mmio.wed);617struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);618struct mt76_phy *mphy = &dev->mphy;619int ret;620621ASSERT_RTNL();622623if (test_and_set_bit(MT76_STATE_WED_RESET, &mphy->state))624return -EBUSY;625626ret = mt7915_mcu_set_ser(dev, SER_RECOVER, SER_SET_RECOVER_L1,627mphy->band_idx);628if (ret)629goto out;630631rtnl_unlock();632if (!wait_for_completion_timeout(&mdev->mmio.wed_reset, 20 * HZ)) {633dev_err(mdev->dev, "wed reset timeout\n");634ret = -ETIMEDOUT;635}636rtnl_lock();637out:638clear_bit(MT76_STATE_WED_RESET, &mphy->state);639640return ret;641}642#endif643644int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,645bool pci, int *irq)646{647#ifdef CONFIG_NET_MEDIATEK_SOC_WED648struct mtk_wed_device *wed = &dev->mt76.mmio.wed;649int ret;650651if (!wed_enable)652return 0;653654if (pci) {655struct pci_dev *pci_dev = pdev_ptr;656657wed->wlan.pci_dev = pci_dev;658wed->wlan.bus_type = MTK_WED_BUS_PCIE;659wed->wlan.base = devm_ioremap(dev->mt76.dev,660pci_resource_start(pci_dev, 0),661pci_resource_len(pci_dev, 0));662if (!wed->wlan.base)663return -ENOMEM;664665wed->wlan.phy_base = pci_resource_start(pci_dev, 0);666wed->wlan.wpdma_int = pci_resource_start(pci_dev, 0) +667MT_INT_WED_SOURCE_CSR;668wed->wlan.wpdma_mask = pci_resource_start(pci_dev, 0) +669MT_INT_WED_MASK_CSR;670wed->wlan.wpdma_phys = pci_resource_start(pci_dev, 0) +671MT_WFDMA_EXT_CSR_BASE;672wed->wlan.wpdma_tx = pci_resource_start(pci_dev, 0) +673MT_TXQ_WED_RING_BASE;674wed->wlan.wpdma_txfree = pci_resource_start(pci_dev, 0) +675MT_RXQ_WED_RING_BASE;676wed->wlan.wpdma_rx_glo = pci_resource_start(pci_dev, 0) +677MT_WPDMA_GLO_CFG;678wed->wlan.wpdma_rx[0] = pci_resource_start(pci_dev, 0) +679MT_RXQ_WED_DATA_RING_BASE;680} else {681struct platform_device *plat_dev = pdev_ptr;682struct resource *res;683684res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);685if (!res)686return 0;687688wed->wlan.platform_dev = plat_dev;689wed->wlan.bus_type = MTK_WED_BUS_AXI;690wed->wlan.base = devm_ioremap(dev->mt76.dev, res->start,691resource_size(res));692if (!wed->wlan.base)693return -ENOMEM;694695wed->wlan.phy_base = res->start;696wed->wlan.wpdma_int = res->start + MT_INT_SOURCE_CSR;697wed->wlan.wpdma_mask = res->start + MT_INT_MASK_CSR;698wed->wlan.wpdma_tx = res->start + MT_TXQ_WED_RING_BASE;699wed->wlan.wpdma_txfree = res->start + MT_RXQ_WED_RING_BASE;700wed->wlan.wpdma_rx_glo = res->start + MT_WPDMA_GLO_CFG;701wed->wlan.wpdma_rx[0] = res->start + MT_RXQ_WED_DATA_RING_BASE;702}703wed->wlan.nbuf = MT7915_HW_TOKEN_SIZE;704wed->wlan.tx_tbit[0] = is_mt7915(&dev->mt76) ? 4 : 30;705wed->wlan.tx_tbit[1] = is_mt7915(&dev->mt76) ? 5 : 31;706wed->wlan.txfree_tbit = is_mt798x(&dev->mt76) ? 2 : 1;707wed->wlan.token_start = MT7915_TOKEN_SIZE - wed->wlan.nbuf;708wed->wlan.wcid_512 = !is_mt7915(&dev->mt76);709710wed->wlan.rx_nbuf = 65536;711wed->wlan.rx_npkt = MT7915_WED_RX_TOKEN_SIZE;712wed->wlan.rx_size = SKB_WITH_OVERHEAD(MT_RX_BUF_SIZE);713if (is_mt7915(&dev->mt76)) {714wed->wlan.rx_tbit[0] = 16;715wed->wlan.rx_tbit[1] = 17;716} else if (is_mt798x(&dev->mt76)) {717wed->wlan.rx_tbit[0] = 22;718wed->wlan.rx_tbit[1] = 23;719} else {720wed->wlan.rx_tbit[0] = 18;721wed->wlan.rx_tbit[1] = 19;722}723724wed->wlan.init_buf = mt7915_wed_init_buf;725wed->wlan.offload_enable = mt76_wed_offload_enable;726wed->wlan.offload_disable = mt76_wed_offload_disable;727wed->wlan.init_rx_buf = mt76_wed_init_rx_buf;728wed->wlan.release_rx_buf = mt76_wed_release_rx_buf;729wed->wlan.update_wo_rx_stats = mt7915_mmio_wed_update_rx_stats;730wed->wlan.reset = mt7915_mmio_wed_reset;731wed->wlan.reset_complete = mt76_wed_reset_complete;732733dev->mt76.rx_token_size = wed->wlan.rx_npkt;734735if (mtk_wed_device_attach(wed))736return 0;737738*irq = wed->irq;739dev->mt76.dma_dev = wed->dev;740741ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));742if (ret)743return ret;744745return 1;746#else747return 0;748#endif749}750751static int mt7915_mmio_init(struct mt76_dev *mdev,752void __iomem *mem_base,753u32 device_id)754{755struct mt76_bus_ops *bus_ops;756struct mt7915_dev *dev;757758dev = container_of(mdev, struct mt7915_dev, mt76);759mt76_mmio_init(&dev->mt76, mem_base);760spin_lock_init(&dev->reg_lock);761762switch (device_id) {763case 0x7915:764dev->reg.reg_rev = mt7915_reg;765dev->reg.offs_rev = mt7915_offs;766dev->reg.map = mt7915_reg_map;767dev->reg.map_size = ARRAY_SIZE(mt7915_reg_map);768break;769case 0x7906:770dev->reg.reg_rev = mt7916_reg;771dev->reg.offs_rev = mt7916_offs;772dev->reg.map = mt7916_reg_map;773dev->reg.map_size = ARRAY_SIZE(mt7916_reg_map);774break;775case 0x7981:776case 0x7986:777dev->reg.reg_rev = mt7986_reg;778dev->reg.offs_rev = mt7916_offs;779dev->reg.map = mt7986_reg_map;780dev->reg.map_size = ARRAY_SIZE(mt7986_reg_map);781break;782default:783return -EINVAL;784}785786dev->bus_ops = dev->mt76.bus;787bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops),788GFP_KERNEL);789if (!bus_ops)790return -ENOMEM;791792bus_ops->rr = mt7915_rr;793bus_ops->wr = mt7915_wr;794bus_ops->rmw = mt7915_rmw;795dev->mt76.bus = bus_ops;796797mdev->rev = (device_id << 16) |798(mt76_rr(dev, MT_HW_REV) & 0xff);799dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);800801return 0;802}803804void mt7915_dual_hif_set_irq_mask(struct mt7915_dev *dev,805bool write_reg,806u32 clear, u32 set)807{808struct mt76_dev *mdev = &dev->mt76;809unsigned long flags;810811spin_lock_irqsave(&mdev->mmio.irq_lock, flags);812813mdev->mmio.irqmask &= ~clear;814mdev->mmio.irqmask |= set;815816if (write_reg) {817if (mtk_wed_device_active(&mdev->mmio.wed))818mtk_wed_device_irq_set_mask(&mdev->mmio.wed,819mdev->mmio.irqmask);820else821mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);822mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);823}824825spin_unlock_irqrestore(&mdev->mmio.irq_lock, flags);826}827828static void mt7915_rx_poll_complete(struct mt76_dev *mdev,829enum mt76_rxq_id q)830{831struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);832833mt7915_irq_enable(dev, MT_INT_RX(q));834}835836/* TODO: support 2/4/6/8 MSI-X vectors */837static void mt7915_irq_tasklet(struct tasklet_struct *t)838{839struct mt7915_dev *dev = from_tasklet(dev, t, mt76.irq_tasklet);840struct mtk_wed_device *wed = &dev->mt76.mmio.wed;841u32 intr, intr1, mask;842843if (mtk_wed_device_active(wed)) {844mtk_wed_device_irq_set_mask(wed, 0);845if (dev->hif2)846mt76_wr(dev, MT_INT1_MASK_CSR, 0);847intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);848} else {849mt76_wr(dev, MT_INT_MASK_CSR, 0);850if (dev->hif2)851mt76_wr(dev, MT_INT1_MASK_CSR, 0);852853intr = mt76_rr(dev, MT_INT_SOURCE_CSR);854intr &= dev->mt76.mmio.irqmask;855mt76_wr(dev, MT_INT_SOURCE_CSR, intr);856}857858if (dev->hif2) {859intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);860intr1 &= dev->mt76.mmio.irqmask;861mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);862863intr |= intr1;864}865866trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);867868mask = intr & MT_INT_RX_DONE_ALL;869if (intr & MT_INT_TX_DONE_MCU)870mask |= MT_INT_TX_DONE_MCU;871872mt7915_irq_disable(dev, mask);873874if (intr & MT_INT_TX_DONE_MCU)875napi_schedule(&dev->mt76.tx_napi);876877if (intr & MT_INT_RX(MT_RXQ_MAIN))878napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN]);879880if (intr & MT_INT_RX(MT_RXQ_BAND1))881napi_schedule(&dev->mt76.napi[MT_RXQ_BAND1]);882883if (intr & MT_INT_RX(MT_RXQ_MCU))884napi_schedule(&dev->mt76.napi[MT_RXQ_MCU]);885886if (intr & MT_INT_RX(MT_RXQ_MCU_WA))887napi_schedule(&dev->mt76.napi[MT_RXQ_MCU_WA]);888889if (!is_mt7915(&dev->mt76) &&890(intr & MT_INT_RX(MT_RXQ_MAIN_WA)))891napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN_WA]);892893if (intr & MT_INT_RX(MT_RXQ_BAND1_WA))894napi_schedule(&dev->mt76.napi[MT_RXQ_BAND1_WA]);895896if (intr & MT_INT_MCU_CMD) {897u32 val = mt76_rr(dev, MT_MCU_CMD);898899mt76_wr(dev, MT_MCU_CMD, val);900if (val & (MT_MCU_CMD_ERROR_MASK | MT_MCU_CMD_WDT_MASK)) {901dev->recovery.state = val;902mt7915_reset(dev);903}904}905}906907irqreturn_t mt7915_irq_handler(int irq, void *dev_instance)908{909struct mt7915_dev *dev = dev_instance;910struct mtk_wed_device *wed = &dev->mt76.mmio.wed;911912if (mtk_wed_device_active(wed))913mtk_wed_device_irq_set_mask(wed, 0);914else915mt76_wr(dev, MT_INT_MASK_CSR, 0);916917if (dev->hif2)918mt76_wr(dev, MT_INT1_MASK_CSR, 0);919920if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))921return IRQ_NONE;922923tasklet_schedule(&dev->mt76.irq_tasklet);924925return IRQ_HANDLED;926}927928struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,929void __iomem *mem_base, u32 device_id)930{931static const struct mt76_driver_ops drv_ops = {932/* txwi_size = txd size + txp size */933.txwi_size = MT_TXD_SIZE + sizeof(struct mt76_connac_fw_txp),934.drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ |935MT_DRV_AMSDU_OFFLOAD,936.survey_flags = SURVEY_INFO_TIME_TX |937SURVEY_INFO_TIME_RX |938SURVEY_INFO_TIME_BSS_RX,939.token_size = MT7915_TOKEN_SIZE,940.tx_prepare_skb = mt7915_tx_prepare_skb,941.tx_complete_skb = mt76_connac_tx_complete_skb,942.rx_skb = mt7915_queue_rx_skb,943.rx_check = mt7915_rx_check,944.rx_poll_complete = mt7915_rx_poll_complete,945.sta_add = mt7915_mac_sta_add,946.sta_event = mt7915_mac_sta_event,947.sta_remove = mt7915_mac_sta_remove,948.update_survey = mt7915_update_channel,949.set_channel = mt7915_set_channel,950};951struct mt7915_dev *dev;952struct mt76_dev *mdev;953int ret;954955mdev = mt76_alloc_device(pdev, sizeof(*dev), &mt7915_ops, &drv_ops);956if (!mdev)957return ERR_PTR(-ENOMEM);958959dev = container_of(mdev, struct mt7915_dev, mt76);960961ret = mt7915_mmio_init(mdev, mem_base, device_id);962if (ret)963goto error;964965tasklet_setup(&mdev->irq_tasklet, mt7915_irq_tasklet);966967return dev;968969error:970mt76_free_device(&dev->mt76);971972return ERR_PTR(ret);973}974975static int __init mt7915_init(void)976{977int ret;978979ret = pci_register_driver(&mt7915_hif_driver);980if (ret)981return ret;982983ret = pci_register_driver(&mt7915_pci_driver);984if (ret)985goto error_pci;986987if (IS_ENABLED(CONFIG_MT798X_WMAC)) {988ret = platform_driver_register(&mt798x_wmac_driver);989if (ret)990goto error_wmac;991}992993return 0;994995error_wmac:996pci_unregister_driver(&mt7915_pci_driver);997error_pci:998pci_unregister_driver(&mt7915_hif_driver);9991000return ret;1001}10021003static void __exit mt7915_exit(void)1004{1005if (IS_ENABLED(CONFIG_MT798X_WMAC))1006platform_driver_unregister(&mt798x_wmac_driver);10071008pci_unregister_driver(&mt7915_pci_driver);1009pci_unregister_driver(&mt7915_hif_driver);1010}10111012module_init(mt7915_init);1013module_exit(mt7915_exit);1014MODULE_DESCRIPTION("MediaTek MT7915E MMIO helpers");1015MODULE_LICENSE("Dual BSD/GPL");101610171018