/** * Process tx and rx packets at the low-level interrupt. * * Should be called from the Stellaris Ethernet Interrupt Handler. This * function will read packets from the Stellaris Ethernet fifo and place them * into a pbuf queue. If the transmitter is idle and there is at least one packet * on the transmit queue, it will place it in the transmit fifo and start the * transmitter. * */ void stellarisif_interrupt(struct netif *netif) { struct ethernetif *ethernetif; struct pbuf *p; /* setup pointer to the if state data */ ethernetif = netif->state; /** * Process the transmit and receive queues as long as there is receive * data available * */ p = low_level_receive(netif); while(p != NULL) { /* Add the rx packet to the rx queue */ if(!enqueue_packet(p, ðernetif->rxq)) { /* Could not place the packet on the queue, bail out. */ pbuf_free(p); break; } /* Check if TX fifo is empty and packet available */ if((HWREG(ETH_BASE + MAC_O_TR) & MAC_TR_NEWTX) == 0) { p = dequeue_packet(ðernetif->txq); if(p != NULL) { low_level_transmit(netif, p); } } /* Read another packet from the RX fifo */ p = low_level_receive(netif); } /* One more check of the transmit queue/fifo */ if((HWREG(ETH_BASE + MAC_O_TR) & MAC_TR_NEWTX) == 0) { p = dequeue_packet(ðernetif->txq); if(p != NULL) { low_level_transmit(netif, p); } } }
/*..........................................................................*/ void eth_driver_read(void) { struct pbuf *p = low_level_receive(); if (p != NULL) { /* new packet received into the pbuf? */ if (ethernet_input(p, &l_netif) != ERR_OK) { /* pbuf not handled? */ LWIP_DEBUGF(NETIF_DEBUG, ("eth_driver_input: input error\n")); pbuf_free(p); /* free the pbuf */ } /* try to output a packet if TX fifo is empty and pbuf is available */ if ((ETH->TR & MAC_TR_NEWTX) == 0) { p = l_txq.get(); if (p != NULL) { low_level_transmit(p); pbuf_free(p); /* free the pbuf, lwIP knows nothing of it */ } } } ETH->IM |= ETH_INT_RX; /* re-enable the RX interrupt */ }