static rtems_isr open_eth_interrupt_handler (rtems_vector_number v) { uint32_t status; /* read and clear interrupt cause */ status = oc.regs->int_src; oc.regs->int_src = status; /* Frame received? */ if (status & (OETH_INT_RXF | OETH_INT_RXE)) { oc.rxInterrupts++; rtems_bsdnet_event_send (oc.rxDaemonTid, INTERRUPT_EVENT); } #ifdef OETH_SUSPEND_NOTXBUF if (status & (OETH_INT_MASK_TXB | OETH_INT_MASK_TXC | OETH_INT_MASK_TXE)) { oc.txInterrupts++; rtems_bsdnet_event_send (oc.txDaemonTid, OPEN_ETH_TX_WAIT_EVENT); } #endif /* #ifdef __leon__ LEON_Clear_interrupt(v-0x10); #endif */ }
/* * SCC interrupt handler * TBD: Can we work out which SCC generated the interrupt from the * value of v? If so we can use the same handler for multiple * SCCs. */ static void m8xx_scc3_interrupt_handler (rtems_irq_hdl_param unused) { /* * Frame received? */ if ((m8260.scc3.sccm & M8260_SCCE_RXF) && (m8260.scc3.scce & M8260_SCCE_RXF) ) { m8260.scc3.scce = M8260_SCCE_RXF; /* m8260.scc3.sccm &= ~M8260_SCCE_RXF; */ hdlc_driver[0].rxInterrupts++; rtems_bsdnet_event_send (hdlc_driver[0].rxDaemonTid, INTERRUPT_EVENT); /* printk( "Rx " ); */ } /* * Buffer transmitted or transmitter error? */ if ((m8260.scc3.sccm & (M8260_SCCE_TX | M8260_SCCE_TXE) ) && (m8260.scc3.scce & (M8260_SCCE_TX | M8260_SCCE_TXE) )) { m8260.scc3.scce = M8260_SCCE_TX | M8260_SCCE_TXE; /* m8260.scc3.sccm &= ~(M8260_SCCE_TX | M8260_SCCE_TXE); */ hdlc_driver[0].txInterrupts++; rtems_bsdnet_event_send (hdlc_driver[0].txDaemonTid, INTERRUPT_EVENT); /* printk( "Tx " ); */ } #if 0 m8260.sipnr_l = M8260_SIMASK_SCC3; /* Clear SCC3 interrupt-in-service bit */ #endif }
void greth_interrupt_handler (void *arg) { uint32_t status; uint32_t ctrl; rtems_event_set events = 0; struct greth_softc *greth = arg; /* read and clear interrupt cause */ status = greth->regs->status; greth->regs->status = status; ctrl = greth->regs->ctrl; /* Frame received? */ if ((ctrl & GRETH_CTRL_RXIRQ) && (status & (GRETH_STATUS_RXERR | GRETH_STATUS_RXIRQ))) { greth->rxInterrupts++; /* Stop RX-Error and RX-Packet interrupts */ ctrl &= ~GRETH_CTRL_RXIRQ; events |= INTERRUPT_EVENT; } if ( (ctrl & GRETH_CTRL_TXIRQ) && (status & (GRETH_STATUS_TXERR | GRETH_STATUS_TXIRQ)) ) { greth->txInterrupts++; ctrl &= ~GRETH_CTRL_TXIRQ; events |= GRETH_TX_WAIT_EVENT; } /* Clear interrupt sources */ greth->regs->ctrl = ctrl; /* Send the event(s) */ if ( events ) rtems_bsdnet_event_send (greth->daemonTid, events); }
static rtems_isr mcf5282_fec_tx_interrupt_handler( rtems_vector_number v ) { MCF5282_FEC_EIR = MCF5282_FEC_EIR_TXF; MCF5282_FEC_EIMR &= ~MCF5282_FEC_EIMR_TXF; enet_driver[0].txInterrupts++; rtems_bsdnet_event_send(enet_driver[0].txDaemonTid, TX_INTERRUPT_EVENT); }
/* * Send packet (caller provides header). */ static void wd_start (struct ifnet *ifp) { struct wd_softc *sc = ifp->if_softc; rtems_bsdnet_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT); ifp->if_flags |= IFF_OACTIVE; }
void xilTemacSend(struct ifnet* ifp) { struct XilTemac* xilTemac = ifp->if_softc; /* wake up tx thread w/ outbound interface's signal */ rtems_bsdnet_event_send( gXilTxThread, xilTemac->iIoEvent ); ifp->if_flags |= IFF_OACTIVE; }
/* * SCC1 interrupt handler */ static void m8xx_scc1_interrupt_handler (void *unused) { /* Frame received? */ if ((m8xx.scc1.sccm & 0x8) && (m8xx.scc1.scce & 0x8)) { m8xx.scc1.scce = 0x8; /* Clear receive frame int */ m8xx.scc1.sccm &= ~0x8; /* Disable receive frame ints */ enet_driver[0].rxInterrupts++; /* Rx int has occurred */ rtems_bsdnet_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT); } /* Buffer transmitted or transmitter error? */ if ((m8xx.scc1.sccm & 0x12) && (m8xx.scc1.scce & 0x12)) { m8xx.scc1.scce = 0x12; /* Clear Tx int */ m8xx.scc1.sccm &= ~0x12; /* Disable Tx ints */ enet_driver[0].txInterrupts++; /* Tx int has occurred */ rtems_bsdnet_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT); } }
int rtems_minimac_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching) { struct ifnet *ifp; rtems_isr_entry dummy; int i; static int registered; uint8_t *tx_buffer = (uint8_t *)MINIMAC_TX_BASE; if(!attaching) { printk("Minimac driver cannot be detached.\n"); return 0; } ifp = &(arpcom.ac_if); if(registered) { printk("Minimac driver already in use.\n"); return 0; } registered = 1; memcpy(arpcom.ac_enaddr, get_mac_address(), 6); ifp->if_mtu = ETHERMTU; ifp->if_unit = 0; ifp->if_name = "minimac"; ifp->if_init = minimac_init; ifp->if_ioctl = minimac_ioctl; ifp->if_start = minimac_start; ifp->if_output = ether_output; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; ifp->if_snd.ifq_maxlen = ifqmaxlen; if_attach(ifp); ether_ifattach(ifp); rx_daemon_id = rtems_bsdnet_newproc("mrxd", 4096, rx_daemon, NULL); tx_daemon_id = rtems_bsdnet_newproc("mtxd", 4096, tx_daemon, NULL); rtems_interrupt_catch(rx_interrupt_handler, MM_IRQ_ETHRX, &dummy); rtems_interrupt_catch(tx_interrupt_handler, MM_IRQ_ETHTX, &dummy); MM_WRITE(MM_MINIMAC_STATE0, MINIMAC_STATE_LOADED); MM_WRITE(MM_MINIMAC_STATE1, MINIMAC_STATE_LOADED); for(i=0;i<7; i++) tx_buffer[i] = 0x55; tx_buffer[7] = 0xd5; MM_WRITE(MM_MINIMAC_SETUP, 0); rtems_bsdnet_event_send(tx_daemon_id, CTS_EVENT); bsp_interrupt_vector_enable(MM_IRQ_ETHRX); bsp_interrupt_vector_enable(MM_IRQ_ETHTX); return 1; }
rtems_isr enet_tx_isr(rtems_vector_number vector) { cp; /* * Buffer transmitted or transmitter error? */ if (g_enet_regs->eir & MCF5272_ENET_EIR_TXF) { cp; g_enet_regs->eir = MCF5272_ENET_EIR_TXF; enet_driver[0].txInterrupts++; rtems_bsdnet_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT); } cp; }
rtems_isr enet_rx_isr(rtems_vector_number vector) { cp; /* * Frame received? */ if (g_enet_regs->eir & MCF5272_ENET_EIR_RXF) { cp; g_enet_regs->eir = MCF5272_ENET_EIR_RXF; enet_driver[0].rxInterrupts++; rtems_bsdnet_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT); } cp; }
static rtems_isr rx_interrupt_handler(rtems_vector_number vector) { /* Deassert IRQ line. * The RX daemon will then read all the slots we marked as empty. */ if(MM_READ(MM_MINIMAC_STATE0) == MINIMAC_STATE_PENDING) MM_WRITE(MM_MINIMAC_STATE0, MINIMAC_STATE_EMPTY); if(MM_READ(MM_MINIMAC_STATE1) == MINIMAC_STATE_PENDING) MM_WRITE(MM_MINIMAC_STATE1, MINIMAC_STATE_EMPTY); rtems_bsdnet_event_send(rx_daemon_id, RX_EVENT); lm32_interrupt_ack(1 << MM_IRQ_ETHRX); }
/* * WD interrupt handler */ static void wd8003Enet_interrupt_handler (void * unused) { unsigned int tport; unsigned char status, status2; tport = wd_softc[0].port ; /* * Read status */ inport_byte(tport+ISR, status); outport_byte(tport+IMR, 0x00); /* * Ring overwrite */ if (status & MSK_OVW){ outport_byte(tport+CMDR, MSK_STP + MSK_RD2); /* stop 8390 */ Wait_X_ms(2); outport_byte(tport+RBCR0, 0); /* clear byte count */ outport_byte(tport+RBCR1, 0); inport_byte(tport+ISR, status2); status |= (status2 & (MSK_PTX+MSK_TXE)) ; /* TX status */ outport_byte(tport+TCR, MSK_LOOP); /* loopback mode */ outport_byte(tport+CMDR, MSK_STA + MSK_RD2); /* start */ overrun = 1 ; if ((status & (MSK_PTX+MSK_TXE)) == 0) resend = 1; } /* * Frame received? */ if (status & (MSK_PRX+MSK_RXE)) { outport_byte(tport+ISR, status & (MSK_PRX+MSK_RXE)); wd_softc[0].rxInterrupts++; rtems_bsdnet_event_send (wd_softc[0].rxDaemonTid, INTERRUPT_EVENT); } }
void xilTemacIsrSingle(struct XilTemac* xilTemac) { uint32_t base = xilTemac->iAddr; uint32_t disr = IN32( base + XTE_DISR_OFFSET ); struct ifnet* ifp = xilTemac->iIfp; if( disr && (ifp->if_flags & IFF_RUNNING) == 0 ) { /* some interrupt status bits are asserted but card is down */ printk("%s: Fatal error, disr 0 or this emac not running\n", DRIVER_PREFIX); /*assert(0);*/ } else { /* Handle all error conditions first */ if( disr & (XTE_DXR_DPTO_MASK | XTE_DXR_TERR_MASK | XTE_DXR_RECV_FIFO_MASK | XTE_DXR_SEND_FIFO_MASK) ) { printk("%s: Fatal Bus error, disr: %08x\n", DRIVER_PREFIX, disr); /*assert(0);*/ } if( disr & XTE_DXR_CORE_MASK ) { /* Normal case, temac interrupt */ uint32_t ipisr = IN32(base + XTE_IPISR_OFFSET); uint32_t ipier = IN32(base + XTE_IPIER_OFFSET); uint32_t newipier = ipier; uint32_t pending = ipisr & ipier; xilTemac->iStats.iInterrupts++; /* Check for all fatal errors, even if that error is not enabled in ipier */ if(ipisr & XTE_IPXR_FIFO_FATAL_ERROR_MASK) { printk("%s: Fatal Fifo Error ipisr: %08x\n", DRIVER_PREFIX, ipisr); /*assert(0);*/ } if(pending & XTE_IPXR_RECV_DONE_MASK) { /* We've received a packet - inc stats - disable rx interrupt - signal rx thread to empty out fifo (rx thread must renable interrupt) */ xilTemac->iStats.iRxInterrupts++; newipier &= ~XTE_IPXR_RECV_DONE_MASK; rtems_bsdnet_event_send(gXilRxThread, xilTemac->iIoEvent); } if(pending & XTE_IPXR_XMIT_DONE_MASK) { /* We've transmitted a packet. This interrupt is only ever enabled in the ipier if the tx thread didn't have enough space in the data fifo or the tplr fifo. If that's the case, we: - inc stats - disable tx interrupt - signal tx thread that a transmit has completed and thus there is now room to send again. */ xilTemac->iStats.iTxInterrupts++; newipier &= ~XTE_IPXR_XMIT_DONE_MASK; rtems_bsdnet_event_send(gXilTxThread, xilTemac->iIoEvent); } if(pending & XTE_IPXR_RECV_DROPPED_MASK) { /* A packet was dropped (because it was invalid, or receiving it have overflowed one of the rx fifo's). - Increment stats. - Clear interrupt condition. */ uint32_t toggle = 0; if(pending & XTE_IPXR_RECV_REJECT_MASK) { xilTemac->iStats.iRxRejectedInvalidFrame++; toggle |= XTE_IPXR_RECV_REJECT_MASK; } if(pending & XTE_IPXR_RECV_PFIFO_ABORT_MASK) { xilTemac->iStats.iRxRejectedDataFifoFull++; toggle |= XTE_IPXR_RECV_PFIFO_ABORT_MASK; } if(pending & XTE_IPXR_RECV_LFIFO_ABORT_MASK) { xilTemac->iStats.iRxRejectedLengthFifoFull++; toggle |= XTE_IPXR_RECV_LFIFO_ABORT_MASK; } xilTemac->iStats.iRxRejectedInterrupts++; OUT32(base + XTE_IPISR_OFFSET, toggle); } if(pending & XTE_IPXR_AUTO_NEG_MASK) { printk("%s: Autonegotiation finished\n", DRIVER_PREFIX); OUT32(base + XTE_IPISR_OFFSET, XTE_IPXR_AUTO_NEG_MASK); } if(newipier != ipier) { OUT32(base + XTE_IPIER_OFFSET, newipier); } } } }
static void mpc5200_fec_send_event(rtems_id task) { rtems_bsdnet_event_send(task, FEC_EVENT); }
static rtems_isr tx_interrupt_handler(rtems_vector_number vector) { lm32_interrupt_ack(1 << MM_IRQ_ETHTX); rtems_bsdnet_event_send(tx_daemon_id, CTS_EVENT); }
static void minimac_start(struct ifnet *ifp) { rtems_bsdnet_event_send(tx_daemon_id, START_TRANSMIT_EVENT); ifp->if_flags |= IFF_OACTIVE; }