예제 #1
0
/* The RDC interrupt handler. */
static irqreturn_t r6040_interrupt(int irq, void *dev_id)
{
	struct net_device *dev = dev_id;
	struct r6040_private *lp = netdev_priv(dev);
	void __iomem *ioaddr = lp->base;
	u16 misr, status;

	/* Save MIER */
	misr = ioread16(ioaddr + MIER);
	/* Mask off RDC MAC interrupt */
	iowrite16(MSK_INT, ioaddr + MIER);
	/* Read MISR status and clear */
	status = ioread16(ioaddr + MISR);

	if (status == 0x0000 || status == 0xffff) {
		/* Restore RDC MAC interrupt */
		iowrite16(misr, ioaddr + MIER);
		return IRQ_NONE;
	}

	/* RX interrupt request */
	if (status & RX_INTS) {
		if (status & RX_NO_DESC) {
			/* RX descriptor unavailable */
			dev->stats.rx_dropped++;
			dev->stats.rx_missed_errors++;
		}
		if (status & RX_FIFO_FULL)
			dev->stats.rx_fifo_errors++;

		if (likely(napi_schedule_prep(&lp->napi))) {
			/* Mask off RX interrupt */
			misr &= ~RX_INTS;
			__napi_schedule(&lp->napi);
		}
	}

	/* TX interrupt request */
	if (status & TX_INTS)
		r6040_tx(dev);

	/* Restore RDC MAC interrupt */
	iowrite16(misr, ioaddr + MIER);

	return IRQ_HANDLED;
}
예제 #2
0
파일: r6040.c 프로젝트: acton393/linux
static int r6040_poll(struct napi_struct *napi, int budget)
{
	struct r6040_private *priv =
		container_of(napi, struct r6040_private, napi);
	struct net_device *dev = priv->dev;
	void __iomem *ioaddr = priv->base;
	int work_done;

	r6040_tx(dev);

	work_done = r6040_rx(dev, budget);

	if (work_done < budget) {
		napi_complete_done(napi, work_done);
		/* Enable RX/TX interrupt */
		iowrite16(ioread16(ioaddr + MIER) | RX_INTS | TX_INTS,
			  ioaddr + MIER);
	}
	return work_done;
}