Пример #1
0
static void b1dma_handle_interrupt(avmcard *card)
{
	u32 status;
	u32 newcsr;

	spin_lock(&card->lock);

	status = b1dma_readl(card, AMCC_INTCSR);
	if ((status & ANY_S5933_INT) == 0) {
		spin_unlock(&card->lock);
		return;
	}

	newcsr = card->csr | (status & ALL_INT);
	if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT;
	if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT;
	b1dma_writel(card, newcsr, AMCC_INTCSR);

	if ((status & RX_TC_INT) != 0) {
		struct avmcard_dmainfo *dma = card->dma;
		u32 rxlen;
		if (card->dma->recvlen == 0) {
			rxlen = b1dma_readl(card, AMCC_RXLEN);
			if (rxlen == 0) {
				dma->recvlen = *((u32 *)dma->recvbuf.dmabuf);
				rxlen = (dma->recvlen + 3) & ~3;
				b1dma_writel(card, dma->recvbuf.dmaaddr + 4, AMCC_RXPTR);
				b1dma_writel(card, rxlen, AMCC_RXLEN);
#ifdef AVM_B1DMA_DEBUG
			} else {
				printk(KERN_ERR "%s: rx not complete (%d).\n",
				       card->name, rxlen);
#endif
			}
		} else {
			spin_unlock(&card->lock);
			b1dma_handle_rx(card);
			dma->recvlen = 0;
			spin_lock(&card->lock);
			b1dma_writel(card, dma->recvbuf.dmaaddr, AMCC_RXPTR);
			b1dma_writel(card, 4, AMCC_RXLEN);
		}
	}

	if ((status & TX_TC_INT) != 0) {
		if (skb_queue_empty(&card->dma->send_queue))
			card->csr &= ~EN_TX_TC_INT;
		else
			b1dma_dispatch_tx(card);
	}
	b1dma_writel(card, card->csr, AMCC_INTCSR);

	spin_unlock(&card->lock);
}
Пример #2
0
static void b1dma_handle_interrupt(avmcard *card)
{
	__u32 status = b1dmainmeml(card->mbase+AMCC_INTCSR);
	__u32 newcsr;

	if ((status & ANY_S5933_INT) == 0) 
		return;

        newcsr = card->csr | (status & ALL_INT);
	if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT;
	if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT;
	b1dmaoutmeml(card->mbase+AMCC_INTCSR, newcsr);

	if ((status & RX_TC_INT) != 0) {
		__u8 *recvbuf = card->dma->recvbuf;
		__u32 rxlen;
	   	if (card->dma->recvlen == 0) {
			card->dma->recvlen = *((__u32 *)recvbuf);
			rxlen = (card->dma->recvlen + 3) & ~3;
			b1dmaoutmeml(card->mbase+AMCC_RXPTR,
					virt_to_phys(recvbuf+4));
			b1dmaoutmeml(card->mbase+AMCC_RXLEN, rxlen);
		} else {
			b1dma_handle_rx(card);
	   		card->dma->recvlen = 0;
			b1dmaoutmeml(card->mbase+AMCC_RXPTR, virt_to_phys(recvbuf));
			b1dmaoutmeml(card->mbase+AMCC_RXLEN, 4);
		}
	}

	if ((status & TX_TC_INT) != 0) {
		card->csr &= ~EN_TX_TC_INT;
	        b1dma_dispatch_tx(card);
	}
	b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
}