xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/mediatek/mt76/mt7915/pci.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: ISC
2*4882a593Smuzhiyun /* Copyright (C) 2020 MediaTek Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Author: Ryder Lee <ryder.lee@mediatek.com>
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <linux/kernel.h>
8*4882a593Smuzhiyun #include <linux/module.h>
9*4882a593Smuzhiyun #include <linux/pci.h>
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include "mt7915.h"
12*4882a593Smuzhiyun #include "mac.h"
13*4882a593Smuzhiyun #include "../trace.h"
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun static const struct pci_device_id mt7915_pci_device_table[] = {
16*4882a593Smuzhiyun 	{ PCI_DEVICE(0x14c3, 0x7915) },
17*4882a593Smuzhiyun 	{ },
18*4882a593Smuzhiyun };
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun static void
mt7915_rx_poll_complete(struct mt76_dev * mdev,enum mt76_rxq_id q)21*4882a593Smuzhiyun mt7915_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
22*4882a593Smuzhiyun {
23*4882a593Smuzhiyun 	struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun 	mt7915_irq_enable(dev, MT_INT_RX_DONE(q));
26*4882a593Smuzhiyun }
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun /* TODO: support 2/4/6/8 MSI-X vectors */
mt7915_irq_handler(int irq,void * dev_instance)29*4882a593Smuzhiyun static irqreturn_t mt7915_irq_handler(int irq, void *dev_instance)
30*4882a593Smuzhiyun {
31*4882a593Smuzhiyun 	struct mt7915_dev *dev = dev_instance;
32*4882a593Smuzhiyun 	u32 intr, mask;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
35*4882a593Smuzhiyun 	intr &= dev->mt76.mmio.irqmask;
36*4882a593Smuzhiyun 	mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 	if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
39*4882a593Smuzhiyun 		return IRQ_NONE;
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 	trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	mask = intr & MT_INT_RX_DONE_ALL;
44*4882a593Smuzhiyun 	if (intr & MT_INT_TX_DONE_MCU)
45*4882a593Smuzhiyun 		mask |= MT_INT_TX_DONE_MCU;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	mt7915_irq_disable(dev, mask);
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	if (intr & MT_INT_TX_DONE_MCU)
50*4882a593Smuzhiyun 		napi_schedule(&dev->mt76.tx_napi);
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 	if (intr & MT_INT_RX_DONE_DATA)
53*4882a593Smuzhiyun 		napi_schedule(&dev->mt76.napi[0]);
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	if (intr & MT_INT_RX_DONE_WM)
56*4882a593Smuzhiyun 		napi_schedule(&dev->mt76.napi[1]);
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	if (intr & MT_INT_RX_DONE_WA)
59*4882a593Smuzhiyun 		napi_schedule(&dev->mt76.napi[2]);
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	if (intr & MT_INT_MCU_CMD) {
62*4882a593Smuzhiyun 		u32 val = mt76_rr(dev, MT_MCU_CMD);
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 		mt76_wr(dev, MT_MCU_CMD, val);
65*4882a593Smuzhiyun 		if (val & MT_MCU_CMD_ERROR_MASK) {
66*4882a593Smuzhiyun 			dev->reset_state = val;
67*4882a593Smuzhiyun 			ieee80211_queue_work(mt76_hw(dev), &dev->reset_work);
68*4882a593Smuzhiyun 			wake_up(&dev->reset_wait);
69*4882a593Smuzhiyun 		}
70*4882a593Smuzhiyun 	}
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	return IRQ_HANDLED;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun static int
mt7915_alloc_device(struct pci_dev * pdev,struct mt7915_dev * dev)76*4882a593Smuzhiyun mt7915_alloc_device(struct pci_dev *pdev, struct mt7915_dev *dev)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun #define NUM_BANDS	2
79*4882a593Smuzhiyun 	int i;
80*4882a593Smuzhiyun 	s8 **sku;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	sku = devm_kzalloc(&pdev->dev, NUM_BANDS * sizeof(*sku), GFP_KERNEL);
83*4882a593Smuzhiyun 	if (!sku)
84*4882a593Smuzhiyun 		return -ENOMEM;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	for (i = 0; i < NUM_BANDS; i++) {
87*4882a593Smuzhiyun 		sku[i] = devm_kzalloc(&pdev->dev, MT7915_SKU_TABLE_SIZE *
88*4882a593Smuzhiyun 				      sizeof(**sku), GFP_KERNEL);
89*4882a593Smuzhiyun 		if (!sku[i])
90*4882a593Smuzhiyun 			return -ENOMEM;
91*4882a593Smuzhiyun 	}
92*4882a593Smuzhiyun 	dev->rate_power = sku;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	return 0;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun 
mt7915_pci_probe(struct pci_dev * pdev,const struct pci_device_id * id)97*4882a593Smuzhiyun static int mt7915_pci_probe(struct pci_dev *pdev,
98*4882a593Smuzhiyun 			    const struct pci_device_id *id)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun 	static const struct mt76_driver_ops drv_ops = {
101*4882a593Smuzhiyun 		/* txwi_size = txd size + txp size */
102*4882a593Smuzhiyun 		.txwi_size = MT_TXD_SIZE + sizeof(struct mt7915_txp),
103*4882a593Smuzhiyun 		.drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ |
104*4882a593Smuzhiyun 			     MT_DRV_AMSDU_OFFLOAD,
105*4882a593Smuzhiyun 		.survey_flags = SURVEY_INFO_TIME_TX |
106*4882a593Smuzhiyun 				SURVEY_INFO_TIME_RX |
107*4882a593Smuzhiyun 				SURVEY_INFO_TIME_BSS_RX,
108*4882a593Smuzhiyun 		.tx_prepare_skb = mt7915_tx_prepare_skb,
109*4882a593Smuzhiyun 		.tx_complete_skb = mt7915_tx_complete_skb,
110*4882a593Smuzhiyun 		.rx_skb = mt7915_queue_rx_skb,
111*4882a593Smuzhiyun 		.rx_poll_complete = mt7915_rx_poll_complete,
112*4882a593Smuzhiyun 		.sta_ps = mt7915_sta_ps,
113*4882a593Smuzhiyun 		.sta_add = mt7915_mac_sta_add,
114*4882a593Smuzhiyun 		.sta_remove = mt7915_mac_sta_remove,
115*4882a593Smuzhiyun 		.update_survey = mt7915_update_channel,
116*4882a593Smuzhiyun 	};
117*4882a593Smuzhiyun 	struct mt7915_dev *dev;
118*4882a593Smuzhiyun 	struct mt76_dev *mdev;
119*4882a593Smuzhiyun 	int ret;
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	ret = pcim_enable_device(pdev);
122*4882a593Smuzhiyun 	if (ret)
123*4882a593Smuzhiyun 		return ret;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
126*4882a593Smuzhiyun 	if (ret)
127*4882a593Smuzhiyun 		return ret;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	pci_set_master(pdev);
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
132*4882a593Smuzhiyun 	if (ret)
133*4882a593Smuzhiyun 		return ret;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt7915_ops,
136*4882a593Smuzhiyun 				 &drv_ops);
137*4882a593Smuzhiyun 	if (!mdev)
138*4882a593Smuzhiyun 		return -ENOMEM;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	dev = container_of(mdev, struct mt7915_dev, mt76);
141*4882a593Smuzhiyun 	ret = mt7915_alloc_device(pdev, dev);
142*4882a593Smuzhiyun 	if (ret)
143*4882a593Smuzhiyun 		goto error;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]);
146*4882a593Smuzhiyun 	mdev->rev = (mt7915_l1_rr(dev, MT_HW_CHIPID) << 16) |
147*4882a593Smuzhiyun 		    (mt7915_l1_rr(dev, MT_HW_REV) & 0xff);
148*4882a593Smuzhiyun 	dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	mt76_wr(dev, MT_INT_MASK_CSR, 0);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	/* master switch of PCIe tnterrupt enable */
153*4882a593Smuzhiyun 	mt7915_l1_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	ret = devm_request_irq(mdev->dev, pdev->irq, mt7915_irq_handler,
156*4882a593Smuzhiyun 			       IRQF_SHARED, KBUILD_MODNAME, dev);
157*4882a593Smuzhiyun 	if (ret)
158*4882a593Smuzhiyun 		goto error;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	ret = mt7915_register_device(dev);
161*4882a593Smuzhiyun 	if (ret)
162*4882a593Smuzhiyun 		goto error;
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	return 0;
165*4882a593Smuzhiyun error:
166*4882a593Smuzhiyun 	mt76_free_device(&dev->mt76);
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	return ret;
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun 
mt7915_pci_remove(struct pci_dev * pdev)171*4882a593Smuzhiyun static void mt7915_pci_remove(struct pci_dev *pdev)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun 	struct mt76_dev *mdev = pci_get_drvdata(pdev);
174*4882a593Smuzhiyun 	struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	mt7915_unregister_device(dev);
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun struct pci_driver mt7915_pci_driver = {
180*4882a593Smuzhiyun 	.name		= KBUILD_MODNAME,
181*4882a593Smuzhiyun 	.id_table	= mt7915_pci_device_table,
182*4882a593Smuzhiyun 	.probe		= mt7915_pci_probe,
183*4882a593Smuzhiyun 	.remove		= mt7915_pci_remove,
184*4882a593Smuzhiyun };
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun module_pci_driver(mt7915_pci_driver);
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, mt7915_pci_device_table);
189*4882a593Smuzhiyun MODULE_FIRMWARE(MT7915_FIRMWARE_WA);
190*4882a593Smuzhiyun MODULE_FIRMWARE(MT7915_FIRMWARE_WM);
191*4882a593Smuzhiyun MODULE_FIRMWARE(MT7915_ROM_PATCH);
192*4882a593Smuzhiyun MODULE_LICENSE("Dual BSD/GPL");
193