1 // SPDX-License-Identifier: ISC 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 4 #include <linux/kernel.h> 5 #include <linux/module.h> 6 #include <linux/platform_device.h> 7 #include <linux/pci.h> 8 9 #include "mt7915.h" 10 #include "mac.h" 11 #include "../trace.h" 12 13 static const u32 mt7915_reg[] = { 14 [INT_SOURCE_CSR] = 0xd7010, 15 [INT_MASK_CSR] = 0xd7014, 16 [INT1_SOURCE_CSR] = 0xd7088, 17 [INT1_MASK_CSR] = 0xd708c, 18 [INT_MCU_CMD_SOURCE] = 0xd51f0, 19 [INT_MCU_CMD_EVENT] = 0x3108, 20 }; 21 22 static const u32 mt7916_reg[] = { 23 [INT_SOURCE_CSR] = 0xd4200, 24 [INT_MASK_CSR] = 0xd4204, 25 [INT1_SOURCE_CSR] = 0xd8200, 26 [INT1_MASK_CSR] = 0xd8204, 27 [INT_MCU_CMD_SOURCE] = 0xd41f0, 28 [INT_MCU_CMD_EVENT] = 0x2108, 29 }; 30 31 static const u32 mt7915_offs[] = { 32 [TMAC_CDTR] = 0x090, 33 [TMAC_ODTR] = 0x094, 34 [TMAC_ATCR] = 0x098, 35 [TMAC_TRCR0] = 0x09c, 36 [TMAC_ICR0] = 0x0a4, 37 [TMAC_ICR1] = 0x0b4, 38 [TMAC_CTCR0] = 0x0f4, 39 [TMAC_TFCR0] = 0x1e0, 40 [MDP_BNRCFR0] = 0x070, 41 [MDP_BNRCFR1] = 0x074, 42 [ARB_DRNGR0] = 0x194, 43 [ARB_SCR] = 0x080, 44 [RMAC_MIB_AIRTIME14] = 0x3b8, 45 [AGG_AWSCR0] = 0x05c, 46 [AGG_PCR0] = 0x06c, 47 [AGG_ACR0] = 0x084, 48 [AGG_MRCR] = 0x098, 49 [AGG_ATCR1] = 0x0f0, 50 [AGG_ATCR3] = 0x0f4, 51 [LPON_UTTR0] = 0x080, 52 [LPON_UTTR1] = 0x084, 53 [LPON_FRCR] = 0x314, 54 [MIB_SDR3] = 0x014, 55 [MIB_SDR4] = 0x018, 56 [MIB_SDR5] = 0x01c, 57 [MIB_SDR7] = 0x024, 58 [MIB_SDR8] = 0x028, 59 [MIB_SDR9] = 0x02c, 60 [MIB_SDR10] = 0x030, 61 [MIB_SDR11] = 0x034, 62 [MIB_SDR12] = 0x038, 63 [MIB_SDR13] = 0x03c, 64 [MIB_SDR14] = 0x040, 65 [MIB_SDR15] = 0x044, 66 [MIB_SDR16] = 0x048, 67 [MIB_SDR17] = 0x04c, 68 [MIB_SDR18] = 0x050, 69 [MIB_SDR19] = 0x054, 70 [MIB_SDR20] = 0x058, 71 [MIB_SDR21] = 0x05c, 72 [MIB_SDR22] = 0x060, 73 [MIB_SDR23] = 0x064, 74 [MIB_SDR24] = 0x068, 75 [MIB_SDR25] = 0x06c, 76 [MIB_SDR27] = 0x074, 77 [MIB_SDR28] = 0x078, 78 [MIB_SDR29] = 0x07c, 79 [MIB_SDRVEC] = 0x080, 80 [MIB_SDR31] = 0x084, 81 [MIB_SDR32] = 0x088, 82 [MIB_SDRMUBF] = 0x090, 83 [MIB_DR8] = 0x0c0, 84 [MIB_DR9] = 0x0c4, 85 [MIB_DR11] = 0x0cc, 86 [MIB_MB_SDR0] = 0x100, 87 [MIB_MB_SDR1] = 0x104, 88 [TX_AGG_CNT] = 0x0a8, 89 [TX_AGG_CNT2] = 0x164, 90 [MIB_ARNG] = 0x4b8, 91 [WTBLON_TOP_WDUCR] = 0x0, 92 [WTBL_UPDATE] = 0x030, 93 [PLE_FL_Q_EMPTY] = 0x0b0, 94 [PLE_FL_Q_CTRL] = 0x1b0, 95 [PLE_AC_QEMPTY] = 0x500, 96 [PLE_FREEPG_CNT] = 0x100, 97 [PLE_FREEPG_HEAD_TAIL] = 0x104, 98 [PLE_PG_HIF_GROUP] = 0x110, 99 [PLE_HIF_PG_INFO] = 0x114, 100 [AC_OFFSET] = 0x040, 101 }; 102 103 static const u32 mt7916_offs[] = { 104 [TMAC_CDTR] = 0x0c8, 105 [TMAC_ODTR] = 0x0cc, 106 [TMAC_ATCR] = 0x00c, 107 [TMAC_TRCR0] = 0x010, 108 [TMAC_ICR0] = 0x014, 109 [TMAC_ICR1] = 0x018, 110 [TMAC_CTCR0] = 0x114, 111 [TMAC_TFCR0] = 0x0e4, 112 [MDP_BNRCFR0] = 0x090, 113 [MDP_BNRCFR1] = 0x094, 114 [ARB_DRNGR0] = 0x1e0, 115 [ARB_SCR] = 0x000, 116 [RMAC_MIB_AIRTIME14] = 0x0398, 117 [AGG_AWSCR0] = 0x030, 118 [AGG_PCR0] = 0x040, 119 [AGG_ACR0] = 0x054, 120 [AGG_MRCR] = 0x068, 121 [AGG_ATCR1] = 0x1a8, 122 [AGG_ATCR3] = 0x080, 123 [LPON_UTTR0] = 0x360, 124 [LPON_UTTR1] = 0x364, 125 [LPON_FRCR] = 0x37c, 126 [MIB_SDR3] = 0x698, 127 [MIB_SDR4] = 0x788, 128 [MIB_SDR5] = 0x780, 129 [MIB_SDR7] = 0x5a8, 130 [MIB_SDR8] = 0x78c, 131 [MIB_SDR9] = 0x024, 132 [MIB_SDR10] = 0x76c, 133 [MIB_SDR11] = 0x790, 134 [MIB_SDR12] = 0x558, 135 [MIB_SDR13] = 0x560, 136 [MIB_SDR14] = 0x564, 137 [MIB_SDR15] = 0x568, 138 [MIB_SDR16] = 0x7fc, 139 [MIB_SDR17] = 0x800, 140 [MIB_SDR18] = 0x030, 141 [MIB_SDR19] = 0x5ac, 142 [MIB_SDR20] = 0x5b0, 143 [MIB_SDR21] = 0x5b4, 144 [MIB_SDR22] = 0x770, 145 [MIB_SDR23] = 0x774, 146 [MIB_SDR24] = 0x778, 147 [MIB_SDR25] = 0x77c, 148 [MIB_SDR27] = 0x080, 149 [MIB_SDR28] = 0x084, 150 [MIB_SDR29] = 0x650, 151 [MIB_SDRVEC] = 0x5a8, 152 [MIB_SDR31] = 0x55c, 153 [MIB_SDR32] = 0x7a8, 154 [MIB_SDRMUBF] = 0x7ac, 155 [MIB_DR8] = 0x56c, 156 [MIB_DR9] = 0x570, 157 [MIB_DR11] = 0x574, 158 [MIB_MB_SDR0] = 0x688, 159 [MIB_MB_SDR1] = 0x690, 160 [TX_AGG_CNT] = 0x7dc, 161 [TX_AGG_CNT2] = 0x7ec, 162 [MIB_ARNG] = 0x0b0, 163 [WTBLON_TOP_WDUCR] = 0x200, 164 [WTBL_UPDATE] = 0x230, 165 [PLE_FL_Q_EMPTY] = 0x360, 166 [PLE_FL_Q_CTRL] = 0x3e0, 167 [PLE_AC_QEMPTY] = 0x600, 168 [PLE_FREEPG_CNT] = 0x380, 169 [PLE_FREEPG_HEAD_TAIL] = 0x384, 170 [PLE_PG_HIF_GROUP] = 0x00c, 171 [PLE_HIF_PG_INFO] = 0x388, 172 [AC_OFFSET] = 0x080, 173 }; 174 175 static const struct __map mt7915_reg_map[] = { 176 { 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */ 177 { 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure regs) */ 178 { 0x40000000, 0x70000, 0x10000 }, /* WF_UMAC_SYSRAM */ 179 { 0x54000000, 0x02000, 0x1000 }, /* WFDMA PCIE0 MCU DMA0 */ 180 { 0x55000000, 0x03000, 0x1000 }, /* WFDMA PCIE0 MCU DMA1 */ 181 { 0x58000000, 0x06000, 0x1000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ 182 { 0x59000000, 0x07000, 0x1000 }, /* WFDMA PCIE1 MCU DMA1 */ 183 { 0x7c000000, 0xf0000, 0x10000 }, /* CONN_INFRA */ 184 { 0x7c020000, 0xd0000, 0x10000 }, /* CONN_INFRA, WFDMA */ 185 { 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */ 186 { 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */ 187 { 0x820c0000, 0x08000, 0x4000 }, /* WF_UMAC_TOP (PLE) */ 188 { 0x820c8000, 0x0c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */ 189 { 0x820cc000, 0x0e000, 0x2000 }, /* WF_UMAC_TOP (PP) */ 190 { 0x820ce000, 0x21c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */ 191 { 0x820cf000, 0x22000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */ 192 { 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */ 193 { 0x820e0000, 0x20000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */ 194 { 0x820e1000, 0x20400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */ 195 { 0x820e2000, 0x20800, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */ 196 { 0x820e3000, 0x20c00, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */ 197 { 0x820e4000, 0x21000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */ 198 { 0x820e5000, 0x21400, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */ 199 { 0x820e7000, 0x21e00, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */ 200 { 0x820e9000, 0x23400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ 201 { 0x820ea000, 0x24000, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */ 202 { 0x820eb000, 0x24200, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */ 203 { 0x820ec000, 0x24600, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_INT) */ 204 { 0x820ed000, 0x24800, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */ 205 { 0x820f0000, 0xa0000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */ 206 { 0x820f1000, 0xa0600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */ 207 { 0x820f2000, 0xa0800, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */ 208 { 0x820f3000, 0xa0c00, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */ 209 { 0x820f4000, 0xa1000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */ 210 { 0x820f5000, 0xa1400, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */ 211 { 0x820f7000, 0xa1e00, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */ 212 { 0x820f9000, 0xa3400, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ 213 { 0x820fa000, 0xa4000, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */ 214 { 0x820fb000, 0xa4200, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */ 215 { 0x820fc000, 0xa4600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_INT) */ 216 { 0x820fd000, 0xa4800, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */ 217 { 0x0, 0x0, 0x0 }, /* imply end of search */ 218 }; 219 220 static const struct __map mt7916_reg_map[] = { 221 { 0x54000000, 0x02000, 0x1000 }, /* WFDMA_0 (PCIE0 MCU DMA0) */ 222 { 0x55000000, 0x03000, 0x1000 }, /* WFDMA_1 (PCIE0 MCU DMA1) */ 223 { 0x56000000, 0x04000, 0x1000 }, /* WFDMA_2 (Reserved) */ 224 { 0x57000000, 0x05000, 0x1000 }, /* WFDMA_3 (MCU wrap CR) */ 225 { 0x58000000, 0x06000, 0x1000 }, /* WFDMA_4 (PCIE1 MCU DMA0) */ 226 { 0x59000000, 0x07000, 0x1000 }, /* WFDMA_5 (PCIE1 MCU DMA1) */ 227 { 0x820c0000, 0x08000, 0x4000 }, /* WF_UMAC_TOP (PLE) */ 228 { 0x820c8000, 0x0c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */ 229 { 0x820cc000, 0x0e000, 0x2000 }, /* WF_UMAC_TOP (PP) */ 230 { 0x820e0000, 0x20000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */ 231 { 0x820e1000, 0x20400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */ 232 { 0x820e2000, 0x20800, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */ 233 { 0x820e3000, 0x20c00, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */ 234 { 0x820e4000, 0x21000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */ 235 { 0x820e5000, 0x21400, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */ 236 { 0x820ce000, 0x21c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */ 237 { 0x820e7000, 0x21e00, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */ 238 { 0x820cf000, 0x22000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */ 239 { 0x820e9000, 0x23400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ 240 { 0x820ea000, 0x24000, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */ 241 { 0x820eb000, 0x24200, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */ 242 { 0x820ec000, 0x24600, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_INT) */ 243 { 0x820ed000, 0x24800, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */ 244 { 0x820ca000, 0x26000, 0x2000 }, /* WF_LMAC_TOP BN0 (WF_MUCOP) */ 245 { 0x820d0000, 0x30000, 0x10000}, /* WF_LMAC_TOP (WF_WTBLON) */ 246 { 0x00400000, 0x80000, 0x10000}, /* WF_MCU_SYSRAM */ 247 { 0x00410000, 0x90000, 0x10000}, /* WF_MCU_SYSRAM (configure cr) */ 248 { 0x820f0000, 0xa0000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */ 249 { 0x820f1000, 0xa0600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */ 250 { 0x820f2000, 0xa0800, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */ 251 { 0x820f3000, 0xa0c00, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */ 252 { 0x820f4000, 0xa1000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */ 253 { 0x820f5000, 0xa1400, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */ 254 { 0x820f7000, 0xa1e00, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */ 255 { 0x820f9000, 0xa3400, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ 256 { 0x820fa000, 0xa4000, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */ 257 { 0x820fb000, 0xa4200, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */ 258 { 0x820fc000, 0xa4600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_INT) */ 259 { 0x820fd000, 0xa4800, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */ 260 { 0x820c4000, 0xa8000, 0x1000 }, /* WF_LMAC_TOP (WF_UWTBL ) */ 261 { 0x820b0000, 0xae000, 0x1000 }, /* [APB2] WFSYS_ON */ 262 { 0x80020000, 0xb0000, 0x10000}, /* WF_TOP_MISC_OFF */ 263 { 0x81020000, 0xc0000, 0x10000}, /* WF_TOP_MISC_ON */ 264 { 0x0, 0x0, 0x0 }, /* imply end of search */ 265 }; 266 267 static u32 mt7915_reg_map_l1(struct mt7915_dev *dev, u32 addr) 268 { 269 u32 offset = FIELD_GET(MT_HIF_REMAP_L1_OFFSET, addr); 270 u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr); 271 u32 l1_remap = is_mt7915(&dev->mt76) ? 272 MT_HIF_REMAP_L1 : MT_HIF_REMAP_L1_MT7916; 273 274 dev->bus_ops->rmw(&dev->mt76, l1_remap, 275 MT_HIF_REMAP_L1_MASK, 276 FIELD_PREP(MT_HIF_REMAP_L1_MASK, base)); 277 /* use read to push write */ 278 dev->bus_ops->rr(&dev->mt76, l1_remap); 279 280 return MT_HIF_REMAP_BASE_L1 + offset; 281 } 282 283 static u32 mt7915_reg_map_l2(struct mt7915_dev *dev, u32 addr) 284 { 285 u32 offset, base; 286 287 if (is_mt7915(&dev->mt76)) { 288 offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET, addr); 289 base = FIELD_GET(MT_HIF_REMAP_L2_BASE, addr); 290 291 dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L2, 292 MT_HIF_REMAP_L2_MASK, 293 FIELD_PREP(MT_HIF_REMAP_L2_MASK, base)); 294 295 /* use read to push write */ 296 dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2); 297 } else { 298 offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET_MT7916, addr); 299 base = FIELD_GET(MT_HIF_REMAP_L2_BASE_MT7916, addr); 300 301 dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L2_MT7916, 302 MT_HIF_REMAP_L2_MASK_MT7916, 303 FIELD_PREP(MT_HIF_REMAP_L2_MASK_MT7916, base)); 304 305 /* use read to push write */ 306 dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2_MT7916); 307 308 offset += MT_HIF_REMAP_BASE_L2_MT7916; 309 } 310 311 return offset; 312 } 313 314 static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr) 315 { 316 int i; 317 318 if (addr < 0x100000) 319 return addr; 320 321 if (!dev->reg.map) { 322 dev_err(dev->mt76.dev, "err: reg_map is null\n"); 323 return addr; 324 } 325 326 for (i = 0; i < dev->reg.map_size; i++) { 327 u32 ofs; 328 329 if (addr < dev->reg.map[i].phys) 330 continue; 331 332 ofs = addr - dev->reg.map[i].phys; 333 if (ofs > dev->reg.map[i].size) 334 continue; 335 336 return dev->reg.map[i].maps + ofs; 337 } 338 339 if ((addr >= MT_INFRA_BASE && addr < MT_WFSYS0_PHY_START) || 340 (addr >= MT_WFSYS0_PHY_START && addr < MT_WFSYS1_PHY_START) || 341 (addr >= MT_WFSYS1_PHY_START && addr <= MT_WFSYS1_PHY_END) || 342 (addr >= MT_CBTOP1_PHY_START && addr <= MT_CBTOP1_PHY_END) || 343 (addr >= MT_CBTOP2_PHY_START && addr <= MT_CBTOP2_PHY_END)) 344 return mt7915_reg_map_l1(dev, addr); 345 346 return mt7915_reg_map_l2(dev, addr); 347 } 348 349 static u32 mt7915_rr(struct mt76_dev *mdev, u32 offset) 350 { 351 struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); 352 u32 addr = __mt7915_reg_addr(dev, offset); 353 354 return dev->bus_ops->rr(mdev, addr); 355 } 356 357 static void mt7915_wr(struct mt76_dev *mdev, u32 offset, u32 val) 358 { 359 struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); 360 u32 addr = __mt7915_reg_addr(dev, offset); 361 362 dev->bus_ops->wr(mdev, addr, val); 363 } 364 365 static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val) 366 { 367 struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); 368 u32 addr = __mt7915_reg_addr(dev, offset); 369 370 return dev->bus_ops->rmw(mdev, addr, mask, val); 371 } 372 373 static int mt7915_mmio_init(struct mt76_dev *mdev, 374 void __iomem *mem_base, 375 u32 device_id) 376 { 377 struct mt76_bus_ops *bus_ops; 378 struct mt7915_dev *dev; 379 380 dev = container_of(mdev, struct mt7915_dev, mt76); 381 mt76_mmio_init(&dev->mt76, mem_base); 382 383 switch (device_id) { 384 case 0x7915: 385 dev->reg.reg_rev = mt7915_reg; 386 dev->reg.offs_rev = mt7915_offs; 387 dev->reg.map = mt7915_reg_map; 388 dev->reg.map_size = ARRAY_SIZE(mt7915_reg_map); 389 break; 390 case 0x7906: 391 dev->reg.reg_rev = mt7916_reg; 392 dev->reg.offs_rev = mt7916_offs; 393 dev->reg.map = mt7916_reg_map; 394 dev->reg.map_size = ARRAY_SIZE(mt7916_reg_map); 395 break; 396 default: 397 return -EINVAL; 398 } 399 400 dev->bus_ops = dev->mt76.bus; 401 bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops), 402 GFP_KERNEL); 403 if (!bus_ops) 404 return -ENOMEM; 405 406 bus_ops->rr = mt7915_rr; 407 bus_ops->wr = mt7915_wr; 408 bus_ops->rmw = mt7915_rmw; 409 dev->mt76.bus = bus_ops; 410 411 mdev->rev = (device_id << 16) | 412 (mt76_rr(dev, MT_HW_REV) & 0xff); 413 dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev); 414 415 return 0; 416 } 417 418 void mt7915_dual_hif_set_irq_mask(struct mt7915_dev *dev, 419 bool write_reg, 420 u32 clear, u32 set) 421 { 422 struct mt76_dev *mdev = &dev->mt76; 423 unsigned long flags; 424 425 spin_lock_irqsave(&mdev->mmio.irq_lock, flags); 426 427 mdev->mmio.irqmask &= ~clear; 428 mdev->mmio.irqmask |= set; 429 430 if (write_reg) { 431 mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask); 432 mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask); 433 } 434 435 spin_unlock_irqrestore(&mdev->mmio.irq_lock, flags); 436 } 437 438 static void mt7915_rx_poll_complete(struct mt76_dev *mdev, 439 enum mt76_rxq_id q) 440 { 441 struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); 442 443 mt7915_irq_enable(dev, MT_INT_RX(q)); 444 } 445 446 /* TODO: support 2/4/6/8 MSI-X vectors */ 447 static void mt7915_irq_tasklet(struct tasklet_struct *t) 448 { 449 struct mt7915_dev *dev = from_tasklet(dev, t, irq_tasklet); 450 u32 intr, intr1, mask; 451 452 mt76_wr(dev, MT_INT_MASK_CSR, 0); 453 if (dev->hif2) 454 mt76_wr(dev, MT_INT1_MASK_CSR, 0); 455 456 intr = mt76_rr(dev, MT_INT_SOURCE_CSR); 457 intr &= dev->mt76.mmio.irqmask; 458 mt76_wr(dev, MT_INT_SOURCE_CSR, intr); 459 460 if (dev->hif2) { 461 intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR); 462 intr1 &= dev->mt76.mmio.irqmask; 463 mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1); 464 465 intr |= intr1; 466 } 467 468 trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask); 469 470 mask = intr & MT_INT_RX_DONE_ALL; 471 if (intr & MT_INT_TX_DONE_MCU) 472 mask |= MT_INT_TX_DONE_MCU; 473 474 mt7915_irq_disable(dev, mask); 475 476 if (intr & MT_INT_TX_DONE_MCU) 477 napi_schedule(&dev->mt76.tx_napi); 478 479 if (intr & MT_INT_RX(MT_RXQ_MAIN)) 480 napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN]); 481 482 if (intr & MT_INT_RX(MT_RXQ_EXT)) 483 napi_schedule(&dev->mt76.napi[MT_RXQ_EXT]); 484 485 if (intr & MT_INT_RX(MT_RXQ_MCU)) 486 napi_schedule(&dev->mt76.napi[MT_RXQ_MCU]); 487 488 if (intr & MT_INT_RX(MT_RXQ_MCU_WA)) 489 napi_schedule(&dev->mt76.napi[MT_RXQ_MCU_WA]); 490 491 if (!is_mt7915(&dev->mt76) && 492 (intr & MT_INT_RX(MT_RXQ_MAIN_WA))) 493 napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN_WA]); 494 495 if (intr & MT_INT_RX(MT_RXQ_EXT_WA)) 496 napi_schedule(&dev->mt76.napi[MT_RXQ_EXT_WA]); 497 498 if (intr & MT_INT_MCU_CMD) { 499 u32 val = mt76_rr(dev, MT_MCU_CMD); 500 501 mt76_wr(dev, MT_MCU_CMD, val); 502 if (val & MT_MCU_CMD_ERROR_MASK) { 503 dev->reset_state = val; 504 ieee80211_queue_work(mt76_hw(dev), &dev->reset_work); 505 wake_up(&dev->reset_wait); 506 } 507 } 508 } 509 510 irqreturn_t mt7915_irq_handler(int irq, void *dev_instance) 511 { 512 struct mt7915_dev *dev = dev_instance; 513 514 mt76_wr(dev, MT_INT_MASK_CSR, 0); 515 if (dev->hif2) 516 mt76_wr(dev, MT_INT1_MASK_CSR, 0); 517 518 if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state)) 519 return IRQ_NONE; 520 521 tasklet_schedule(&dev->irq_tasklet); 522 523 return IRQ_HANDLED; 524 } 525 526 struct mt7915_dev *mt7915_mmio_probe(struct device *pdev, 527 void __iomem *mem_base, u32 device_id) 528 { 529 static const struct mt76_driver_ops drv_ops = { 530 /* txwi_size = txd size + txp size */ 531 .txwi_size = MT_TXD_SIZE + sizeof(struct mt7915_txp), 532 .drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ, 533 .survey_flags = SURVEY_INFO_TIME_TX | 534 SURVEY_INFO_TIME_RX | 535 SURVEY_INFO_TIME_BSS_RX, 536 .token_size = MT7915_TOKEN_SIZE, 537 .tx_prepare_skb = mt7915_tx_prepare_skb, 538 .tx_complete_skb = mt7915_tx_complete_skb, 539 .rx_skb = mt7915_queue_rx_skb, 540 .rx_check = mt7915_rx_check, 541 .rx_poll_complete = mt7915_rx_poll_complete, 542 .sta_ps = mt7915_sta_ps, 543 .sta_add = mt7915_mac_sta_add, 544 .sta_remove = mt7915_mac_sta_remove, 545 .update_survey = mt7915_update_channel, 546 }; 547 struct ieee80211_ops *ops; 548 struct mt7915_dev *dev; 549 struct mt76_dev *mdev; 550 int ret; 551 552 ops = devm_kmemdup(pdev, &mt7915_ops, sizeof(mt7915_ops), GFP_KERNEL); 553 if (!ops) 554 return ERR_PTR(-ENOMEM); 555 556 mdev = mt76_alloc_device(pdev, sizeof(*dev), ops, &drv_ops); 557 if (!mdev) 558 return ERR_PTR(-ENOMEM); 559 560 dev = container_of(mdev, struct mt7915_dev, mt76); 561 562 ret = mt7915_mmio_init(mdev, mem_base, device_id); 563 if (ret) 564 goto error; 565 566 tasklet_setup(&dev->irq_tasklet, mt7915_irq_tasklet); 567 568 mt76_wr(dev, MT_INT_MASK_CSR, 0); 569 570 return dev; 571 572 error: 573 mt76_free_device(&dev->mt76); 574 575 return ERR_PTR(ret); 576 } 577 578 static int __init mt7915_init(void) 579 { 580 int ret; 581 582 ret = pci_register_driver(&mt7915_hif_driver); 583 if (ret) 584 return ret; 585 586 ret = pci_register_driver(&mt7915_pci_driver); 587 if (ret) 588 pci_unregister_driver(&mt7915_hif_driver); 589 590 return ret; 591 } 592 593 static void __exit mt7915_exit(void) 594 { 595 pci_unregister_driver(&mt7915_pci_driver); 596 pci_unregister_driver(&mt7915_hif_driver); 597 } 598 599 module_init(mt7915_init); 600 module_exit(mt7915_exit); 601 MODULE_LICENSE("Dual BSD/GPL"); 602