Пример #1
0
static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
{
	struct net_device *dev = dev_id;
	u32 int_flags;
	irqreturn_t ret = IRQ_NONE;

	if (irq != dev->irq)
		goto out_badirq;

	/* TESTBIT is cleared on read. */
	int_flags = inl(regaddr(dev, interruptControl));
	if (int_flags & MIPSNET_INTCTL_TESTBIT) {
		/* TESTBIT takes effect after a write with 0. */
		outl(0, regaddr(dev, interruptControl));
		ret = IRQ_HANDLED;
	} else if (int_flags & MIPSNET_INTCTL_TXDONE) {
		/* Only one packet at a time, we are done. */
		dev->stats.tx_packets++;
		netif_wake_queue(dev);
		outl(MIPSNET_INTCTL_TXDONE,
		     regaddr(dev, interruptControl));
		ret = IRQ_HANDLED;
	} else if (int_flags & MIPSNET_INTCTL_RXDONE) {
		mipsnet_get_fromdev(dev, inl(regaddr(dev, rxDataCount)));
		outl(MIPSNET_INTCTL_RXDONE, regaddr(dev, interruptControl));
		ret = IRQ_HANDLED;
	}
	return ret;

out_badirq:
	printk(KERN_INFO "%s: %s(): irq %d for unknown device\n",
	       dev->name, __func__, irq);
	return ret;
}
Пример #2
0
static irqreturn_t
mipsnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	struct net_device *dev = dev_id;

	irqreturn_t retval = IRQ_NONE;
	uint64_t interruptFlags;

	if (irq == dev->irq) {
		pr_debug("%s:%s(): irq %d for device\n",
		         dev->name, __FUNCTION__, irq);

		retval = IRQ_HANDLED;

		interruptFlags =
		    inl(mipsnet_reg_address(dev, interruptControl));
		pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name,
		         __FUNCTION__, interruptFlags);

		if (interruptFlags & MIPSNET_INTCTL_TXDONE) {
			pr_debug("%s:%s(): got TXDone\n",
			         dev->name, __FUNCTION__);
			outl(MIPSNET_INTCTL_TXDONE,
			     mipsnet_reg_address(dev, interruptControl));
			// only one packet at a time, we are done.
			netif_wake_queue(dev);
		} else if (interruptFlags & MIPSNET_INTCTL_RXDONE) {
			pr_debug("%s:%s(): got RX data\n",
			         dev->name, __FUNCTION__);
			mipsnet_get_fromdev(dev,
			            inl(mipsnet_reg_address(dev, rxDataCount)));
			pr_debug("%s:%s(): clearing RX int\n",
			         dev->name, __FUNCTION__);
			outl(MIPSNET_INTCTL_RXDONE,
			     mipsnet_reg_address(dev, interruptControl));

		} else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) {
			pr_debug("%s:%s(): got test interrupt\n",
			         dev->name, __FUNCTION__);
			// TESTBIT is cleared on read.
			//    And takes effect after a write with 0
			outl(0, mipsnet_reg_address(dev, interruptControl));
		} else {
			pr_debug("%s:%s(): no valid fags 0x%016llx\n",
			         dev->name, __FUNCTION__, interruptFlags);
			// Maybe shared IRQ, just ignore, no clearing.
			retval = IRQ_NONE;
		}

	} else {
		printk(KERN_INFO "%s: %s(): irq %d for unknown device\n",
		       dev->name, __FUNCTION__, irq);
		retval = IRQ_NONE;
	}
	return retval;
}				//mipsnet_interrupt()