static irqreturn_t sport_rx_isr(int irq, void *dev_id) { unsigned int i, j; struct nortel *c = (struct nortel *)dev_id; /* * iRxBuffer points to what was just received. * iTxBuffer points to what was just transmitted. * Copy the data received into the channel structure, * update these pointers, and copy the data to transmit. */ copy_nortel_to_internal(c, iRxBuffer); iRxBuffer += TDM_CHANNELS; j = bfin_read_DMA3_START_ADDR(); if((unsigned int)iRxBuffer >= j + DMA_BUFLEN) iRxBuffer = (u8 *)j; iTxBuffer += TDM_CHANNELS; j = bfin_read_DMA4_START_ADDR(); if((unsigned int)iTxBuffer >= j + DMA_BUFLEN) iTxBuffer = (u8 *)j; copy_internal_to_nortel(c, iTxBuffer); /* * The next transfer is now set up and waiting. * Acknowledge the transfer and let the next one go. */ i = bfin_read_DMA3_IRQ_STATUS(); j = DMA_DONE; if(i & DMA_ERR) { if(debug) printk(KERN_DEBUG "sport_rx_isr: DMA5 reported an error\n"); j |= DMA_ERR; } bfin_write_DMA3_IRQ_STATUS(j); /* ACK DMA (and error if present) */ __builtin_bfin_ssync(); /* * We must begin to process the received frame. Right now, * we do this within the IRQ handler since it's fast, * but this is the routine that you may want to kick off to a * bottom-half handler (tasklet or workqueue). * * Once the frame is processed, we must do the ethernet side. * If we are providing sync to the PC, we kick off a TDMoE packet * every 8 (ZT_CHUNKSIZE) frames. * If we are not providing sync to the PC, we don't worry about * ethernet at all, as it will be taking care of by the * ethernet receive code. */ process_frame(c); ++c->intcount; if(tdmoe_master && (c->intcount % 8 == 0)) { copy_internal_to_tdmoe(c); /* also queues packet for tx */ tasklet_hi_schedule(ð_flush_tasklet); /* actually put the frames on the wire */ } return IRQ_HANDLED; }