static int bfin_EMAC_recv(struct eth_device *dev) { int length = 0; for (;;) { if ((rxbuf[rxIdx]->StatusWord & RX_COMP) == 0) { length = -1; break; } if ((rxbuf[rxIdx]->StatusWord & RX_DMAO) != 0) { printf("Ethernet: rx dma overrun\n"); break; } if ((rxbuf[rxIdx]->StatusWord & RX_OK) == 0) { printf("Ethernet: rx error\n"); break; } length = rxbuf[rxIdx]->StatusWord & 0x000007FF; if (length <= 4) { printf("Ethernet: bad frame\n"); break; } debug("%s: len = %d\n", __func__, length - 4); NetRxPackets[rxIdx] = (volatile uchar *)(rxbuf[rxIdx]->FrmData->Dest); NetReceive(NetRxPackets[rxIdx], length - 4); bfin_write_DMA1_IRQ_STATUS(DMA_DONE | DMA_ERR); rxbuf[rxIdx]->StatusWord = 0x00000000; if ((rxIdx + 1) >= PKTBUFSRX) rxIdx = 0; else rxIdx++; } return length; }
/* interrupt routine to handle rx and error signal */ static irqreturn_t bfin_mac_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; int number = 0; get_one_packet: if (current_rx_ptr->status.status_word == 0) { /* no more new packet received */ if (number == 0) { if (current_rx_ptr->next->status.status_word != 0) { current_rx_ptr = current_rx_ptr->next; goto real_rx; } } bfin_write_DMA1_IRQ_STATUS(bfin_read_DMA1_IRQ_STATUS() | DMA_DONE | DMA_ERR); return IRQ_HANDLED; } real_rx: bfin_mac_rx(dev); number++; goto get_one_packet; }