mmio.c 6.73 KB
Newer Older
1 2 3
// SPDX-License-Identifier: ISC
/* Copyright (C) 2020 MediaTek Inc. */

4 5
#include <linux/kernel.h>
#include <linux/module.h>
6 7
#include <linux/platform_device.h>
#include <linux/pci.h>
8 9

#include "mt7615.h"
10
#include "regs.h"
11 12 13
#include "mac.h"
#include "../trace.h"

14 15 16 17
const u32 mt7615e_reg_map[] = {
	[MT_TOP_CFG_BASE]	= 0x01000,
	[MT_HW_BASE]		= 0x01000,
	[MT_PCIE_REMAP_2]	= 0x02504,
18
	[MT_ARB_BASE]		= 0x20c00,
19 20
	[MT_HIF_BASE]		= 0x04000,
	[MT_CSR_BASE]		= 0x07000,
21 22
	[MT_PLE_BASE]		= 0x08000,
	[MT_PSE_BASE]		= 0x0c000,
23 24 25 26 27
	[MT_CFG_BASE]		= 0x20200,
	[MT_AGG_BASE]		= 0x20a00,
	[MT_TMAC_BASE]		= 0x21000,
	[MT_RMAC_BASE]		= 0x21200,
	[MT_DMA_BASE]		= 0x21800,
28
	[MT_PF_BASE]		= 0x22000,
29 30 31 32 33 34 35 36 37 38
	[MT_WTBL_BASE_ON]	= 0x23000,
	[MT_WTBL_BASE_OFF]	= 0x23400,
	[MT_LPON_BASE]		= 0x24200,
	[MT_MIB_BASE]		= 0x24800,
	[MT_WTBL_BASE_ADDR]	= 0x30000,
	[MT_PCIE_REMAP_BASE2]	= 0x80000,
	[MT_TOP_MISC_BASE]	= 0xc0000,
	[MT_EFUSE_ADDR_BASE]	= 0x81070000,
};

39 40 41 42 43 44 45 46
const u32 mt7663e_reg_map[] = {
	[MT_TOP_CFG_BASE]	= 0x01000,
	[MT_HW_BASE]		= 0x02000,
	[MT_DMA_SHDL_BASE]	= 0x06000,
	[MT_PCIE_REMAP_2]	= 0x0700c,
	[MT_ARB_BASE]		= 0x20c00,
	[MT_HIF_BASE]		= 0x04000,
	[MT_CSR_BASE]		= 0x07000,
47 48
	[MT_PLE_BASE]		= 0x08000,
	[MT_PSE_BASE]		= 0x0c000,
49
	[MT_PP_BASE]            = 0x0e000,
50 51 52 53 54
	[MT_CFG_BASE]		= 0x20000,
	[MT_AGG_BASE]		= 0x22000,
	[MT_TMAC_BASE]		= 0x24000,
	[MT_RMAC_BASE]		= 0x25000,
	[MT_DMA_BASE]		= 0x27000,
55
	[MT_PF_BASE]		= 0x28000,
56 57 58 59 60 61 62 63 64 65
	[MT_WTBL_BASE_ON]	= 0x29000,
	[MT_WTBL_BASE_OFF]	= 0x29800,
	[MT_LPON_BASE]		= 0x2b000,
	[MT_MIB_BASE]		= 0x2d000,
	[MT_WTBL_BASE_ADDR]	= 0x30000,
	[MT_PCIE_REMAP_BASE2]	= 0x90000,
	[MT_TOP_MISC_BASE]	= 0xc0000,
	[MT_EFUSE_ADDR_BASE]	= 0x78011000,
};

66 67
u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr)
{
68
	u32 base, offset;
69

70 71 72 73 74 75 76
	if (is_mt7663(&dev->mt76)) {
		base = addr & MT7663_MCU_PCIE_REMAP_2_BASE;
		offset = addr & MT7663_MCU_PCIE_REMAP_2_OFFSET;
	} else {
		base = addr & MT_MCU_PCIE_REMAP_2_BASE;
		offset = addr & MT_MCU_PCIE_REMAP_2_OFFSET;
	}
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
	mt76_wr(dev, MT_MCU_PCIE_REMAP_2, base);

	return MT_PCIE_REMAP_BASE_2 + offset;
}

static void
mt7615_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
{
	struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);

	mt7615_irq_enable(dev, MT_INT_RX_DONE(q));
}

static irqreturn_t mt7615_irq_handler(int irq, void *dev_instance)
{
	struct mt7615_dev *dev = dev_instance;

94
	mt76_wr(dev, MT_INT_MASK_CSR, 0);
95 96 97 98

	if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
		return IRQ_NONE;

99 100 101 102 103
	tasklet_schedule(&dev->irq_tasklet);

	return IRQ_HANDLED;
}

104
static void mt7615_irq_tasklet(struct tasklet_struct *t)
105
{
106
	struct mt7615_dev *dev = from_tasklet(dev, t, irq_tasklet);
107
	u32 intr, mask = 0, tx_mcu_mask = mt7615_tx_mcu_int_mask(dev);
108 109

	mt76_wr(dev, MT_INT_MASK_CSR, 0);
110

111
	intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
112
	intr &= dev->mt76.mmio.irqmask;
113 114 115
	mt76_wr(dev, MT_INT_SOURCE_CSR, intr);

	trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
116

117
	mask |= intr & MT_INT_RX_DONE_ALL;
118 119
	if (intr & tx_mcu_mask)
		mask |= tx_mcu_mask;
120 121
	mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);

122
	if (intr & tx_mcu_mask)
123 124
		napi_schedule(&dev->mt76.tx_napi);

125
	if (intr & MT_INT_RX_DONE(0))
126 127
		napi_schedule(&dev->mt76.napi[0]);

128
	if (intr & MT_INT_RX_DONE(1))
129 130
		napi_schedule(&dev->mt76.napi[1]);

131 132 133 134 135 136 137 138 139
	if (intr & MT_INT_MCU_CMD) {
		u32 val = mt76_rr(dev, MT_MCU_CMD);

		if (val & MT_MCU_CMD_ERROR_MASK) {
			dev->reset_state = val;
			ieee80211_queue_work(mt76_hw(dev), &dev->reset_work);
			wake_up(&dev->reset_wait);
		}
	}
140 141
}

142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
static u32 __mt7615_reg_addr(struct mt7615_dev *dev, u32 addr)
{
	if (addr < 0x100000)
		return addr;

	return mt7615_reg_map(dev, addr);
}

static u32 mt7615_rr(struct mt76_dev *mdev, u32 offset)
{
	struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
	u32 addr = __mt7615_reg_addr(dev, offset);

	return dev->bus_ops->rr(mdev, addr);
}

static void mt7615_wr(struct mt76_dev *mdev, u32 offset, u32 val)
{
	struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
	u32 addr = __mt7615_reg_addr(dev, offset);

	dev->bus_ops->wr(mdev, addr, val);
}

static u32 mt7615_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
{
	struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
	u32 addr = __mt7615_reg_addr(dev, offset);

	return dev->bus_ops->rmw(mdev, addr, mask, val);
}

174 175
int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
		      int irq, const u32 *map)
176 177 178
{
	static const struct mt76_driver_ops drv_ops = {
		/* txwi_size = txd size + txp size */
179
		.txwi_size = MT_TXD_SIZE + sizeof(struct mt7615_txp_common),
180
		.drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ,
181 182 183 184 185 186 187 188 189 190 191 192
		.survey_flags = SURVEY_INFO_TIME_TX |
				SURVEY_INFO_TIME_RX |
				SURVEY_INFO_TIME_BSS_RX,
		.tx_prepare_skb = mt7615_tx_prepare_skb,
		.tx_complete_skb = mt7615_tx_complete_skb,
		.rx_skb = mt7615_queue_rx_skb,
		.rx_poll_complete = mt7615_rx_poll_complete,
		.sta_ps = mt7615_sta_ps,
		.sta_add = mt7615_mac_sta_add,
		.sta_remove = mt7615_mac_sta_remove,
		.update_survey = mt7615_update_channel,
	};
193
	struct mt76_bus_ops *bus_ops;
194
	struct ieee80211_ops *ops;
195 196 197 198
	struct mt7615_dev *dev;
	struct mt76_dev *mdev;
	int ret;

199 200 201 202 203
	ops = devm_kmemdup(pdev, &mt7615_ops, sizeof(mt7615_ops), GFP_KERNEL);
	if (!ops)
		return -ENOMEM;

	mdev = mt76_alloc_device(pdev, sizeof(*dev), ops, &drv_ops);
204 205 206 207 208
	if (!mdev)
		return -ENOMEM;

	dev = container_of(mdev, struct mt7615_dev, mt76);
	mt76_mmio_init(&dev->mt76, mem_base);
209
	tasklet_setup(&dev->irq_tasklet, mt7615_irq_tasklet);
210

211
	dev->reg_map = map;
212
	dev->ops = ops;
213 214 215 216
	mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
		    (mt76_rr(dev, MT_HW_REV) & 0xff);
	dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);

217 218 219 220 221 222 223 224 225 226 227 228 229
	dev->bus_ops = dev->mt76.bus;
	bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops),
			       GFP_KERNEL);
	if (!bus_ops) {
		ret = -ENOMEM;
		goto error;
	}

	bus_ops->rr = mt7615_rr;
	bus_ops->wr = mt7615_wr;
	bus_ops->rmw = mt7615_rmw;
	dev->mt76.bus = bus_ops;

230 231
	mt76_wr(dev, MT_INT_MASK_CSR, 0);

232 233 234 235 236
	ret = devm_request_irq(mdev->dev, irq, mt7615_irq_handler,
			       IRQF_SHARED, KBUILD_MODNAME, dev);
	if (ret)
		goto error;

237 238 239
	if (is_mt7663(mdev))
		mt76_wr(dev, MT_PCIE_IRQ_ENABLE, 1);

240 241 242 243 244 245
	ret = mt7615_register_device(dev);
	if (ret)
		goto error;

	return 0;
error:
246 247
	mt76_free_device(&dev->mt76);

248 249
	return ret;
}
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277

static int __init mt7615_init(void)
{
	int ret;

	ret = pci_register_driver(&mt7615_pci_driver);
	if (ret)
		return ret;

	if (IS_ENABLED(CONFIG_MT7622_WMAC)) {
		ret = platform_driver_register(&mt7622_wmac_driver);
		if (ret)
			pci_unregister_driver(&mt7615_pci_driver);
	}

	return ret;
}

static void __exit mt7615_exit(void)
{
	if (IS_ENABLED(CONFIG_MT7622_WMAC))
		platform_driver_unregister(&mt7622_wmac_driver);
	pci_unregister_driver(&mt7615_pci_driver);
}

module_init(mt7615_init);
module_exit(mt7615_exit);
MODULE_LICENSE("Dual BSD/GPL");