diff --git a/Makefile b/Makefile index eeb3c33d..71d208be 100644 --- a/Makefile +++ b/Makefile @@ -14,4 +14,5 @@ mt76x2e-y := \ mt76x2e-$(CONFIG_OF) += mt76x2_of.o mt7603e-y := \ - mt7603_pci.o mt7603_main.o mt7603_init.o mt7603_mcu.o + mt7603_pci.o mt7603_main.o mt7603_init.o mt7603_mcu.o \ + mt7603_core.o diff --git a/mt7603.h b/mt7603.h index c2f41bcb..56a2f768 100644 --- a/mt7603.h +++ b/mt7603.h @@ -23,12 +23,27 @@ struct mt7603_dev { struct mt76_dev mt76; - u32 rev; + + u32 irqmask; + spinlock_t irq_lock; }; extern const struct ieee80211_ops mt7603_ops; struct mt7603_dev *mt7603_alloc_device(struct device *pdev); +irqreturn_t mt7603_irq_handler(int irq, void *dev_instance); int mt7603_mcu_init(struct mt7603_dev *dev); +void mt7603_set_irq_mask(struct mt7603_dev *dev, u32 clear, u32 set); + +static inline void mt7603_irq_enable(struct mt7603_dev *dev, u32 mask) +{ + mt7603_set_irq_mask(dev, 0, mask); +} + +static inline void mt7603_irq_disable(struct mt7603_dev *dev, u32 mask) +{ + mt7603_set_irq_mask(dev, mask, 0); +} + #endif diff --git a/mt7603_core.c b/mt7603_core.c new file mode 100644 index 00000000..c6b0fbd1 --- /dev/null +++ b/mt7603_core.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 Felix Fietkau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "mt7603.h" + +void mt7603_set_irq_mask(struct mt7603_dev *dev, u32 clear, u32 set) +{ + unsigned long flags; + + spin_lock_irqsave(&dev->irq_lock, flags); + dev->irqmask &= ~clear; + dev->irqmask |= set; + mt76_wr(dev, MT_INT_MASK_CSR, dev->irqmask); + spin_unlock_irqrestore(&dev->irq_lock, flags); +} + +irqreturn_t mt7603_irq_handler(int irq, void *dev_instance) +{ + struct mt7603_dev *dev = dev_instance; + u32 intr; + + intr = mt76_rr(dev, MT_INT_SOURCE_CSR); + mt76_wr(dev, MT_INT_SOURCE_CSR, intr); + + if (!test_bit(MT76_STATE_INITIALIZED, &dev->mt76.state)) + return IRQ_NONE; + + intr &= dev->irqmask; + printk("got irq: %08x\n", intr); + +#if 0 + if (intr & MT_INT_TX_DONE_ALL) { + mt7603_irq_disable(dev, MT_INT_TX_DONE_ALL); + tasklet_schedule(&dev->tx_tasklet); + } + + if (intr & MT_INT_RX_DONE(0)) { + mt7603_irq_disable(dev, MT_INT_RX_DONE(0)); + napi_schedule(&dev->napi); + } + + if (intr & MT_INT_RX_DONE(1)) { + mt7603_irq_disable(dev, MT_INT_RX_DONE(1)); + tasklet_schedule(&dev->rx_tasklet); + } + + if (intr & MT_INT_PRE_TBTT) + tasklet_schedule(&dev->pre_tbtt_tasklet); + + /* send buffered multicast frames now */ + if (intr & MT_INT_TBTT) + mt76_queue_kick(dev, &dev->q_tx[MT_TXQ_PSD]); + + if (intr & MT_INT_TX_STAT) { + mt7603_mac_poll_tx_status(dev, true); + tasklet_schedule(&dev->tx_tasklet); + } +#endif + + return IRQ_HANDLED; +} diff --git a/mt7603_pci.c b/mt7603_pci.c index 92d86dd1..bc8601c9 100644 --- a/mt7603_pci.c +++ b/mt7603_pci.c @@ -53,11 +53,24 @@ mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev->rev = mt76_rr(dev, MT_ASIC_VERSION); dev_printk(KERN_INFO, dev->mt76.dev, "ASIC revision: %08x\n", dev->rev); + ret = devm_request_irq(dev->mt76.dev, pdev->irq, mt7603_irq_handler, + IRQF_SHARED, KBUILD_MODNAME, dev); + if (ret) + goto error; + ret = mt7603_mcu_init(dev); if (ret) - return ret; + goto error; - return -EINVAL; + if (1) { + ret = -EINVAL; + goto error; + } + + return 0; +error: + ieee80211_free_hw(mt76_hw(dev)); + return ret; } static void