162306a36Sopenharmony_ci// SPDX-License-Identifier: ISC 262306a36Sopenharmony_ci/* Copyright (C) 2020 MediaTek Inc. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/kernel.h> 562306a36Sopenharmony_ci#include <linux/module.h> 662306a36Sopenharmony_ci#include <linux/platform_device.h> 762306a36Sopenharmony_ci#include <linux/rtnetlink.h> 862306a36Sopenharmony_ci#include <linux/pci.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include "mt7915.h" 1162306a36Sopenharmony_ci#include "mac.h" 1262306a36Sopenharmony_ci#include "mcu.h" 1362306a36Sopenharmony_ci#include "../trace.h" 1462306a36Sopenharmony_ci#include "../dma.h" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cistatic bool wed_enable; 1762306a36Sopenharmony_cimodule_param(wed_enable, bool, 0644); 1862306a36Sopenharmony_ciMODULE_PARM_DESC(wed_enable, "Enable Wireless Ethernet Dispatch support"); 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic const u32 mt7915_reg[] = { 2162306a36Sopenharmony_ci [INT_SOURCE_CSR] = 0xd7010, 2262306a36Sopenharmony_ci [INT_MASK_CSR] = 0xd7014, 2362306a36Sopenharmony_ci [INT1_SOURCE_CSR] = 0xd7088, 2462306a36Sopenharmony_ci [INT1_MASK_CSR] = 0xd708c, 2562306a36Sopenharmony_ci [INT_MCU_CMD_SOURCE] = 0xd51f0, 2662306a36Sopenharmony_ci [INT_MCU_CMD_EVENT] = 0x3108, 2762306a36Sopenharmony_ci [WFDMA0_ADDR] = 0xd4000, 2862306a36Sopenharmony_ci [WFDMA0_PCIE1_ADDR] = 0xd8000, 2962306a36Sopenharmony_ci [WFDMA_EXT_CSR_ADDR] = 0xd7000, 3062306a36Sopenharmony_ci [CBTOP1_PHY_END] = 0x77ffffff, 3162306a36Sopenharmony_ci [INFRA_MCU_ADDR_END] = 0x7c3fffff, 3262306a36Sopenharmony_ci [FW_ASSERT_STAT_ADDR] = 0x219848, 3362306a36Sopenharmony_ci [FW_EXCEPT_TYPE_ADDR] = 0x21987c, 3462306a36Sopenharmony_ci [FW_EXCEPT_COUNT_ADDR] = 0x219848, 3562306a36Sopenharmony_ci [FW_CIRQ_COUNT_ADDR] = 0x216f94, 3662306a36Sopenharmony_ci [FW_CIRQ_IDX_ADDR] = 0x216ef8, 3762306a36Sopenharmony_ci [FW_CIRQ_LISR_ADDR] = 0x2170ac, 3862306a36Sopenharmony_ci [FW_TASK_ID_ADDR] = 0x216f90, 3962306a36Sopenharmony_ci [FW_TASK_IDX_ADDR] = 0x216f9c, 4062306a36Sopenharmony_ci [FW_TASK_QID1_ADDR] = 0x219680, 4162306a36Sopenharmony_ci [FW_TASK_QID2_ADDR] = 0x219760, 4262306a36Sopenharmony_ci [FW_TASK_START_ADDR] = 0x219558, 4362306a36Sopenharmony_ci [FW_TASK_END_ADDR] = 0x219554, 4462306a36Sopenharmony_ci [FW_TASK_SIZE_ADDR] = 0x219560, 4562306a36Sopenharmony_ci [FW_LAST_MSG_ID_ADDR] = 0x216f70, 4662306a36Sopenharmony_ci [FW_EINT_INFO_ADDR] = 0x219818, 4762306a36Sopenharmony_ci [FW_SCHED_INFO_ADDR] = 0x219828, 4862306a36Sopenharmony_ci [SWDEF_BASE_ADDR] = 0x41f200, 4962306a36Sopenharmony_ci [TXQ_WED_RING_BASE] = 0xd7300, 5062306a36Sopenharmony_ci [RXQ_WED_RING_BASE] = 0xd7410, 5162306a36Sopenharmony_ci [RXQ_WED_DATA_RING_BASE] = 0xd4500, 5262306a36Sopenharmony_ci}; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistatic const u32 mt7916_reg[] = { 5562306a36Sopenharmony_ci [INT_SOURCE_CSR] = 0xd4200, 5662306a36Sopenharmony_ci [INT_MASK_CSR] = 0xd4204, 5762306a36Sopenharmony_ci [INT1_SOURCE_CSR] = 0xd8200, 5862306a36Sopenharmony_ci [INT1_MASK_CSR] = 0xd8204, 5962306a36Sopenharmony_ci [INT_MCU_CMD_SOURCE] = 0xd41f0, 6062306a36Sopenharmony_ci [INT_MCU_CMD_EVENT] = 0x2108, 6162306a36Sopenharmony_ci [WFDMA0_ADDR] = 0xd4000, 6262306a36Sopenharmony_ci [WFDMA0_PCIE1_ADDR] = 0xd8000, 6362306a36Sopenharmony_ci [WFDMA_EXT_CSR_ADDR] = 0xd7000, 6462306a36Sopenharmony_ci [CBTOP1_PHY_END] = 0x7fffffff, 6562306a36Sopenharmony_ci [INFRA_MCU_ADDR_END] = 0x7c085fff, 6662306a36Sopenharmony_ci [FW_ASSERT_STAT_ADDR] = 0x02204c14, 6762306a36Sopenharmony_ci [FW_EXCEPT_TYPE_ADDR] = 0x022051a4, 6862306a36Sopenharmony_ci [FW_EXCEPT_COUNT_ADDR] = 0x022050bc, 6962306a36Sopenharmony_ci [FW_CIRQ_COUNT_ADDR] = 0x022001ac, 7062306a36Sopenharmony_ci [FW_CIRQ_IDX_ADDR] = 0x02204f84, 7162306a36Sopenharmony_ci [FW_CIRQ_LISR_ADDR] = 0x022050d0, 7262306a36Sopenharmony_ci [FW_TASK_ID_ADDR] = 0x0220406c, 7362306a36Sopenharmony_ci [FW_TASK_IDX_ADDR] = 0x0220500c, 7462306a36Sopenharmony_ci [FW_TASK_QID1_ADDR] = 0x022028c8, 7562306a36Sopenharmony_ci [FW_TASK_QID2_ADDR] = 0x02202a38, 7662306a36Sopenharmony_ci [FW_TASK_START_ADDR] = 0x0220286c, 7762306a36Sopenharmony_ci [FW_TASK_END_ADDR] = 0x02202870, 7862306a36Sopenharmony_ci [FW_TASK_SIZE_ADDR] = 0x02202878, 7962306a36Sopenharmony_ci [FW_LAST_MSG_ID_ADDR] = 0x02204fe8, 8062306a36Sopenharmony_ci [FW_EINT_INFO_ADDR] = 0x0220525c, 8162306a36Sopenharmony_ci [FW_SCHED_INFO_ADDR] = 0x0220516c, 8262306a36Sopenharmony_ci [SWDEF_BASE_ADDR] = 0x411400, 8362306a36Sopenharmony_ci [TXQ_WED_RING_BASE] = 0xd7300, 8462306a36Sopenharmony_ci [RXQ_WED_RING_BASE] = 0xd7410, 8562306a36Sopenharmony_ci [RXQ_WED_DATA_RING_BASE] = 0xd4540, 8662306a36Sopenharmony_ci}; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic const u32 mt7986_reg[] = { 8962306a36Sopenharmony_ci [INT_SOURCE_CSR] = 0x24200, 9062306a36Sopenharmony_ci [INT_MASK_CSR] = 0x24204, 9162306a36Sopenharmony_ci [INT1_SOURCE_CSR] = 0x28200, 9262306a36Sopenharmony_ci [INT1_MASK_CSR] = 0x28204, 9362306a36Sopenharmony_ci [INT_MCU_CMD_SOURCE] = 0x241f0, 9462306a36Sopenharmony_ci [INT_MCU_CMD_EVENT] = 0x54000108, 9562306a36Sopenharmony_ci [WFDMA0_ADDR] = 0x24000, 9662306a36Sopenharmony_ci [WFDMA0_PCIE1_ADDR] = 0x28000, 9762306a36Sopenharmony_ci [WFDMA_EXT_CSR_ADDR] = 0x27000, 9862306a36Sopenharmony_ci [CBTOP1_PHY_END] = 0x7fffffff, 9962306a36Sopenharmony_ci [INFRA_MCU_ADDR_END] = 0x7c085fff, 10062306a36Sopenharmony_ci [FW_ASSERT_STAT_ADDR] = 0x02204b54, 10162306a36Sopenharmony_ci [FW_EXCEPT_TYPE_ADDR] = 0x022050dc, 10262306a36Sopenharmony_ci [FW_EXCEPT_COUNT_ADDR] = 0x02204ffc, 10362306a36Sopenharmony_ci [FW_CIRQ_COUNT_ADDR] = 0x022001ac, 10462306a36Sopenharmony_ci [FW_CIRQ_IDX_ADDR] = 0x02204ec4, 10562306a36Sopenharmony_ci [FW_CIRQ_LISR_ADDR] = 0x02205010, 10662306a36Sopenharmony_ci [FW_TASK_ID_ADDR] = 0x02204fac, 10762306a36Sopenharmony_ci [FW_TASK_IDX_ADDR] = 0x02204f4c, 10862306a36Sopenharmony_ci [FW_TASK_QID1_ADDR] = 0x02202814, 10962306a36Sopenharmony_ci [FW_TASK_QID2_ADDR] = 0x02202984, 11062306a36Sopenharmony_ci [FW_TASK_START_ADDR] = 0x022027b8, 11162306a36Sopenharmony_ci [FW_TASK_END_ADDR] = 0x022027bc, 11262306a36Sopenharmony_ci [FW_TASK_SIZE_ADDR] = 0x022027c4, 11362306a36Sopenharmony_ci [FW_LAST_MSG_ID_ADDR] = 0x02204f28, 11462306a36Sopenharmony_ci [FW_EINT_INFO_ADDR] = 0x02205194, 11562306a36Sopenharmony_ci [FW_SCHED_INFO_ADDR] = 0x022051a4, 11662306a36Sopenharmony_ci [SWDEF_BASE_ADDR] = 0x411400, 11762306a36Sopenharmony_ci [TXQ_WED_RING_BASE] = 0x24420, 11862306a36Sopenharmony_ci [RXQ_WED_RING_BASE] = 0x24520, 11962306a36Sopenharmony_ci [RXQ_WED_DATA_RING_BASE] = 0x24540, 12062306a36Sopenharmony_ci}; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic const u32 mt7915_offs[] = { 12362306a36Sopenharmony_ci [TMAC_CDTR] = 0x090, 12462306a36Sopenharmony_ci [TMAC_ODTR] = 0x094, 12562306a36Sopenharmony_ci [TMAC_ATCR] = 0x098, 12662306a36Sopenharmony_ci [TMAC_TRCR0] = 0x09c, 12762306a36Sopenharmony_ci [TMAC_ICR0] = 0x0a4, 12862306a36Sopenharmony_ci [TMAC_ICR1] = 0x0b4, 12962306a36Sopenharmony_ci [TMAC_CTCR0] = 0x0f4, 13062306a36Sopenharmony_ci [TMAC_TFCR0] = 0x1e0, 13162306a36Sopenharmony_ci [MDP_BNRCFR0] = 0x070, 13262306a36Sopenharmony_ci [MDP_BNRCFR1] = 0x074, 13362306a36Sopenharmony_ci [ARB_DRNGR0] = 0x194, 13462306a36Sopenharmony_ci [ARB_SCR] = 0x080, 13562306a36Sopenharmony_ci [RMAC_MIB_AIRTIME14] = 0x3b8, 13662306a36Sopenharmony_ci [AGG_AWSCR0] = 0x05c, 13762306a36Sopenharmony_ci [AGG_PCR0] = 0x06c, 13862306a36Sopenharmony_ci [AGG_ACR0] = 0x084, 13962306a36Sopenharmony_ci [AGG_ACR4] = 0x08c, 14062306a36Sopenharmony_ci [AGG_MRCR] = 0x098, 14162306a36Sopenharmony_ci [AGG_ATCR1] = 0x0f0, 14262306a36Sopenharmony_ci [AGG_ATCR3] = 0x0f4, 14362306a36Sopenharmony_ci [LPON_UTTR0] = 0x080, 14462306a36Sopenharmony_ci [LPON_UTTR1] = 0x084, 14562306a36Sopenharmony_ci [LPON_FRCR] = 0x314, 14662306a36Sopenharmony_ci [MIB_SDR3] = 0x014, 14762306a36Sopenharmony_ci [MIB_SDR4] = 0x018, 14862306a36Sopenharmony_ci [MIB_SDR5] = 0x01c, 14962306a36Sopenharmony_ci [MIB_SDR7] = 0x024, 15062306a36Sopenharmony_ci [MIB_SDR8] = 0x028, 15162306a36Sopenharmony_ci [MIB_SDR9] = 0x02c, 15262306a36Sopenharmony_ci [MIB_SDR10] = 0x030, 15362306a36Sopenharmony_ci [MIB_SDR11] = 0x034, 15462306a36Sopenharmony_ci [MIB_SDR12] = 0x038, 15562306a36Sopenharmony_ci [MIB_SDR13] = 0x03c, 15662306a36Sopenharmony_ci [MIB_SDR14] = 0x040, 15762306a36Sopenharmony_ci [MIB_SDR15] = 0x044, 15862306a36Sopenharmony_ci [MIB_SDR16] = 0x048, 15962306a36Sopenharmony_ci [MIB_SDR17] = 0x04c, 16062306a36Sopenharmony_ci [MIB_SDR18] = 0x050, 16162306a36Sopenharmony_ci [MIB_SDR19] = 0x054, 16262306a36Sopenharmony_ci [MIB_SDR20] = 0x058, 16362306a36Sopenharmony_ci [MIB_SDR21] = 0x05c, 16462306a36Sopenharmony_ci [MIB_SDR22] = 0x060, 16562306a36Sopenharmony_ci [MIB_SDR23] = 0x064, 16662306a36Sopenharmony_ci [MIB_SDR24] = 0x068, 16762306a36Sopenharmony_ci [MIB_SDR25] = 0x06c, 16862306a36Sopenharmony_ci [MIB_SDR27] = 0x074, 16962306a36Sopenharmony_ci [MIB_SDR28] = 0x078, 17062306a36Sopenharmony_ci [MIB_SDR29] = 0x07c, 17162306a36Sopenharmony_ci [MIB_SDRVEC] = 0x080, 17262306a36Sopenharmony_ci [MIB_SDR31] = 0x084, 17362306a36Sopenharmony_ci [MIB_SDR32] = 0x088, 17462306a36Sopenharmony_ci [MIB_SDRMUBF] = 0x090, 17562306a36Sopenharmony_ci [MIB_DR8] = 0x0c0, 17662306a36Sopenharmony_ci [MIB_DR9] = 0x0c4, 17762306a36Sopenharmony_ci [MIB_DR11] = 0x0cc, 17862306a36Sopenharmony_ci [MIB_MB_SDR0] = 0x100, 17962306a36Sopenharmony_ci [MIB_MB_SDR1] = 0x104, 18062306a36Sopenharmony_ci [TX_AGG_CNT] = 0x0a8, 18162306a36Sopenharmony_ci [TX_AGG_CNT2] = 0x164, 18262306a36Sopenharmony_ci [MIB_ARNG] = 0x4b8, 18362306a36Sopenharmony_ci [WTBLON_TOP_WDUCR] = 0x0, 18462306a36Sopenharmony_ci [WTBL_UPDATE] = 0x030, 18562306a36Sopenharmony_ci [PLE_FL_Q_EMPTY] = 0x0b0, 18662306a36Sopenharmony_ci [PLE_FL_Q_CTRL] = 0x1b0, 18762306a36Sopenharmony_ci [PLE_AC_QEMPTY] = 0x500, 18862306a36Sopenharmony_ci [PLE_FREEPG_CNT] = 0x100, 18962306a36Sopenharmony_ci [PLE_FREEPG_HEAD_TAIL] = 0x104, 19062306a36Sopenharmony_ci [PLE_PG_HIF_GROUP] = 0x110, 19162306a36Sopenharmony_ci [PLE_HIF_PG_INFO] = 0x114, 19262306a36Sopenharmony_ci [AC_OFFSET] = 0x040, 19362306a36Sopenharmony_ci [ETBF_PAR_RPT0] = 0x068, 19462306a36Sopenharmony_ci}; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_cistatic const u32 mt7916_offs[] = { 19762306a36Sopenharmony_ci [TMAC_CDTR] = 0x0c8, 19862306a36Sopenharmony_ci [TMAC_ODTR] = 0x0cc, 19962306a36Sopenharmony_ci [TMAC_ATCR] = 0x00c, 20062306a36Sopenharmony_ci [TMAC_TRCR0] = 0x010, 20162306a36Sopenharmony_ci [TMAC_ICR0] = 0x014, 20262306a36Sopenharmony_ci [TMAC_ICR1] = 0x018, 20362306a36Sopenharmony_ci [TMAC_CTCR0] = 0x114, 20462306a36Sopenharmony_ci [TMAC_TFCR0] = 0x0e4, 20562306a36Sopenharmony_ci [MDP_BNRCFR0] = 0x090, 20662306a36Sopenharmony_ci [MDP_BNRCFR1] = 0x094, 20762306a36Sopenharmony_ci [ARB_DRNGR0] = 0x1e0, 20862306a36Sopenharmony_ci [ARB_SCR] = 0x000, 20962306a36Sopenharmony_ci [RMAC_MIB_AIRTIME14] = 0x0398, 21062306a36Sopenharmony_ci [AGG_AWSCR0] = 0x030, 21162306a36Sopenharmony_ci [AGG_PCR0] = 0x040, 21262306a36Sopenharmony_ci [AGG_ACR0] = 0x054, 21362306a36Sopenharmony_ci [AGG_ACR4] = 0x05c, 21462306a36Sopenharmony_ci [AGG_MRCR] = 0x068, 21562306a36Sopenharmony_ci [AGG_ATCR1] = 0x1a8, 21662306a36Sopenharmony_ci [AGG_ATCR3] = 0x080, 21762306a36Sopenharmony_ci [LPON_UTTR0] = 0x360, 21862306a36Sopenharmony_ci [LPON_UTTR1] = 0x364, 21962306a36Sopenharmony_ci [LPON_FRCR] = 0x37c, 22062306a36Sopenharmony_ci [MIB_SDR3] = 0x698, 22162306a36Sopenharmony_ci [MIB_SDR4] = 0x788, 22262306a36Sopenharmony_ci [MIB_SDR5] = 0x780, 22362306a36Sopenharmony_ci [MIB_SDR7] = 0x5a8, 22462306a36Sopenharmony_ci [MIB_SDR8] = 0x78c, 22562306a36Sopenharmony_ci [MIB_SDR9] = 0x024, 22662306a36Sopenharmony_ci [MIB_SDR10] = 0x76c, 22762306a36Sopenharmony_ci [MIB_SDR11] = 0x790, 22862306a36Sopenharmony_ci [MIB_SDR12] = 0x558, 22962306a36Sopenharmony_ci [MIB_SDR13] = 0x560, 23062306a36Sopenharmony_ci [MIB_SDR14] = 0x564, 23162306a36Sopenharmony_ci [MIB_SDR15] = 0x568, 23262306a36Sopenharmony_ci [MIB_SDR16] = 0x7fc, 23362306a36Sopenharmony_ci [MIB_SDR17] = 0x800, 23462306a36Sopenharmony_ci [MIB_SDR18] = 0x030, 23562306a36Sopenharmony_ci [MIB_SDR19] = 0x5ac, 23662306a36Sopenharmony_ci [MIB_SDR20] = 0x5b0, 23762306a36Sopenharmony_ci [MIB_SDR21] = 0x5b4, 23862306a36Sopenharmony_ci [MIB_SDR22] = 0x770, 23962306a36Sopenharmony_ci [MIB_SDR23] = 0x774, 24062306a36Sopenharmony_ci [MIB_SDR24] = 0x778, 24162306a36Sopenharmony_ci [MIB_SDR25] = 0x77c, 24262306a36Sopenharmony_ci [MIB_SDR27] = 0x080, 24362306a36Sopenharmony_ci [MIB_SDR28] = 0x084, 24462306a36Sopenharmony_ci [MIB_SDR29] = 0x650, 24562306a36Sopenharmony_ci [MIB_SDRVEC] = 0x5a8, 24662306a36Sopenharmony_ci [MIB_SDR31] = 0x55c, 24762306a36Sopenharmony_ci [MIB_SDR32] = 0x7a8, 24862306a36Sopenharmony_ci [MIB_SDRMUBF] = 0x7ac, 24962306a36Sopenharmony_ci [MIB_DR8] = 0x56c, 25062306a36Sopenharmony_ci [MIB_DR9] = 0x570, 25162306a36Sopenharmony_ci [MIB_DR11] = 0x574, 25262306a36Sopenharmony_ci [MIB_MB_SDR0] = 0x688, 25362306a36Sopenharmony_ci [MIB_MB_SDR1] = 0x690, 25462306a36Sopenharmony_ci [TX_AGG_CNT] = 0x7dc, 25562306a36Sopenharmony_ci [TX_AGG_CNT2] = 0x7ec, 25662306a36Sopenharmony_ci [MIB_ARNG] = 0x0b0, 25762306a36Sopenharmony_ci [WTBLON_TOP_WDUCR] = 0x200, 25862306a36Sopenharmony_ci [WTBL_UPDATE] = 0x230, 25962306a36Sopenharmony_ci [PLE_FL_Q_EMPTY] = 0x360, 26062306a36Sopenharmony_ci [PLE_FL_Q_CTRL] = 0x3e0, 26162306a36Sopenharmony_ci [PLE_AC_QEMPTY] = 0x600, 26262306a36Sopenharmony_ci [PLE_FREEPG_CNT] = 0x380, 26362306a36Sopenharmony_ci [PLE_FREEPG_HEAD_TAIL] = 0x384, 26462306a36Sopenharmony_ci [PLE_PG_HIF_GROUP] = 0x00c, 26562306a36Sopenharmony_ci [PLE_HIF_PG_INFO] = 0x388, 26662306a36Sopenharmony_ci [AC_OFFSET] = 0x080, 26762306a36Sopenharmony_ci [ETBF_PAR_RPT0] = 0x100, 26862306a36Sopenharmony_ci}; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cistatic const struct mt76_connac_reg_map mt7915_reg_map[] = { 27162306a36Sopenharmony_ci { 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */ 27262306a36Sopenharmony_ci { 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure regs) */ 27362306a36Sopenharmony_ci { 0x40000000, 0x70000, 0x10000 }, /* WF_UMAC_SYSRAM */ 27462306a36Sopenharmony_ci { 0x54000000, 0x02000, 0x01000 }, /* WFDMA PCIE0 MCU DMA0 */ 27562306a36Sopenharmony_ci { 0x55000000, 0x03000, 0x01000 }, /* WFDMA PCIE0 MCU DMA1 */ 27662306a36Sopenharmony_ci { 0x58000000, 0x06000, 0x01000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ 27762306a36Sopenharmony_ci { 0x59000000, 0x07000, 0x01000 }, /* WFDMA PCIE1 MCU DMA1 */ 27862306a36Sopenharmony_ci { 0x7c000000, 0xf0000, 0x10000 }, /* CONN_INFRA */ 27962306a36Sopenharmony_ci { 0x7c020000, 0xd0000, 0x10000 }, /* CONN_INFRA, WFDMA */ 28062306a36Sopenharmony_ci { 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */ 28162306a36Sopenharmony_ci { 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */ 28262306a36Sopenharmony_ci { 0x820c0000, 0x08000, 0x04000 }, /* WF_UMAC_TOP (PLE) */ 28362306a36Sopenharmony_ci { 0x820c8000, 0x0c000, 0x02000 }, /* WF_UMAC_TOP (PSE) */ 28462306a36Sopenharmony_ci { 0x820cc000, 0x0e000, 0x02000 }, /* WF_UMAC_TOP (PP) */ 28562306a36Sopenharmony_ci { 0x820ce000, 0x21c00, 0x00200 }, /* WF_LMAC_TOP (WF_SEC) */ 28662306a36Sopenharmony_ci { 0x820cf000, 0x22000, 0x01000 }, /* WF_LMAC_TOP (WF_PF) */ 28762306a36Sopenharmony_ci { 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */ 28862306a36Sopenharmony_ci { 0x820e0000, 0x20000, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */ 28962306a36Sopenharmony_ci { 0x820e1000, 0x20400, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */ 29062306a36Sopenharmony_ci { 0x820e2000, 0x20800, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */ 29162306a36Sopenharmony_ci { 0x820e3000, 0x20c00, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */ 29262306a36Sopenharmony_ci { 0x820e4000, 0x21000, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */ 29362306a36Sopenharmony_ci { 0x820e5000, 0x21400, 0x00800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */ 29462306a36Sopenharmony_ci { 0x820e7000, 0x21e00, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */ 29562306a36Sopenharmony_ci { 0x820e9000, 0x23400, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ 29662306a36Sopenharmony_ci { 0x820ea000, 0x24000, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */ 29762306a36Sopenharmony_ci { 0x820eb000, 0x24200, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */ 29862306a36Sopenharmony_ci { 0x820ec000, 0x24600, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_INT) */ 29962306a36Sopenharmony_ci { 0x820ed000, 0x24800, 0x00800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */ 30062306a36Sopenharmony_ci { 0x820f0000, 0xa0000, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */ 30162306a36Sopenharmony_ci { 0x820f1000, 0xa0600, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */ 30262306a36Sopenharmony_ci { 0x820f2000, 0xa0800, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */ 30362306a36Sopenharmony_ci { 0x820f3000, 0xa0c00, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */ 30462306a36Sopenharmony_ci { 0x820f4000, 0xa1000, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */ 30562306a36Sopenharmony_ci { 0x820f5000, 0xa1400, 0x00800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */ 30662306a36Sopenharmony_ci { 0x820f7000, 0xa1e00, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */ 30762306a36Sopenharmony_ci { 0x820f9000, 0xa3400, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ 30862306a36Sopenharmony_ci { 0x820fa000, 0xa4000, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */ 30962306a36Sopenharmony_ci { 0x820fb000, 0xa4200, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */ 31062306a36Sopenharmony_ci { 0x820fc000, 0xa4600, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_INT) */ 31162306a36Sopenharmony_ci { 0x820fd000, 0xa4800, 0x00800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */ 31262306a36Sopenharmony_ci { 0x0, 0x0, 0x0 }, /* imply end of search */ 31362306a36Sopenharmony_ci}; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_cistatic const struct mt76_connac_reg_map mt7916_reg_map[] = { 31662306a36Sopenharmony_ci { 0x54000000, 0x02000, 0x01000 }, /* WFDMA_0 (PCIE0 MCU DMA0) */ 31762306a36Sopenharmony_ci { 0x55000000, 0x03000, 0x01000 }, /* WFDMA_1 (PCIE0 MCU DMA1) */ 31862306a36Sopenharmony_ci { 0x56000000, 0x04000, 0x01000 }, /* WFDMA_2 (Reserved) */ 31962306a36Sopenharmony_ci { 0x57000000, 0x05000, 0x01000 }, /* WFDMA_3 (MCU wrap CR) */ 32062306a36Sopenharmony_ci { 0x58000000, 0x06000, 0x01000 }, /* WFDMA_4 (PCIE1 MCU DMA0) */ 32162306a36Sopenharmony_ci { 0x59000000, 0x07000, 0x01000 }, /* WFDMA_5 (PCIE1 MCU DMA1) */ 32262306a36Sopenharmony_ci { 0x820c0000, 0x08000, 0x04000 }, /* WF_UMAC_TOP (PLE) */ 32362306a36Sopenharmony_ci { 0x820c8000, 0x0c000, 0x02000 }, /* WF_UMAC_TOP (PSE) */ 32462306a36Sopenharmony_ci { 0x820cc000, 0x0e000, 0x02000 }, /* WF_UMAC_TOP (PP) */ 32562306a36Sopenharmony_ci { 0x820e0000, 0x20000, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */ 32662306a36Sopenharmony_ci { 0x820e1000, 0x20400, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */ 32762306a36Sopenharmony_ci { 0x820e2000, 0x20800, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */ 32862306a36Sopenharmony_ci { 0x820e3000, 0x20c00, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */ 32962306a36Sopenharmony_ci { 0x820e4000, 0x21000, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */ 33062306a36Sopenharmony_ci { 0x820e5000, 0x21400, 0x00800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */ 33162306a36Sopenharmony_ci { 0x820ce000, 0x21c00, 0x00200 }, /* WF_LMAC_TOP (WF_SEC) */ 33262306a36Sopenharmony_ci { 0x820e7000, 0x21e00, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */ 33362306a36Sopenharmony_ci { 0x820cf000, 0x22000, 0x01000 }, /* WF_LMAC_TOP (WF_PF) */ 33462306a36Sopenharmony_ci { 0x820e9000, 0x23400, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ 33562306a36Sopenharmony_ci { 0x820ea000, 0x24000, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */ 33662306a36Sopenharmony_ci { 0x820eb000, 0x24200, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */ 33762306a36Sopenharmony_ci { 0x820ec000, 0x24600, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_INT) */ 33862306a36Sopenharmony_ci { 0x820ed000, 0x24800, 0x00800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */ 33962306a36Sopenharmony_ci { 0x820ca000, 0x26000, 0x02000 }, /* WF_LMAC_TOP BN0 (WF_MUCOP) */ 34062306a36Sopenharmony_ci { 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */ 34162306a36Sopenharmony_ci { 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */ 34262306a36Sopenharmony_ci { 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure cr) */ 34362306a36Sopenharmony_ci { 0x820f0000, 0xa0000, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */ 34462306a36Sopenharmony_ci { 0x820f1000, 0xa0600, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */ 34562306a36Sopenharmony_ci { 0x820f2000, 0xa0800, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */ 34662306a36Sopenharmony_ci { 0x820f3000, 0xa0c00, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */ 34762306a36Sopenharmony_ci { 0x820f4000, 0xa1000, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */ 34862306a36Sopenharmony_ci { 0x820f5000, 0xa1400, 0x00800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */ 34962306a36Sopenharmony_ci { 0x820f7000, 0xa1e00, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */ 35062306a36Sopenharmony_ci { 0x820f9000, 0xa3400, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ 35162306a36Sopenharmony_ci { 0x820fa000, 0xa4000, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */ 35262306a36Sopenharmony_ci { 0x820fb000, 0xa4200, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */ 35362306a36Sopenharmony_ci { 0x820fc000, 0xa4600, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_INT) */ 35462306a36Sopenharmony_ci { 0x820fd000, 0xa4800, 0x00800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */ 35562306a36Sopenharmony_ci { 0x820c4000, 0xa8000, 0x01000 }, /* WF_LMAC_TOP (WF_UWTBL ) */ 35662306a36Sopenharmony_ci { 0x820b0000, 0xae000, 0x01000 }, /* [APB2] WFSYS_ON */ 35762306a36Sopenharmony_ci { 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */ 35862306a36Sopenharmony_ci { 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */ 35962306a36Sopenharmony_ci { 0x0, 0x0, 0x0 }, /* imply end of search */ 36062306a36Sopenharmony_ci}; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_cistatic const struct mt76_connac_reg_map mt7986_reg_map[] = { 36362306a36Sopenharmony_ci { 0x54000000, 0x402000, 0x01000 }, /* WFDMA_0 (PCIE0 MCU DMA0) */ 36462306a36Sopenharmony_ci { 0x55000000, 0x403000, 0x01000 }, /* WFDMA_1 (PCIE0 MCU DMA1) */ 36562306a36Sopenharmony_ci { 0x56000000, 0x404000, 0x01000 }, /* WFDMA_2 (Reserved) */ 36662306a36Sopenharmony_ci { 0x57000000, 0x405000, 0x01000 }, /* WFDMA_3 (MCU wrap CR) */ 36762306a36Sopenharmony_ci { 0x58000000, 0x406000, 0x01000 }, /* WFDMA_4 (PCIE1 MCU DMA0) */ 36862306a36Sopenharmony_ci { 0x59000000, 0x407000, 0x01000 }, /* WFDMA_5 (PCIE1 MCU DMA1) */ 36962306a36Sopenharmony_ci { 0x820c0000, 0x408000, 0x04000 }, /* WF_UMAC_TOP (PLE) */ 37062306a36Sopenharmony_ci { 0x820c8000, 0x40c000, 0x02000 }, /* WF_UMAC_TOP (PSE) */ 37162306a36Sopenharmony_ci { 0x820cc000, 0x40e000, 0x02000 }, /* WF_UMAC_TOP (PP) */ 37262306a36Sopenharmony_ci { 0x820e0000, 0x420000, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */ 37362306a36Sopenharmony_ci { 0x820e1000, 0x420400, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */ 37462306a36Sopenharmony_ci { 0x820e2000, 0x420800, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */ 37562306a36Sopenharmony_ci { 0x820e3000, 0x420c00, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */ 37662306a36Sopenharmony_ci { 0x820e4000, 0x421000, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */ 37762306a36Sopenharmony_ci { 0x820e5000, 0x421400, 0x00800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */ 37862306a36Sopenharmony_ci { 0x820ce000, 0x421c00, 0x00200 }, /* WF_LMAC_TOP (WF_SEC) */ 37962306a36Sopenharmony_ci { 0x820e7000, 0x421e00, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */ 38062306a36Sopenharmony_ci { 0x820cf000, 0x422000, 0x01000 }, /* WF_LMAC_TOP (WF_PF) */ 38162306a36Sopenharmony_ci { 0x820e9000, 0x423400, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ 38262306a36Sopenharmony_ci { 0x820ea000, 0x424000, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */ 38362306a36Sopenharmony_ci { 0x820eb000, 0x424200, 0x00400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */ 38462306a36Sopenharmony_ci { 0x820ec000, 0x424600, 0x00200 }, /* WF_LMAC_TOP BN0 (WF_INT) */ 38562306a36Sopenharmony_ci { 0x820ed000, 0x424800, 0x00800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */ 38662306a36Sopenharmony_ci { 0x820ca000, 0x426000, 0x02000 }, /* WF_LMAC_TOP BN0 (WF_MUCOP) */ 38762306a36Sopenharmony_ci { 0x820d0000, 0x430000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */ 38862306a36Sopenharmony_ci { 0x00400000, 0x480000, 0x10000 }, /* WF_MCU_SYSRAM */ 38962306a36Sopenharmony_ci { 0x00410000, 0x490000, 0x10000 }, /* WF_MCU_SYSRAM */ 39062306a36Sopenharmony_ci { 0x820f0000, 0x4a0000, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */ 39162306a36Sopenharmony_ci { 0x820f1000, 0x4a0600, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */ 39262306a36Sopenharmony_ci { 0x820f2000, 0x4a0800, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */ 39362306a36Sopenharmony_ci { 0x820f3000, 0x4a0c00, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */ 39462306a36Sopenharmony_ci { 0x820f4000, 0x4a1000, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */ 39562306a36Sopenharmony_ci { 0x820f5000, 0x4a1400, 0x00800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */ 39662306a36Sopenharmony_ci { 0x820f7000, 0x4a1e00, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */ 39762306a36Sopenharmony_ci { 0x820f9000, 0x4a3400, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ 39862306a36Sopenharmony_ci { 0x820fa000, 0x4a4000, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */ 39962306a36Sopenharmony_ci { 0x820fb000, 0x4a4200, 0x00400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */ 40062306a36Sopenharmony_ci { 0x820fc000, 0x4a4600, 0x00200 }, /* WF_LMAC_TOP BN1 (WF_INT) */ 40162306a36Sopenharmony_ci { 0x820fd000, 0x4a4800, 0x00800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */ 40262306a36Sopenharmony_ci { 0x820c4000, 0x4a8000, 0x01000 }, /* WF_LMAC_TOP (WF_UWTBL ) */ 40362306a36Sopenharmony_ci { 0x820b0000, 0x4ae000, 0x01000 }, /* [APB2] WFSYS_ON */ 40462306a36Sopenharmony_ci { 0x80020000, 0x4b0000, 0x10000 }, /* WF_TOP_MISC_OFF */ 40562306a36Sopenharmony_ci { 0x81020000, 0x4c0000, 0x10000 }, /* WF_TOP_MISC_ON */ 40662306a36Sopenharmony_ci { 0x89000000, 0x4d0000, 0x01000 }, /* WF_MCU_CFG_ON */ 40762306a36Sopenharmony_ci { 0x89010000, 0x4d1000, 0x01000 }, /* WF_MCU_CIRQ */ 40862306a36Sopenharmony_ci { 0x89020000, 0x4d2000, 0x01000 }, /* WF_MCU_GPT */ 40962306a36Sopenharmony_ci { 0x89030000, 0x4d3000, 0x01000 }, /* WF_MCU_WDT */ 41062306a36Sopenharmony_ci { 0x80010000, 0x4d4000, 0x01000 }, /* WF_AXIDMA */ 41162306a36Sopenharmony_ci { 0x0, 0x0, 0x0 }, /* imply end of search */ 41262306a36Sopenharmony_ci}; 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_cistatic u32 mt7915_reg_map_l1(struct mt7915_dev *dev, u32 addr) 41562306a36Sopenharmony_ci{ 41662306a36Sopenharmony_ci u32 offset = FIELD_GET(MT_HIF_REMAP_L1_OFFSET, addr); 41762306a36Sopenharmony_ci u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr); 41862306a36Sopenharmony_ci u32 l1_remap; 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci if (is_mt798x(&dev->mt76)) 42162306a36Sopenharmony_ci return MT_CONN_INFRA_OFFSET(addr); 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci l1_remap = is_mt7915(&dev->mt76) ? 42462306a36Sopenharmony_ci MT_HIF_REMAP_L1 : MT_HIF_REMAP_L1_MT7916; 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci dev->bus_ops->rmw(&dev->mt76, l1_remap, 42762306a36Sopenharmony_ci MT_HIF_REMAP_L1_MASK, 42862306a36Sopenharmony_ci FIELD_PREP(MT_HIF_REMAP_L1_MASK, base)); 42962306a36Sopenharmony_ci /* use read to push write */ 43062306a36Sopenharmony_ci dev->bus_ops->rr(&dev->mt76, l1_remap); 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci return MT_HIF_REMAP_BASE_L1 + offset; 43362306a36Sopenharmony_ci} 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_cistatic u32 mt7915_reg_map_l2(struct mt7915_dev *dev, u32 addr) 43662306a36Sopenharmony_ci{ 43762306a36Sopenharmony_ci u32 offset, base; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci if (is_mt7915(&dev->mt76)) { 44062306a36Sopenharmony_ci offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET, addr); 44162306a36Sopenharmony_ci base = FIELD_GET(MT_HIF_REMAP_L2_BASE, addr); 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L2, 44462306a36Sopenharmony_ci MT_HIF_REMAP_L2_MASK, 44562306a36Sopenharmony_ci FIELD_PREP(MT_HIF_REMAP_L2_MASK, base)); 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci /* use read to push write */ 44862306a36Sopenharmony_ci dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2); 44962306a36Sopenharmony_ci } else { 45062306a36Sopenharmony_ci u32 ofs = is_mt798x(&dev->mt76) ? 0x400000 : 0; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET_MT7916, addr); 45362306a36Sopenharmony_ci base = FIELD_GET(MT_HIF_REMAP_L2_BASE_MT7916, addr); 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L2_MT7916 + ofs, 45662306a36Sopenharmony_ci MT_HIF_REMAP_L2_MASK_MT7916, 45762306a36Sopenharmony_ci FIELD_PREP(MT_HIF_REMAP_L2_MASK_MT7916, base)); 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci /* use read to push write */ 46062306a36Sopenharmony_ci dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2_MT7916 + ofs); 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci offset += (MT_HIF_REMAP_BASE_L2_MT7916 + ofs); 46362306a36Sopenharmony_ci } 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci return offset; 46662306a36Sopenharmony_ci} 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_cistatic u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr) 46962306a36Sopenharmony_ci{ 47062306a36Sopenharmony_ci int i; 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci if (addr < 0x100000) 47362306a36Sopenharmony_ci return addr; 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci if (!dev->reg.map) { 47662306a36Sopenharmony_ci dev_err(dev->mt76.dev, "err: reg_map is null\n"); 47762306a36Sopenharmony_ci return addr; 47862306a36Sopenharmony_ci } 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci for (i = 0; i < dev->reg.map_size; i++) { 48162306a36Sopenharmony_ci u32 ofs; 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci if (addr < dev->reg.map[i].phys) 48462306a36Sopenharmony_ci continue; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci ofs = addr - dev->reg.map[i].phys; 48762306a36Sopenharmony_ci if (ofs > dev->reg.map[i].size) 48862306a36Sopenharmony_ci continue; 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci return dev->reg.map[i].maps + ofs; 49162306a36Sopenharmony_ci } 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ci if ((addr >= MT_INFRA_BASE && addr < MT_WFSYS0_PHY_START) || 49462306a36Sopenharmony_ci (addr >= MT_WFSYS0_PHY_START && addr < MT_WFSYS1_PHY_START) || 49562306a36Sopenharmony_ci (addr >= MT_WFSYS1_PHY_START && addr <= MT_WFSYS1_PHY_END)) 49662306a36Sopenharmony_ci return mt7915_reg_map_l1(dev, addr); 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ci if (dev_is_pci(dev->mt76.dev) && 49962306a36Sopenharmony_ci ((addr >= MT_CBTOP1_PHY_START && addr <= MT_CBTOP1_PHY_END) || 50062306a36Sopenharmony_ci addr >= MT_CBTOP2_PHY_START)) 50162306a36Sopenharmony_ci return mt7915_reg_map_l1(dev, addr); 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci /* CONN_INFRA: covert to phyiscal addr and use layer 1 remap */ 50462306a36Sopenharmony_ci if (addr >= MT_INFRA_MCU_START && addr <= MT_INFRA_MCU_END) { 50562306a36Sopenharmony_ci addr = addr - MT_INFRA_MCU_START + MT_INFRA_BASE; 50662306a36Sopenharmony_ci return mt7915_reg_map_l1(dev, addr); 50762306a36Sopenharmony_ci } 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci return mt7915_reg_map_l2(dev, addr); 51062306a36Sopenharmony_ci} 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_civoid mt7915_memcpy_fromio(struct mt7915_dev *dev, void *buf, u32 offset, 51362306a36Sopenharmony_ci size_t len) 51462306a36Sopenharmony_ci{ 51562306a36Sopenharmony_ci u32 addr = __mt7915_reg_addr(dev, offset); 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci memcpy_fromio(buf, dev->mt76.mmio.regs + addr, len); 51862306a36Sopenharmony_ci} 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_cistatic u32 mt7915_rr(struct mt76_dev *mdev, u32 offset) 52162306a36Sopenharmony_ci{ 52262306a36Sopenharmony_ci struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); 52362306a36Sopenharmony_ci u32 addr = __mt7915_reg_addr(dev, offset); 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci return dev->bus_ops->rr(mdev, addr); 52662306a36Sopenharmony_ci} 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_cistatic void mt7915_wr(struct mt76_dev *mdev, u32 offset, u32 val) 52962306a36Sopenharmony_ci{ 53062306a36Sopenharmony_ci struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); 53162306a36Sopenharmony_ci u32 addr = __mt7915_reg_addr(dev, offset); 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci dev->bus_ops->wr(mdev, addr, val); 53462306a36Sopenharmony_ci} 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_cistatic u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val) 53762306a36Sopenharmony_ci{ 53862306a36Sopenharmony_ci struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); 53962306a36Sopenharmony_ci u32 addr = __mt7915_reg_addr(dev, offset); 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci return dev->bus_ops->rmw(mdev, addr, mask, val); 54262306a36Sopenharmony_ci} 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci#ifdef CONFIG_NET_MEDIATEK_SOC_WED 54562306a36Sopenharmony_cistatic int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed) 54662306a36Sopenharmony_ci{ 54762306a36Sopenharmony_ci struct mt7915_dev *dev; 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed); 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci spin_lock_bh(&dev->mt76.token_lock); 55262306a36Sopenharmony_ci dev->mt76.token_size = wed->wlan.token_start; 55362306a36Sopenharmony_ci spin_unlock_bh(&dev->mt76.token_lock); 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci return !wait_event_timeout(dev->mt76.tx_wait, 55662306a36Sopenharmony_ci !dev->mt76.wed_token_count, HZ); 55762306a36Sopenharmony_ci} 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_cistatic void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed) 56062306a36Sopenharmony_ci{ 56162306a36Sopenharmony_ci struct mt7915_dev *dev; 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed); 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci spin_lock_bh(&dev->mt76.token_lock); 56662306a36Sopenharmony_ci dev->mt76.token_size = MT7915_TOKEN_SIZE; 56762306a36Sopenharmony_ci spin_unlock_bh(&dev->mt76.token_lock); 56862306a36Sopenharmony_ci} 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_cistatic void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed) 57162306a36Sopenharmony_ci{ 57262306a36Sopenharmony_ci struct mt7915_dev *dev; 57362306a36Sopenharmony_ci int i; 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed); 57662306a36Sopenharmony_ci for (i = 0; i < dev->mt76.rx_token_size; i++) { 57762306a36Sopenharmony_ci struct mt76_txwi_cache *t; 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci t = mt76_rx_token_release(&dev->mt76, i); 58062306a36Sopenharmony_ci if (!t || !t->ptr) 58162306a36Sopenharmony_ci continue; 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci mt76_put_page_pool_buf(t->ptr, false); 58462306a36Sopenharmony_ci t->ptr = NULL; 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci mt76_put_rxwi(&dev->mt76, t); 58762306a36Sopenharmony_ci } 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci mt76_free_pending_rxwi(&dev->mt76); 59062306a36Sopenharmony_ci} 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_cistatic u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size) 59362306a36Sopenharmony_ci{ 59462306a36Sopenharmony_ci struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc; 59562306a36Sopenharmony_ci struct mt76_txwi_cache *t = NULL; 59662306a36Sopenharmony_ci struct mt7915_dev *dev; 59762306a36Sopenharmony_ci struct mt76_queue *q; 59862306a36Sopenharmony_ci int i, len; 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed); 60162306a36Sopenharmony_ci q = &dev->mt76.q_rx[MT_RXQ_MAIN]; 60262306a36Sopenharmony_ci len = SKB_WITH_OVERHEAD(q->buf_size); 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci for (i = 0; i < size; i++) { 60562306a36Sopenharmony_ci enum dma_data_direction dir; 60662306a36Sopenharmony_ci dma_addr_t addr; 60762306a36Sopenharmony_ci u32 offset; 60862306a36Sopenharmony_ci int token; 60962306a36Sopenharmony_ci void *buf; 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci t = mt76_get_rxwi(&dev->mt76); 61262306a36Sopenharmony_ci if (!t) 61362306a36Sopenharmony_ci goto unmap; 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci buf = mt76_get_page_pool_buf(q, &offset, q->buf_size); 61662306a36Sopenharmony_ci if (!buf) 61762306a36Sopenharmony_ci goto unmap; 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ci addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset; 62062306a36Sopenharmony_ci dir = page_pool_get_dma_dir(q->page_pool); 62162306a36Sopenharmony_ci dma_sync_single_for_device(dev->mt76.dma_dev, addr, len, dir); 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci desc->buf0 = cpu_to_le32(addr); 62462306a36Sopenharmony_ci token = mt76_rx_token_consume(&dev->mt76, buf, t, addr); 62562306a36Sopenharmony_ci if (token < 0) { 62662306a36Sopenharmony_ci mt76_put_page_pool_buf(buf, false); 62762306a36Sopenharmony_ci goto unmap; 62862306a36Sopenharmony_ci } 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN, 63162306a36Sopenharmony_ci token)); 63262306a36Sopenharmony_ci desc++; 63362306a36Sopenharmony_ci } 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci return 0; 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ciunmap: 63862306a36Sopenharmony_ci if (t) 63962306a36Sopenharmony_ci mt76_put_rxwi(&dev->mt76, t); 64062306a36Sopenharmony_ci mt7915_mmio_wed_release_rx_buf(wed); 64162306a36Sopenharmony_ci return -ENOMEM; 64262306a36Sopenharmony_ci} 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_cistatic void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed, 64562306a36Sopenharmony_ci struct mtk_wed_wo_rx_stats *stats) 64662306a36Sopenharmony_ci{ 64762306a36Sopenharmony_ci int idx = le16_to_cpu(stats->wlan_idx); 64862306a36Sopenharmony_ci struct mt7915_dev *dev; 64962306a36Sopenharmony_ci struct mt76_wcid *wcid; 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed); 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_ci if (idx >= mt7915_wtbl_size(dev)) 65462306a36Sopenharmony_ci return; 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci rcu_read_lock(); 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci wcid = rcu_dereference(dev->mt76.wcid[idx]); 65962306a36Sopenharmony_ci if (wcid) { 66062306a36Sopenharmony_ci wcid->stats.rx_bytes += le32_to_cpu(stats->rx_byte_cnt); 66162306a36Sopenharmony_ci wcid->stats.rx_packets += le32_to_cpu(stats->rx_pkt_cnt); 66262306a36Sopenharmony_ci wcid->stats.rx_errors += le32_to_cpu(stats->rx_err_cnt); 66362306a36Sopenharmony_ci wcid->stats.rx_drops += le32_to_cpu(stats->rx_drop_cnt); 66462306a36Sopenharmony_ci } 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ci rcu_read_unlock(); 66762306a36Sopenharmony_ci} 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_cistatic int mt7915_mmio_wed_reset(struct mtk_wed_device *wed) 67062306a36Sopenharmony_ci{ 67162306a36Sopenharmony_ci struct mt76_dev *mdev = container_of(wed, struct mt76_dev, mmio.wed); 67262306a36Sopenharmony_ci struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); 67362306a36Sopenharmony_ci struct mt76_phy *mphy = &dev->mphy; 67462306a36Sopenharmony_ci int ret; 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci ASSERT_RTNL(); 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci if (test_and_set_bit(MT76_STATE_WED_RESET, &mphy->state)) 67962306a36Sopenharmony_ci return -EBUSY; 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_ci ret = mt7915_mcu_set_ser(dev, SER_RECOVER, SER_SET_RECOVER_L1, 68262306a36Sopenharmony_ci mphy->band_idx); 68362306a36Sopenharmony_ci if (ret) 68462306a36Sopenharmony_ci goto out; 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_ci rtnl_unlock(); 68762306a36Sopenharmony_ci if (!wait_for_completion_timeout(&mdev->mmio.wed_reset, 20 * HZ)) { 68862306a36Sopenharmony_ci dev_err(mdev->dev, "wed reset timeout\n"); 68962306a36Sopenharmony_ci ret = -ETIMEDOUT; 69062306a36Sopenharmony_ci } 69162306a36Sopenharmony_ci rtnl_lock(); 69262306a36Sopenharmony_ciout: 69362306a36Sopenharmony_ci clear_bit(MT76_STATE_WED_RESET, &mphy->state); 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci return ret; 69662306a36Sopenharmony_ci} 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_cistatic void mt7915_mmio_wed_reset_complete(struct mtk_wed_device *wed) 69962306a36Sopenharmony_ci{ 70062306a36Sopenharmony_ci struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci complete(&dev->mmio.wed_reset_complete); 70362306a36Sopenharmony_ci} 70462306a36Sopenharmony_ci#endif 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ciint mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, 70762306a36Sopenharmony_ci bool pci, int *irq) 70862306a36Sopenharmony_ci{ 70962306a36Sopenharmony_ci#ifdef CONFIG_NET_MEDIATEK_SOC_WED 71062306a36Sopenharmony_ci struct mtk_wed_device *wed = &dev->mt76.mmio.wed; 71162306a36Sopenharmony_ci int ret; 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci if (!wed_enable) 71462306a36Sopenharmony_ci return 0; 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci if (pci) { 71762306a36Sopenharmony_ci struct pci_dev *pci_dev = pdev_ptr; 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_ci wed->wlan.pci_dev = pci_dev; 72062306a36Sopenharmony_ci wed->wlan.bus_type = MTK_WED_BUS_PCIE; 72162306a36Sopenharmony_ci wed->wlan.base = devm_ioremap(dev->mt76.dev, 72262306a36Sopenharmony_ci pci_resource_start(pci_dev, 0), 72362306a36Sopenharmony_ci pci_resource_len(pci_dev, 0)); 72462306a36Sopenharmony_ci wed->wlan.phy_base = pci_resource_start(pci_dev, 0); 72562306a36Sopenharmony_ci wed->wlan.wpdma_int = pci_resource_start(pci_dev, 0) + 72662306a36Sopenharmony_ci MT_INT_WED_SOURCE_CSR; 72762306a36Sopenharmony_ci wed->wlan.wpdma_mask = pci_resource_start(pci_dev, 0) + 72862306a36Sopenharmony_ci MT_INT_WED_MASK_CSR; 72962306a36Sopenharmony_ci wed->wlan.wpdma_phys = pci_resource_start(pci_dev, 0) + 73062306a36Sopenharmony_ci MT_WFDMA_EXT_CSR_BASE; 73162306a36Sopenharmony_ci wed->wlan.wpdma_tx = pci_resource_start(pci_dev, 0) + 73262306a36Sopenharmony_ci MT_TXQ_WED_RING_BASE; 73362306a36Sopenharmony_ci wed->wlan.wpdma_txfree = pci_resource_start(pci_dev, 0) + 73462306a36Sopenharmony_ci MT_RXQ_WED_RING_BASE; 73562306a36Sopenharmony_ci wed->wlan.wpdma_rx_glo = pci_resource_start(pci_dev, 0) + 73662306a36Sopenharmony_ci MT_WPDMA_GLO_CFG; 73762306a36Sopenharmony_ci wed->wlan.wpdma_rx = pci_resource_start(pci_dev, 0) + 73862306a36Sopenharmony_ci MT_RXQ_WED_DATA_RING_BASE; 73962306a36Sopenharmony_ci } else { 74062306a36Sopenharmony_ci struct platform_device *plat_dev = pdev_ptr; 74162306a36Sopenharmony_ci struct resource *res; 74262306a36Sopenharmony_ci 74362306a36Sopenharmony_ci res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0); 74462306a36Sopenharmony_ci if (!res) 74562306a36Sopenharmony_ci return 0; 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_ci wed->wlan.platform_dev = plat_dev; 74862306a36Sopenharmony_ci wed->wlan.bus_type = MTK_WED_BUS_AXI; 74962306a36Sopenharmony_ci wed->wlan.base = devm_ioremap(dev->mt76.dev, res->start, 75062306a36Sopenharmony_ci resource_size(res)); 75162306a36Sopenharmony_ci wed->wlan.phy_base = res->start; 75262306a36Sopenharmony_ci wed->wlan.wpdma_int = res->start + MT_INT_SOURCE_CSR; 75362306a36Sopenharmony_ci wed->wlan.wpdma_mask = res->start + MT_INT_MASK_CSR; 75462306a36Sopenharmony_ci wed->wlan.wpdma_tx = res->start + MT_TXQ_WED_RING_BASE; 75562306a36Sopenharmony_ci wed->wlan.wpdma_txfree = res->start + MT_RXQ_WED_RING_BASE; 75662306a36Sopenharmony_ci wed->wlan.wpdma_rx_glo = res->start + MT_WPDMA_GLO_CFG; 75762306a36Sopenharmony_ci wed->wlan.wpdma_rx = res->start + MT_RXQ_WED_DATA_RING_BASE; 75862306a36Sopenharmony_ci } 75962306a36Sopenharmony_ci wed->wlan.nbuf = MT7915_HW_TOKEN_SIZE; 76062306a36Sopenharmony_ci wed->wlan.tx_tbit[0] = is_mt7915(&dev->mt76) ? 4 : 30; 76162306a36Sopenharmony_ci wed->wlan.tx_tbit[1] = is_mt7915(&dev->mt76) ? 5 : 31; 76262306a36Sopenharmony_ci wed->wlan.txfree_tbit = is_mt798x(&dev->mt76) ? 2 : 1; 76362306a36Sopenharmony_ci wed->wlan.token_start = MT7915_TOKEN_SIZE - wed->wlan.nbuf; 76462306a36Sopenharmony_ci wed->wlan.wcid_512 = !is_mt7915(&dev->mt76); 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci wed->wlan.rx_nbuf = 65536; 76762306a36Sopenharmony_ci wed->wlan.rx_npkt = MT7915_WED_RX_TOKEN_SIZE; 76862306a36Sopenharmony_ci wed->wlan.rx_size = SKB_WITH_OVERHEAD(MT_RX_BUF_SIZE); 76962306a36Sopenharmony_ci if (is_mt7915(&dev->mt76)) { 77062306a36Sopenharmony_ci wed->wlan.rx_tbit[0] = 16; 77162306a36Sopenharmony_ci wed->wlan.rx_tbit[1] = 17; 77262306a36Sopenharmony_ci } else if (is_mt798x(&dev->mt76)) { 77362306a36Sopenharmony_ci wed->wlan.rx_tbit[0] = 22; 77462306a36Sopenharmony_ci wed->wlan.rx_tbit[1] = 23; 77562306a36Sopenharmony_ci } else { 77662306a36Sopenharmony_ci wed->wlan.rx_tbit[0] = 18; 77762306a36Sopenharmony_ci wed->wlan.rx_tbit[1] = 19; 77862306a36Sopenharmony_ci } 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_ci wed->wlan.init_buf = mt7915_wed_init_buf; 78162306a36Sopenharmony_ci wed->wlan.offload_enable = mt7915_mmio_wed_offload_enable; 78262306a36Sopenharmony_ci wed->wlan.offload_disable = mt7915_mmio_wed_offload_disable; 78362306a36Sopenharmony_ci wed->wlan.init_rx_buf = mt7915_mmio_wed_init_rx_buf; 78462306a36Sopenharmony_ci wed->wlan.release_rx_buf = mt7915_mmio_wed_release_rx_buf; 78562306a36Sopenharmony_ci wed->wlan.update_wo_rx_stats = mt7915_mmio_wed_update_rx_stats; 78662306a36Sopenharmony_ci wed->wlan.reset = mt7915_mmio_wed_reset; 78762306a36Sopenharmony_ci wed->wlan.reset_complete = mt7915_mmio_wed_reset_complete; 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_ci dev->mt76.rx_token_size = wed->wlan.rx_npkt; 79062306a36Sopenharmony_ci 79162306a36Sopenharmony_ci if (mtk_wed_device_attach(wed)) 79262306a36Sopenharmony_ci return 0; 79362306a36Sopenharmony_ci 79462306a36Sopenharmony_ci *irq = wed->irq; 79562306a36Sopenharmony_ci dev->mt76.dma_dev = wed->dev; 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_ci ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32)); 79862306a36Sopenharmony_ci if (ret) 79962306a36Sopenharmony_ci return ret; 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci return 1; 80262306a36Sopenharmony_ci#else 80362306a36Sopenharmony_ci return 0; 80462306a36Sopenharmony_ci#endif 80562306a36Sopenharmony_ci} 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_cistatic int mt7915_mmio_init(struct mt76_dev *mdev, 80862306a36Sopenharmony_ci void __iomem *mem_base, 80962306a36Sopenharmony_ci u32 device_id) 81062306a36Sopenharmony_ci{ 81162306a36Sopenharmony_ci struct mt76_bus_ops *bus_ops; 81262306a36Sopenharmony_ci struct mt7915_dev *dev; 81362306a36Sopenharmony_ci 81462306a36Sopenharmony_ci dev = container_of(mdev, struct mt7915_dev, mt76); 81562306a36Sopenharmony_ci mt76_mmio_init(&dev->mt76, mem_base); 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci switch (device_id) { 81862306a36Sopenharmony_ci case 0x7915: 81962306a36Sopenharmony_ci dev->reg.reg_rev = mt7915_reg; 82062306a36Sopenharmony_ci dev->reg.offs_rev = mt7915_offs; 82162306a36Sopenharmony_ci dev->reg.map = mt7915_reg_map; 82262306a36Sopenharmony_ci dev->reg.map_size = ARRAY_SIZE(mt7915_reg_map); 82362306a36Sopenharmony_ci break; 82462306a36Sopenharmony_ci case 0x7906: 82562306a36Sopenharmony_ci dev->reg.reg_rev = mt7916_reg; 82662306a36Sopenharmony_ci dev->reg.offs_rev = mt7916_offs; 82762306a36Sopenharmony_ci dev->reg.map = mt7916_reg_map; 82862306a36Sopenharmony_ci dev->reg.map_size = ARRAY_SIZE(mt7916_reg_map); 82962306a36Sopenharmony_ci break; 83062306a36Sopenharmony_ci case 0x7981: 83162306a36Sopenharmony_ci case 0x7986: 83262306a36Sopenharmony_ci dev->reg.reg_rev = mt7986_reg; 83362306a36Sopenharmony_ci dev->reg.offs_rev = mt7916_offs; 83462306a36Sopenharmony_ci dev->reg.map = mt7986_reg_map; 83562306a36Sopenharmony_ci dev->reg.map_size = ARRAY_SIZE(mt7986_reg_map); 83662306a36Sopenharmony_ci break; 83762306a36Sopenharmony_ci default: 83862306a36Sopenharmony_ci return -EINVAL; 83962306a36Sopenharmony_ci } 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci dev->bus_ops = dev->mt76.bus; 84262306a36Sopenharmony_ci bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops), 84362306a36Sopenharmony_ci GFP_KERNEL); 84462306a36Sopenharmony_ci if (!bus_ops) 84562306a36Sopenharmony_ci return -ENOMEM; 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci bus_ops->rr = mt7915_rr; 84862306a36Sopenharmony_ci bus_ops->wr = mt7915_wr; 84962306a36Sopenharmony_ci bus_ops->rmw = mt7915_rmw; 85062306a36Sopenharmony_ci dev->mt76.bus = bus_ops; 85162306a36Sopenharmony_ci 85262306a36Sopenharmony_ci mdev->rev = (device_id << 16) | 85362306a36Sopenharmony_ci (mt76_rr(dev, MT_HW_REV) & 0xff); 85462306a36Sopenharmony_ci dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev); 85562306a36Sopenharmony_ci 85662306a36Sopenharmony_ci return 0; 85762306a36Sopenharmony_ci} 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_civoid mt7915_dual_hif_set_irq_mask(struct mt7915_dev *dev, 86062306a36Sopenharmony_ci bool write_reg, 86162306a36Sopenharmony_ci u32 clear, u32 set) 86262306a36Sopenharmony_ci{ 86362306a36Sopenharmony_ci struct mt76_dev *mdev = &dev->mt76; 86462306a36Sopenharmony_ci unsigned long flags; 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_ci spin_lock_irqsave(&mdev->mmio.irq_lock, flags); 86762306a36Sopenharmony_ci 86862306a36Sopenharmony_ci mdev->mmio.irqmask &= ~clear; 86962306a36Sopenharmony_ci mdev->mmio.irqmask |= set; 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci if (write_reg) { 87262306a36Sopenharmony_ci if (mtk_wed_device_active(&mdev->mmio.wed)) 87362306a36Sopenharmony_ci mtk_wed_device_irq_set_mask(&mdev->mmio.wed, 87462306a36Sopenharmony_ci mdev->mmio.irqmask); 87562306a36Sopenharmony_ci else 87662306a36Sopenharmony_ci mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask); 87762306a36Sopenharmony_ci mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask); 87862306a36Sopenharmony_ci } 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_ci spin_unlock_irqrestore(&mdev->mmio.irq_lock, flags); 88162306a36Sopenharmony_ci} 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_cistatic void mt7915_rx_poll_complete(struct mt76_dev *mdev, 88462306a36Sopenharmony_ci enum mt76_rxq_id q) 88562306a36Sopenharmony_ci{ 88662306a36Sopenharmony_ci struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_ci mt7915_irq_enable(dev, MT_INT_RX(q)); 88962306a36Sopenharmony_ci} 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci/* TODO: support 2/4/6/8 MSI-X vectors */ 89262306a36Sopenharmony_cistatic void mt7915_irq_tasklet(struct tasklet_struct *t) 89362306a36Sopenharmony_ci{ 89462306a36Sopenharmony_ci struct mt7915_dev *dev = from_tasklet(dev, t, mt76.irq_tasklet); 89562306a36Sopenharmony_ci struct mtk_wed_device *wed = &dev->mt76.mmio.wed; 89662306a36Sopenharmony_ci u32 intr, intr1, mask; 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_ci if (mtk_wed_device_active(wed)) { 89962306a36Sopenharmony_ci mtk_wed_device_irq_set_mask(wed, 0); 90062306a36Sopenharmony_ci if (dev->hif2) 90162306a36Sopenharmony_ci mt76_wr(dev, MT_INT1_MASK_CSR, 0); 90262306a36Sopenharmony_ci intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask); 90362306a36Sopenharmony_ci } else { 90462306a36Sopenharmony_ci mt76_wr(dev, MT_INT_MASK_CSR, 0); 90562306a36Sopenharmony_ci if (dev->hif2) 90662306a36Sopenharmony_ci mt76_wr(dev, MT_INT1_MASK_CSR, 0); 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci intr = mt76_rr(dev, MT_INT_SOURCE_CSR); 90962306a36Sopenharmony_ci intr &= dev->mt76.mmio.irqmask; 91062306a36Sopenharmony_ci mt76_wr(dev, MT_INT_SOURCE_CSR, intr); 91162306a36Sopenharmony_ci } 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_ci if (dev->hif2) { 91462306a36Sopenharmony_ci intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR); 91562306a36Sopenharmony_ci intr1 &= dev->mt76.mmio.irqmask; 91662306a36Sopenharmony_ci mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1); 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_ci intr |= intr1; 91962306a36Sopenharmony_ci } 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_ci trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask); 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ci mask = intr & MT_INT_RX_DONE_ALL; 92462306a36Sopenharmony_ci if (intr & MT_INT_TX_DONE_MCU) 92562306a36Sopenharmony_ci mask |= MT_INT_TX_DONE_MCU; 92662306a36Sopenharmony_ci 92762306a36Sopenharmony_ci mt7915_irq_disable(dev, mask); 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_ci if (intr & MT_INT_TX_DONE_MCU) 93062306a36Sopenharmony_ci napi_schedule(&dev->mt76.tx_napi); 93162306a36Sopenharmony_ci 93262306a36Sopenharmony_ci if (intr & MT_INT_RX(MT_RXQ_MAIN)) 93362306a36Sopenharmony_ci napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN]); 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci if (intr & MT_INT_RX(MT_RXQ_BAND1)) 93662306a36Sopenharmony_ci napi_schedule(&dev->mt76.napi[MT_RXQ_BAND1]); 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_ci if (intr & MT_INT_RX(MT_RXQ_MCU)) 93962306a36Sopenharmony_ci napi_schedule(&dev->mt76.napi[MT_RXQ_MCU]); 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci if (intr & MT_INT_RX(MT_RXQ_MCU_WA)) 94262306a36Sopenharmony_ci napi_schedule(&dev->mt76.napi[MT_RXQ_MCU_WA]); 94362306a36Sopenharmony_ci 94462306a36Sopenharmony_ci if (!is_mt7915(&dev->mt76) && 94562306a36Sopenharmony_ci (intr & MT_INT_RX(MT_RXQ_MAIN_WA))) 94662306a36Sopenharmony_ci napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN_WA]); 94762306a36Sopenharmony_ci 94862306a36Sopenharmony_ci if (intr & MT_INT_RX(MT_RXQ_BAND1_WA)) 94962306a36Sopenharmony_ci napi_schedule(&dev->mt76.napi[MT_RXQ_BAND1_WA]); 95062306a36Sopenharmony_ci 95162306a36Sopenharmony_ci if (intr & MT_INT_MCU_CMD) { 95262306a36Sopenharmony_ci u32 val = mt76_rr(dev, MT_MCU_CMD); 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci mt76_wr(dev, MT_MCU_CMD, val); 95562306a36Sopenharmony_ci if (val & (MT_MCU_CMD_ERROR_MASK | MT_MCU_CMD_WDT_MASK)) { 95662306a36Sopenharmony_ci dev->recovery.state = val; 95762306a36Sopenharmony_ci mt7915_reset(dev); 95862306a36Sopenharmony_ci } 95962306a36Sopenharmony_ci } 96062306a36Sopenharmony_ci} 96162306a36Sopenharmony_ci 96262306a36Sopenharmony_ciirqreturn_t mt7915_irq_handler(int irq, void *dev_instance) 96362306a36Sopenharmony_ci{ 96462306a36Sopenharmony_ci struct mt7915_dev *dev = dev_instance; 96562306a36Sopenharmony_ci struct mtk_wed_device *wed = &dev->mt76.mmio.wed; 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci if (mtk_wed_device_active(wed)) 96862306a36Sopenharmony_ci mtk_wed_device_irq_set_mask(wed, 0); 96962306a36Sopenharmony_ci else 97062306a36Sopenharmony_ci mt76_wr(dev, MT_INT_MASK_CSR, 0); 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci if (dev->hif2) 97362306a36Sopenharmony_ci mt76_wr(dev, MT_INT1_MASK_CSR, 0); 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state)) 97662306a36Sopenharmony_ci return IRQ_NONE; 97762306a36Sopenharmony_ci 97862306a36Sopenharmony_ci tasklet_schedule(&dev->mt76.irq_tasklet); 97962306a36Sopenharmony_ci 98062306a36Sopenharmony_ci return IRQ_HANDLED; 98162306a36Sopenharmony_ci} 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_cistruct mt7915_dev *mt7915_mmio_probe(struct device *pdev, 98462306a36Sopenharmony_ci void __iomem *mem_base, u32 device_id) 98562306a36Sopenharmony_ci{ 98662306a36Sopenharmony_ci static const struct mt76_driver_ops drv_ops = { 98762306a36Sopenharmony_ci /* txwi_size = txd size + txp size */ 98862306a36Sopenharmony_ci .txwi_size = MT_TXD_SIZE + sizeof(struct mt76_connac_fw_txp), 98962306a36Sopenharmony_ci .drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ | 99062306a36Sopenharmony_ci MT_DRV_AMSDU_OFFLOAD, 99162306a36Sopenharmony_ci .survey_flags = SURVEY_INFO_TIME_TX | 99262306a36Sopenharmony_ci SURVEY_INFO_TIME_RX | 99362306a36Sopenharmony_ci SURVEY_INFO_TIME_BSS_RX, 99462306a36Sopenharmony_ci .token_size = MT7915_TOKEN_SIZE, 99562306a36Sopenharmony_ci .tx_prepare_skb = mt7915_tx_prepare_skb, 99662306a36Sopenharmony_ci .tx_complete_skb = mt76_connac_tx_complete_skb, 99762306a36Sopenharmony_ci .rx_skb = mt7915_queue_rx_skb, 99862306a36Sopenharmony_ci .rx_check = mt7915_rx_check, 99962306a36Sopenharmony_ci .rx_poll_complete = mt7915_rx_poll_complete, 100062306a36Sopenharmony_ci .sta_add = mt7915_mac_sta_add, 100162306a36Sopenharmony_ci .sta_remove = mt7915_mac_sta_remove, 100262306a36Sopenharmony_ci .update_survey = mt7915_update_channel, 100362306a36Sopenharmony_ci }; 100462306a36Sopenharmony_ci struct mt7915_dev *dev; 100562306a36Sopenharmony_ci struct mt76_dev *mdev; 100662306a36Sopenharmony_ci int ret; 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_ci mdev = mt76_alloc_device(pdev, sizeof(*dev), &mt7915_ops, &drv_ops); 100962306a36Sopenharmony_ci if (!mdev) 101062306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_ci dev = container_of(mdev, struct mt7915_dev, mt76); 101362306a36Sopenharmony_ci 101462306a36Sopenharmony_ci ret = mt7915_mmio_init(mdev, mem_base, device_id); 101562306a36Sopenharmony_ci if (ret) 101662306a36Sopenharmony_ci goto error; 101762306a36Sopenharmony_ci 101862306a36Sopenharmony_ci tasklet_setup(&mdev->irq_tasklet, mt7915_irq_tasklet); 101962306a36Sopenharmony_ci 102062306a36Sopenharmony_ci return dev; 102162306a36Sopenharmony_ci 102262306a36Sopenharmony_cierror: 102362306a36Sopenharmony_ci mt76_free_device(&dev->mt76); 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_ci return ERR_PTR(ret); 102662306a36Sopenharmony_ci} 102762306a36Sopenharmony_ci 102862306a36Sopenharmony_cistatic int __init mt7915_init(void) 102962306a36Sopenharmony_ci{ 103062306a36Sopenharmony_ci int ret; 103162306a36Sopenharmony_ci 103262306a36Sopenharmony_ci ret = pci_register_driver(&mt7915_hif_driver); 103362306a36Sopenharmony_ci if (ret) 103462306a36Sopenharmony_ci return ret; 103562306a36Sopenharmony_ci 103662306a36Sopenharmony_ci ret = pci_register_driver(&mt7915_pci_driver); 103762306a36Sopenharmony_ci if (ret) 103862306a36Sopenharmony_ci goto error_pci; 103962306a36Sopenharmony_ci 104062306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_MT798X_WMAC)) { 104162306a36Sopenharmony_ci ret = platform_driver_register(&mt798x_wmac_driver); 104262306a36Sopenharmony_ci if (ret) 104362306a36Sopenharmony_ci goto error_wmac; 104462306a36Sopenharmony_ci } 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_ci return 0; 104762306a36Sopenharmony_ci 104862306a36Sopenharmony_cierror_wmac: 104962306a36Sopenharmony_ci pci_unregister_driver(&mt7915_pci_driver); 105062306a36Sopenharmony_cierror_pci: 105162306a36Sopenharmony_ci pci_unregister_driver(&mt7915_hif_driver); 105262306a36Sopenharmony_ci 105362306a36Sopenharmony_ci return ret; 105462306a36Sopenharmony_ci} 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_cistatic void __exit mt7915_exit(void) 105762306a36Sopenharmony_ci{ 105862306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_MT798X_WMAC)) 105962306a36Sopenharmony_ci platform_driver_unregister(&mt798x_wmac_driver); 106062306a36Sopenharmony_ci 106162306a36Sopenharmony_ci pci_unregister_driver(&mt7915_pci_driver); 106262306a36Sopenharmony_ci pci_unregister_driver(&mt7915_hif_driver); 106362306a36Sopenharmony_ci} 106462306a36Sopenharmony_ci 106562306a36Sopenharmony_cimodule_init(mt7915_init); 106662306a36Sopenharmony_cimodule_exit(mt7915_exit); 106762306a36Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 1068