Exemplo n.º 1
0
/*
 * Driver transmit daemon
 */
void at91rm9200_emac_txDaemon (void *arg)
{
    at91rm9200_emac_softc_t *sc = (at91rm9200_emac_softc_t *)arg;
    struct ifnet *ifp = &sc->arpcom.ac_if;
    struct mbuf *m;
    rtems_event_set events;

    for (;;)
    {
        /* turn on TX interrupt, then wait for one */
        EMAC_REG(EMAC_IER) = EMAC_INT_TCOM;     /* Transmit complete */

        rtems_bsdnet_event_receive(
            START_TRANSMIT_EVENT,
            RTEMS_EVENT_ANY | RTEMS_WAIT,
            RTEMS_NO_TIMEOUT,
            &events);

        /* Send packets till queue is empty */
        for (;;)
        {
            /* Get the next mbuf chain to transmit. */
            IF_DEQUEUE(&ifp->if_snd, m);
            if (!m)
                break;
            at91rm9200_emac_sendpacket (ifp, m);
        }
        ifp->if_flags &= ~IFF_OACTIVE;
    }
}
Exemplo n.º 2
0
/*
 * Driver transmit daemon
 */
void
wd_txDaemon (void *arg)
{
	struct wd_softc *sc = (struct wd_softc *)arg;
	struct ifnet *ifp = &sc->arpcom.ac_if;
	struct mbuf *m;
	rtems_event_set events;

	for (;;) {
		/*
		 * Wait for packet
		 */
		rtems_bsdnet_event_receive (START_TRANSMIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);

		/*
		 * Send packets till queue is empty
		 */
		for (;;) {
			/*
			 * Get the next mbuf chain to transmit.
			 */
			IF_DEQUEUE(&ifp->if_snd, m);
			if (!m)
				break;
			sendpacket (ifp, m);
		}
		ifp->if_flags &= ~IFF_OACTIVE;
	}
}
Exemplo n.º 3
0
/*
 * Driver transmit daemon
 */
void mc9328mxl_enet_tx_task(void *arg)
{
    mc9328mxl_enet_softc_t *sc = (mc9328mxl_enet_softc_t *)arg;
    struct ifnet *ifp = &sc->arpcom.ac_if;
    struct mbuf *m;
    rtems_event_set events;

    for (;;)
    {
        rtems_bsdnet_event_receive(
            START_TRANSMIT_EVENT,
            RTEMS_EVENT_ANY | RTEMS_WAIT,
            RTEMS_NO_TIMEOUT,
            &events);

        /* Send packets till queue is empty */
        for (;;)
        {
            /* Get the next mbuf chain to transmit. */
            IF_DEQUEUE(&ifp->if_snd, m);
            if (!m) {
                break;
            }
            mc9328mxl_enet_sendpacket (ifp, m);
            softc.stats.tx_packets++;

        }
        ifp->if_flags &= ~IFF_OACTIVE;
    }
}
Exemplo n.º 4
0
static void mpc5200_fec_wait_for_event(void)
{
  rtems_event_set out;
  rtems_bsdnet_event_receive(
    FEC_EVENT,
    RTEMS_EVENT_ANY | RTEMS_WAIT,
    RTEMS_NO_TIMEOUT,
    &out
  );
}
Exemplo n.º 5
0
static void tx_daemon(void *arg)
{
  struct ifnet *ifp = &arpcom.ac_if;
  rtems_event_set events;
  struct mbuf *m;
  
  while(1) {
    rtems_bsdnet_event_receive(START_TRANSMIT_EVENT,
      RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);
    while(1) {
      IF_DEQUEUE(&ifp->if_snd, m);
      if(m == NULL)
        break;
      rtems_bsdnet_event_receive(CTS_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT,
        RTEMS_NO_TIMEOUT, &events);
      send_packet(ifp, m);
      m_freem(m);
    }
    ifp->if_flags &= ~IFF_OACTIVE;
  }
}
Exemplo n.º 6
0
static void rx_daemon(void *arg)
{
  rtems_event_set events;
  
  while(1) {
    rtems_bsdnet_event_receive(RX_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT,
      RTEMS_NO_TIMEOUT, &events);

    if(MM_READ(MM_MINIMAC_STATE0) == MINIMAC_STATE_EMPTY) {
      receive_packet((uint8_t *)MINIMAC_RX0_BASE, MM_READ(MM_MINIMAC_COUNT0));
      MM_WRITE(MM_MINIMAC_STATE0, MINIMAC_STATE_LOADED);
    }
    if(MM_READ(MM_MINIMAC_STATE1) == MINIMAC_STATE_EMPTY) {
      receive_packet((uint8_t *)MINIMAC_RX1_BASE, MM_READ(MM_MINIMAC_COUNT1));
      MM_WRITE(MM_MINIMAC_STATE1, MINIMAC_STATE_LOADED);
    }
  }
}
Exemplo n.º 7
0
void xilTemacRxThread( void *ignore )
{
  struct XilTemac* xilTemac;
  struct ifnet*   ifp;
  int             i;
  rtems_event_set events;

#ifdef DEBUG
  printk("%s: xilTemacRxThread running\n", DRIVER_PREFIX );
#endif

  for(;;) {
    rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
                                RTEMS_WAIT | RTEMS_EVENT_ANY,
                                RTEMS_NO_TIMEOUT,
                                &events);

#ifdef DEBUG
    printk("%s: rxthread, wakeup\n", DRIVER_PREFIX );
#endif

    for(i=0; i< NUM_XILTEMAC_UNITS; i++) {
      xilTemac = &gXilTemac[i];

      if( xilTemac->iIsPresent ) {
        ifp = xilTemac->iIfp;

        if( (ifp->if_flags & IFF_RUNNING) != 0 ) {
          if( events & xilTemac->iIoEvent ) {
            xilTemacRxThreadSingle(ifp);
          }
        }
        else {
          printk("%s: rxthread, interface %s present but not running\n", DRIVER_PREFIX, xilTemac->iUnitName );
          assert(0);
        }
      }
    }
  }
}
Exemplo n.º 8
0
void xilTemacTxThread( void *ignore )
{
  struct XilTemac  *xilTemac;
  struct ifnet     *ifp;

  rtems_event_set  events;
  int              i;

  for(;;) {
    /* Wait for:
       - notification from stack of packet to send OR
       - notification from interrupt handler that there is space available to
         send already queued packets
    */
    rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
                                RTEMS_EVENT_ANY | RTEMS_WAIT,
                                RTEMS_NO_TIMEOUT,
                                &events );

    for(i=0; i< NUM_XILTEMAC_UNITS; i++) {
      xilTemac = &gXilTemac[i];

      if( xilTemac->iIsPresent ) {
        ifp = xilTemac->iIfp;

        if( (ifp->if_flags & IFF_RUNNING) ) {

          if( events & xilTemac->iIoEvent ) {
            xilTemacTxThreadSingle(ifp);
          }

        } else {
          printk("%s: xilTemacTxThread: event received for device: %s, but device not active\n",
            DRIVER_PREFIX, xilTemac->iUnitName);
          assert(0);
        }
      }
    }
  }
}
Exemplo n.º 9
0
static void
open_eth_rxDaemon (void *arg)
{
    struct ether_header *eh;
    struct open_eth_softc *dp = (struct open_eth_softc *) &oc;
    struct ifnet *ifp = &dp->arpcom.ac_if;
    struct mbuf *m;
    unsigned int len;
    uint32_t len_status;
    unsigned int bad;
    rtems_event_set events;


    for (;;)
      {

	  rtems_bsdnet_event_receive (INTERRUPT_EVENT,
				      RTEMS_WAIT | RTEMS_EVENT_ANY,
				      RTEMS_NO_TIMEOUT, &events);
#ifdef OPEN_ETH_DEBUG
    printf ("r\n");
#endif

	  while (!
		 ((len_status =
		   dp->regs->xd[dp->rx_ptr+dp->txbufs].len_status) & OETH_RX_BD_EMPTY))
	    {
		bad = 0;
		if (len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT))
		  {
		      dp->rxLengthError++;
		      bad = 1;
		  }
		if (len_status & OETH_RX_BD_DRIBBLE)
		  {
		      dp->rxNonOctet++;
		      bad = 1;
		  }
		if (len_status & OETH_RX_BD_CRCERR)
		  {
		      dp->rxBadCRC++;
		      bad = 1;
		  }
		if (len_status & OETH_RX_BD_OVERRUN)
		  {
		      dp->rxOverrun++;
		      bad = 1;
		  }
		if (len_status & OETH_RX_BD_MISS)
		  {
		      dp->rxMiss++;
		      bad = 1;
		  }
		if (len_status & OETH_RX_BD_LATECOL)
		  {
		      dp->rxCollision++;
		      bad = 1;
		  }

		if (!bad)
		  {
		      /* pass on the packet in the receive buffer */
		      len = len_status >> 16;
		      m = (struct mbuf *) (dp->rxdesc[dp->rx_ptr].m);
		      m->m_len = m->m_pkthdr.len =
			  len - sizeof (struct ether_header);
		      eh = mtod (m, struct ether_header *);
		      m->m_data += sizeof (struct ether_header);
#ifdef CPU_U32_FIX
	              ipalign(m);	/* Align packet on 32-bit boundary */
#endif

		      ether_input (ifp, eh, m);

		      /* get a new mbuf */
		      MGETHDR (m, M_WAIT, MT_DATA);
		      MCLGET (m, M_WAIT);
		      m->m_pkthdr.rcvif = ifp;
		      dp->rxdesc[dp->rx_ptr].m = m;
		      dp->regs->xd[dp->rx_ptr + dp->txbufs].addr =
			  (uint32_t*) mtod (m, void *);
		      dp->rxPackets++;
		  }

		dp->regs->xd[dp->rx_ptr+dp->txbufs].len_status =
		  (dp->regs->xd[dp->rx_ptr+dp->txbufs].len_status &
		    ~OETH_TX_BD_STATS) | OETH_TX_BD_READY;
		dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;
	    }
      }
Exemplo n.º 10
0
static void
mcf5272_enet_rxDaemon (void *arg)
{
    struct mcf5272_enet_struct *sc = (struct mcf5272_enet_struct *)arg;
    struct ifnet *ifp = &sc->arpcom.ac_if;
    struct mbuf *m;
    uint16_t status;
    bd_t *rxBd;
    int rxBdIndex;

    /*
     * Allocate space for incoming packets and start reception
     */
    for (rxBdIndex = 0 ; ;) {
        rxBd = sc->rxBdBase + rxBdIndex;
        MGETHDR (m, M_WAIT, MT_DATA);
        MCLGET (m, M_WAIT);
        m->m_pkthdr.rcvif = ifp;
        sc->rxMbuf[rxBdIndex] = m;
        rxBd->buffer = mtod (m, void *);
        rxBd->status = MCF5272_BD_EMPTY;
        g_enet_regs->rdar = 0x1000000;
        if (++rxBdIndex == sc->rxBdCount) {
            rxBd->status |= MCF5272_BD_WRAP;
            break;
        }
    }

    /*
     * Input packet handling loop
     */
    rxBdIndex = 0;
    for (;;) {
        rxBd = sc->rxBdBase + rxBdIndex;

        /*
         * Wait for packet if there's not one ready
         */
        if ((status = rxBd->status) & MCF5272_BD_EMPTY) {
            /*
             * Clear old events
             */
            g_enet_regs->eir = MCF5272_ENET_EIR_RXF;

            /*
             * Wait for packet
             * Note that the buffer descriptor is checked
             * *before* the event wait -- this catches the
             * possibility that a packet arrived between the
             * `if' above, and the clearing of the event register.
             */
            while ((status = rxBd->status) & MCF5272_BD_EMPTY) {
                rtems_event_set events;

                /*
                 * Unmask RXF (Full frame received) event
                 */
                g_enet_regs->eir |= MCF5272_ENET_EIR_RXF;

                rtems_bsdnet_event_receive (INTERRUPT_EVENT,
                                            RTEMS_WAIT|RTEMS_EVENT_ANY,
                                            RTEMS_NO_TIMEOUT,
                                            &events);
                cp;
            }
        }
    cp;

        /*
         * Check that packet is valid
         */
        if (status & MCF5272_BD_LAST) {
            /*
             * Pass the packet up the chain.
             * FIXME: Packet filtering hook could be done here.
             */
            struct ether_header *eh;

            m = sc->rxMbuf[rxBdIndex];
            m->m_len = m->m_pkthdr.len = (rxBd->length -
                                          sizeof(uint32_t) -
                                          sizeof(struct ether_header));
            eh = mtod (m, struct ether_header *);
            m->m_data += sizeof(struct ether_header);
            ether_input (ifp, eh, m);

            /*
             * Allocate a new mbuf
             */
            MGETHDR (m, M_WAIT, MT_DATA);
            MCLGET (m, M_WAIT);
            m->m_pkthdr.rcvif = ifp;
            sc->rxMbuf[rxBdIndex] = m;
            rxBd->buffer = mtod (m, void *);
        }
        else {
            /*
             * Something went wrong with the reception
             */
            if (!(status & MCF5272_BD_LAST)) {
                sc->rxNotLast++;
            }
            if (status & MCF5272_BD_LONG) {
                sc->rxGiant++;
            }
            if (status & MCF5272_BD_NONALIGNED) {
                sc->rxNonOctet++;
            }
            if (status & MCF5272_BD_SHORT) {
                sc->rxRunt++;
            }
            if (status & MCF5272_BD_CRC_ERROR) {
                sc->rxBadCRC++;
            }
            if (status & MCF5272_BD_OVERRUN) {
                sc->rxOverrun++;
            }
            if (status & MCF5272_BD_TRUNCATED) {
                sc->rxTruncated++;
            }
        }
        /*
         * Reenable the buffer descriptor
         */
        rxBd->status = (status & MCF5272_BD_WRAP) | MCF5272_BD_EMPTY;
        g_enet_regs->rdar = 0x1000000;
        /*
         * Move to next buffer descriptor
         */
        if (++rxBdIndex == sc->rxBdCount) {
            rxBdIndex = 0;
        }
    }
Exemplo n.º 11
0
/*
 * SCC reader task
 */
static void
scc_rxDaemon (void *arg)
{
	struct scc_softc *sc = (struct scc_softc *)arg;
	struct ifnet *ifp = &sc->arpcom.ac_if;
	struct mbuf *m;
	uint16_t         status;
	volatile m360BufferDescriptor_t *rxBd;
	int rxBdIndex;

	/*
	 * Allocate space for incoming packets and start reception
	 */
	for (rxBdIndex = 0 ; ;) {
		rxBd = sc->rxBdBase + rxBdIndex;
		MGETHDR (m, M_WAIT, MT_DATA);
		MCLGET (m, M_WAIT);
		m->m_pkthdr.rcvif = ifp;
		sc->rxMbuf[rxBdIndex] = m;
		rxBd->buffer = mtod (m, void *);
		if (++rxBdIndex == sc->rxBdCount) {
			rxBd->status = M360_BD_EMPTY | M360_BD_INTERRUPT | M360_BD_WRAP;
			break;
		}
		rxBd->status = M360_BD_EMPTY | M360_BD_INTERRUPT;
	}

	/*
	 * Input packet handling loop
	 */
	rxBdIndex = 0;
	for (;;) {
		rxBd = sc->rxBdBase + rxBdIndex;

		/*
		 * Wait for packet if there's not one ready
		 */
		if ((status = rxBd->status) & M360_BD_EMPTY) {
			/*
			 * Clear old events
			 */
			m360.scc1.scce = 0x8;

			/*
			 * Wait for packet
			 * Note that the buffer descriptor is checked
			 * *before* the event wait -- this catches the
			 * possibility that a packet arrived between the
			 * `if' above, and the clearing of the event register.
			 */
			while ((status = rxBd->status) & M360_BD_EMPTY) {
				rtems_interrupt_level level;
				rtems_event_set events;

				/*
				 * Unmask RXF (Full frame received) event
				 */
				rtems_interrupt_disable (level);
				m360.scc1.sccm |= 0x8;
				rtems_interrupt_enable (level);

				rtems_bsdnet_event_receive (INTERRUPT_EVENT,
						RTEMS_WAIT|RTEMS_EVENT_ANY,
						RTEMS_NO_TIMEOUT,
						&events);
			}
		}

		/*
		 * Check that packet is valid
		 */
		if ((status & (M360_BD_LAST |
				M360_BD_FIRST_IN_FRAME |
				M360_BD_LONG |
				M360_BD_NONALIGNED |
				M360_BD_SHORT |
				M360_BD_CRC_ERROR |
				M360_BD_OVERRUN |
				M360_BD_COLLISION)) ==
						(M360_BD_LAST |
						M360_BD_FIRST_IN_FRAME)) {
			/*
			 * Pass the packet up the chain.
			 * FIXME: Packet filtering hook could be done here.
			 */
			struct ether_header *eh;

			m = sc->rxMbuf[rxBdIndex];
			m->m_len = m->m_pkthdr.len = rxBd->length -
						sizeof(uint32_t) -
						sizeof(struct ether_header);
			eh = mtod (m, struct ether_header *);
			m->m_data += sizeof(struct ether_header);
			ether_input (ifp, eh, m);

			/*
			 * Allocate a new mbuf
			 */
			MGETHDR (m, M_WAIT, MT_DATA);
			MCLGET (m, M_WAIT);
			m->m_pkthdr.rcvif = ifp;
			sc->rxMbuf[rxBdIndex] = m;
			rxBd->buffer = mtod (m, void *);
		}
		else {
			/*
			 * Something went wrong with the reception
			 */
			if (!(status & M360_BD_LAST))
				sc->rxNotLast++;
			if (!(status & M360_BD_FIRST_IN_FRAME))
				sc->rxNotFirst++;
			if (status & M360_BD_LONG)
				sc->rxGiant++;
			if (status & M360_BD_NONALIGNED)
				sc->rxNonOctet++;
			if (status & M360_BD_SHORT)
				sc->rxRunt++;
			if (status & M360_BD_CRC_ERROR)
				sc->rxBadCRC++;
			if (status & M360_BD_OVERRUN)
				sc->rxOverrun++;
			if (status & M360_BD_COLLISION)
				sc->rxCollision++;
		}

		/*
		 * Reenable the buffer descriptor
		 */
		rxBd->status = (status & (M360_BD_WRAP | M360_BD_INTERRUPT)) | M360_BD_EMPTY;

		/*
		 * Move to next buffer descriptor
		 */
		if (++rxBdIndex == sc->rxBdCount)
			rxBdIndex = 0;
	}
Exemplo n.º 12
0
static void
fec_rxDaemon (void *arg)
{
    volatile struct mcf5282_enet_struct *sc = (volatile struct mcf5282_enet_struct *)arg;
    struct ifnet *ifp = (struct ifnet* )&sc->arpcom.ac_if;
    struct mbuf *m;
    uint16_t status;
    volatile mcf5282BufferDescriptor_t *rxBd;
    int rxBdIndex;

    /*
     * Allocate space for incoming packets and start reception
     */
    for (rxBdIndex = 0 ; ;) {
        rxBd = sc->rxBdBase + rxBdIndex;
        MGETHDR(m, M_WAIT, MT_DATA);
        MCLGET(m, M_WAIT);
        m->m_pkthdr.rcvif = ifp;
        sc->rxMbuf[rxBdIndex] = m;
        rxBd->buffer = mtod(m, void *);
        rxBd->status = MCF5282_FEC_RxBD_E;
        if (++rxBdIndex == sc->rxBdCount) {
            rxBd->status |= MCF5282_FEC_RxBD_W;
            break;
        }
    }

    /*
     * Input packet handling loop
     */
    MCF5282_FEC_RDAR = 0;

    rxBdIndex = 0;
    for (;;) {
        rxBd = sc->rxBdBase + rxBdIndex;

        /*
         * Wait for packet if there's not one ready
         */
        if ((status = rxBd->status) & MCF5282_FEC_RxBD_E) {
            /*
             * Clear old events.
             */
            MCF5282_FEC_EIR = MCF5282_FEC_EIR_RXF;

            /*
             * Wait for packet to arrive.
             * Check the buffer descriptor before waiting for the event.
             * This catches the case when a packet arrives between the
             * `if' above, and the clearing of the RXF bit in the EIR.
             */
            while ((status = rxBd->status) & MCF5282_FEC_RxBD_E) {
                rtems_event_set events;
                int level;

                rtems_interrupt_disable(level);
                MCF5282_FEC_EIMR |= MCF5282_FEC_EIMR_RXF;
                rtems_interrupt_enable(level);
                rtems_bsdnet_event_receive (RX_INTERRUPT_EVENT,
                                            RTEMS_WAIT|RTEMS_EVENT_ANY,
                                            RTEMS_NO_TIMEOUT,
                                            &events);
            }
        }

        /*
         * Check that packet is valid
         */
        if (status & MCF5282_FEC_RxBD_L) {
            /*
             * Pass the packet up the chain.
             * FIXME: Packet filtering hook could be done here.
             */
            struct ether_header *eh;
            int len = rxBd->length - sizeof(uint32_t);

            m = sc->rxMbuf[rxBdIndex];
#ifdef RTEMS_MCF5282_BSP_ENABLE_DATA_CACHE
            /*
             * Invalidate the cache.  The cache is so small that it's
             * reasonable to simply invalidate the whole thing.
             */
            rtems_cache_invalidate_entire_data();
#endif
            m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
            eh = mtod(m, struct ether_header *);
            m->m_data += sizeof(struct ether_header);
            ether_input(ifp, eh, m);

            /*
             * Allocate a new mbuf
             */
            MGETHDR(m, M_WAIT, MT_DATA);
            MCLGET(m, M_WAIT);
            m->m_pkthdr.rcvif = ifp;
            sc->rxMbuf[rxBdIndex] = m;
            rxBd->buffer = mtod(m, void *);
        }

        /*
         * Reenable the buffer descriptor
         */
        rxBd->status = (status & MCF5282_FEC_RxBD_W) | MCF5282_FEC_RxBD_E;
        MCF5282_FEC_RDAR = 0;

        /*
         * Move to next buffer descriptor
         */
        if (++rxBdIndex == sc->rxBdCount)
            rxBdIndex = 0;
    }
}
Exemplo n.º 13
0
static void
wd_rxDaemon (void *arg)
{
  unsigned int tport;
  struct ether_header *eh;
  struct wd_softc *dp = (struct wd_softc *)&wd_softc[0];
  struct ifnet *ifp = &dp->arpcom.ac_if;
  struct mbuf *m;
  unsigned int i2;
  unsigned int len;
  volatile unsigned char start, next, current;
  unsigned char *shp, *temp;
  unsigned short *real_short_ptr;
  rtems_event_set events;

  tport = wd_softc[0].port ;

  for (;;){

    rtems_bsdnet_event_receive (INTERRUPT_EVENT,
				RTEMS_WAIT|RTEMS_EVENT_ANY,
				RTEMS_NO_TIMEOUT,
				&events);

    for (;;){
      inport_byte(tport+BNRY, start);

      outport_byte(tport+CMDR, MSK_PG1 + MSK_RD2);
      inport_byte(tport+CURR, current);
      outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2);

      start += 1;
      if (start >= OUTPAGE){
	start = 0;
      }

      if (current == start)
	break;

      /* real_short_ptr avoids cast on lvalue which gcc no longer allows */
      shp = dp->base + 1 + (SHAPAGE * start);
      next = *shp++;
      real_short_ptr = (unsigned short *)shp;
      len = *(real_short_ptr)++ - 4;

      if (next >= OUTPAGE){
	next = 0;
      }

      MGETHDR (m, M_WAIT, MT_DATA);
      MCLGET (m, M_WAIT);
      m->m_pkthdr.rcvif = ifp;

      temp = (unsigned char *) m->m_data;
      m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);

      if ((i2 = (OUTPAGE - start) * SHAPAGE - 4) < len){
	memcpy(temp, shp, i2);
	len -= i2;
	temp += i2;
	shp = dp->base;
      }
      memcpy(temp, shp, len);

      eh = mtod (m, struct ether_header *);
      m->m_data += sizeof(struct ether_header);
      ether_input (ifp, eh, m);

      outport_byte(tport+BNRY, next-1);
    }

  /*
   * Ring overwrite
   */
    if (overrun){
      outport_byte(tport+ISR, MSK_OVW);		/* reset IR */
      outport_byte(tport+TCR, 0);		/* out of loopback */
      if (resend  == 1)
	outport_byte(tport+CMDR, MSK_TXP + MSK_RD2);	/* resend */
      resend = 0;
      overrun = 0;
    }

    outport_byte(tport+IMR, 0x15);  /* re-enable IT rx */
  }
}
Exemplo n.º 14
0
static void fec_rxDaemon (void *arg)
{
  struct m8xx_fec_enet_struct *sc = (struct m8xx_fec_enet_struct *)arg;
  struct ifnet *ifp = &sc->arpcom.ac_if;
  struct mbuf *m;
  uint16_t   status;
  m8xxBufferDescriptor_t *rxBd;
  int rxBdIndex;

  /*
   * Allocate space for incoming packets and start reception
   */
  for (rxBdIndex = 0 ; ;) {
    rxBd = sc->rxBdBase + rxBdIndex;
    MGETHDR (m, M_WAIT, MT_DATA);
    MCLGET (m, M_WAIT);
    m->m_pkthdr.rcvif = ifp;
    sc->rxMbuf[rxBdIndex] = m;
    rxBd->buffer = mtod (m, void *);
    rxBd->status = M8xx_BD_EMPTY;
    m8xx.fec.r_des_active = 0x1000000;
    if (++rxBdIndex == sc->rxBdCount) {
      rxBd->status |= M8xx_BD_WRAP;
      break;
    }
  }

  /*
   * Input packet handling loop
   */
  rxBdIndex = 0;
  for (;;) {
    rxBd = sc->rxBdBase + rxBdIndex;

    /*
     * Wait for packet if there's not one ready
     */
    if ((status = rxBd->status) & M8xx_BD_EMPTY) {
      /*
       * Clear old events
       */
      m8xx.fec.ievent = M8xx_FEC_IEVENT_RFINT;

      /*
       * Wait for packet
       * Note that the buffer descriptor is checked
       * *before* the event wait -- this catches the
       * possibility that a packet arrived between the
       * `if' above, and the clearing of the event register.
       */
      while ((status = rxBd->status) & M8xx_BD_EMPTY) {
        rtems_event_set events;

        /*
         * Unmask RXF (Full frame received) event
         */
        m8xx.fec.ievent |= M8xx_FEC_IEVENT_RFINT;

        rtems_bsdnet_event_receive (INTERRUPT_EVENT,
                                    RTEMS_WAIT|RTEMS_EVENT_ANY,
                                    RTEMS_NO_TIMEOUT,
                                    &events);
      }
    }

    /*
     * Check that packet is valid
     */
    if (status & M8xx_BD_LAST) {
      /*
       * Pass the packet up the chain.
       * FIXME: Packet filtering hook could be done here.
       */
      struct ether_header *eh;

      /*
       * Invalidate the buffer for this descriptor
       */
      rtems_cache_invalidate_multiple_data_lines((const void *)rxBd->buffer, rxBd->length);

      m = sc->rxMbuf[rxBdIndex];
      m->m_len = m->m_pkthdr.len = rxBd->length -
        sizeof(uint32_t) -
        sizeof(struct ether_header);
      eh = mtod (m, struct ether_header *);
      m->m_data += sizeof(struct ether_header);
      ether_input (ifp, eh, m);

      /*
       * Allocate a new mbuf
       */
      MGETHDR (m, M_WAIT, MT_DATA);
      MCLGET (m, M_WAIT);
      m->m_pkthdr.rcvif = ifp;
      sc->rxMbuf[rxBdIndex] = m;
      rxBd->buffer = mtod (m, void *);
    }
    else {
      /*
       * Something went wrong with the reception
       */
      if (!(status & M8xx_BD_LAST))
        sc->rxNotLast++;
      if (status & M8xx_BD_LONG)
        sc->rxGiant++;
      if (status & M8xx_BD_NONALIGNED)
        sc->rxNonOctet++;
      if (status & M8xx_BD_SHORT)
        sc->rxRunt++;
      if (status & M8xx_BD_CRC_ERROR)
        sc->rxBadCRC++;
      if (status & M8xx_BD_OVERRUN)
        sc->rxOverrun++;
      if (status & M8xx_BD_COLLISION)
        sc->rxCollision++;
    }
    /*
     * Reenable the buffer descriptor
     */
    rxBd->status = (status & M8xx_BD_WRAP) |
      M8xx_BD_EMPTY;
    m8xx.fec.r_des_active = 0x1000000;
    /*
     * Move to next buffer descriptor
     */
    if (++rxBdIndex == sc->rxBdCount)
      rxBdIndex = 0;
  }
Exemplo n.º 15
0
static void rxDaemon(void *arg) {
  struct bfin_ethernetSoftc *sc;
  struct ifnet *ifp;
  struct mbuf *m;
  struct mbuf *rxPacket;
  void *dataPtr;
  rtems_event_set events;
  struct ether_header *eh;
  rxStatusT *status;
  uint32_t rxStatus;
  int head;
  int prevHead;
  int length;
  void *ethBase;
  void *rxdmaBase;

  sc = (struct bfin_ethernetSoftc *) arg;
  rxdmaBase = sc->rxdmaBase;
  ethBase = sc->ethBase;
  ifp = &sc->arpcom.ac_if;
  prevHead = sc->rxDescCount - 1;
  head = 0;

  BFIN_REG16(rxdmaBase, DMA_CONFIG_OFFSET) = DMA_MODE_RX;
  BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) |= EMAC_OPMODE_RE;

  while (1) {
    status = sc->rx[head].status.addr;
    rtems_cache_invalidate_multiple_data_lines(status, sizeof(*status));
    while (status->status != 0) {
      if (status->status & EMAC_RX_STAT_RX_OK) {
        /* get new cluster to replace this one */
        MGETHDR(m, M_WAIT, MT_DATA);
        MCLGET(m, M_WAIT);
        m->m_pkthdr.rcvif = ifp;
      } else
        m = NULL;

      rxStatus = status->status;
      /* update statistics */


      if (m) {
        /* save received packet to send up a little later */
        rxPacket = sc->rx[head].m;
        dataPtr = sc->rx[head].data.addr;

        /* setup dma for new cluster */
        sc->rx[head].m = m;
        sc->rx[head].data.addr = (void *) (((intptr_t) m->m_data + 3) & ~3);
        /* invalidate cache for new data buffer, in case any lines
           are dirty from previous owner */
        rtems_cache_invalidate_multiple_data_lines(
            sc->rx[head].data.addr,
            BFIN_ETHERNET_MAX_FRAME_LENGTH + 2);
      } else
        rxPacket = NULL;

      sc->rx[head].status.dmaConfig = DMA_MODE_STATUS_LAST;
      rtems_cache_flush_multiple_data_lines(&sc->rx[head],
                                            sizeof(sc->rx[head]));

      /* mark descriptor as empty */
      status->status = 0;
      rtems_cache_flush_multiple_data_lines(&status->status,
                                            sizeof(status->status));

      /* allow dma to continue from previous descriptor into this
         one */
      sc->rx[prevHead].status.dmaConfig = DMA_MODE_STATUS;
      rtems_cache_flush_multiple_data_lines(
          &sc->rx[prevHead].status.dmaConfig,
          sizeof(sc->rx[prevHead].status.dmaConfig));

      if (rxPacket) {
        /* send it up */
        eh = (struct ether_header *) ((intptr_t) dataPtr + 2);
        rxPacket->m_data = (caddr_t) ((intptr_t) dataPtr + 2 + 14);
        length = (rxStatus & EMAC_RX_STAT_RX_FRLEN_MASK) >>
                  EMAC_RX_STAT_RX_FRLEN_SHIFT;
        rxPacket->m_len = length - 14;
        rxPacket->m_pkthdr.len = rxPacket->m_len;
        /* invalidate packet buffer cache again (even though it
           was invalidated prior to giving it to dma engine),
           because speculative reads might cause cache lines to
           be filled at any time */
        rtems_cache_invalidate_multiple_data_lines(eh, length);
        ether_input(ifp, eh, rxPacket);
      }

      if (++prevHead == sc->rxDescCount)
        prevHead = 0;
      if (++head == sc->rxDescCount)
        head = 0;
      status = sc->rx[head].status.addr;
      rtems_cache_invalidate_multiple_data_lines(status, sizeof(*status));
    }

    /* if dma stopped before the next descriptor, restart it */
    if ((BFIN_REG16(rxdmaBase, DMA_IRQ_STATUS_OFFSET) &
         DMA_IRQ_STATUS_DMA_RUN) == 0 &&
        BFIN_REG32(rxdmaBase, DMA_NEXT_DESC_PTR_OFFSET) !=
        (uint32_t) &sc->rx[head].data) {
      BFIN_REG16(rxdmaBase, DMA_CONFIG_OFFSET) = DMA_MODE_RX;
    }

    rtems_bsdnet_event_receive(INTERRUPT_EVENT, RTEMS_WAIT | RTEMS_EVENT_ANY,
                               RTEMS_NO_TIMEOUT, &events);
  }

}
Exemplo n.º 16
0
static void txDaemon(void *arg) {
  struct bfin_ethernetSoftc *sc;
  struct ifnet *ifp;
  struct mbuf *m, *first;
  rtems_event_set events;
  void *ethBase;
  void *txdmaBase;
  txStatusT *status;
  int head;
  int prevHead;
  int tail;
  int length;
  char *ptr;

  sc = (struct bfin_ethernetSoftc *) arg;
  ifp = &sc->arpcom.ac_if;

  ethBase = sc->ethBase;
  txdmaBase = sc->txdmaBase;
  head = 0;
  prevHead = sc->txDescCount - 1;
  tail = 0;

  while (1) {
    /* wait for packet or isr */
    rtems_bsdnet_event_receive(START_TRANSMIT_EVENT | INTERRUPT_EVENT,
                               RTEMS_EVENT_ANY | RTEMS_WAIT,
                               RTEMS_NO_TIMEOUT, &events);

    /* if no descriptors are available, try to free one.  To reduce
       transmit latency only do one here. */
    if (sc->tx[head].inUse && txFree(sc, tail)) {
      if (++tail == sc->txDescCount)
        tail = 0;
    }
    /* send packets until the queue is empty or we run out of tx
       descriptors */
    while (!sc->tx[head].inUse && (ifp->if_flags & IFF_OACTIVE)) {
      /* get the next mbuf chain to transmit */
      IF_DEQUEUE(&ifp->if_snd, m);
      if (m != NULL) {
        /* copy packet into our buffer */
        ptr = sc->tx[head].buffer.packet.data;
        length = 0;
        first = m;
        while (m && length <= BFIN_ETHERNET_MAX_FRAME_LENGTH) {
          length += m->m_len;
          if (length <= BFIN_ETHERNET_MAX_FRAME_LENGTH)
            memcpy(ptr, m->m_data, m->m_len);
          ptr += m->m_len;
          m = m->m_next;
        }
        m_freem(first); /* all done with mbuf */
        if (length <= BFIN_ETHERNET_MAX_FRAME_LENGTH) {
          sc->tx[head].buffer.packet.length = length;

          /* setup tx dma */
          status = (txStatusT *) sc->tx[head].status.addr;
          status->status = 0;
          sc->tx[head].inUse = true;
          rtems_cache_flush_multiple_data_lines(status, sizeof(*status));

          /* configure dma to stop after sending this packet */
          sc->tx[head].status.dmaConfig = DMA_MODE_STATUS_LAST;
          rtems_cache_flush_multiple_data_lines(
              &sc->tx[head].status.dmaConfig,
              sizeof(sc->tx[head].status.dmaConfig));
          rtems_cache_flush_multiple_data_lines(
              &sc->tx[head].buffer.packet,
              length + sizeof(uint16_t));

          /* modify previous descriptor to let it continue
             automatically */
          sc->tx[prevHead].status.dmaConfig = DMA_MODE_STATUS;
          rtems_cache_flush_multiple_data_lines(
              &sc->tx[prevHead].status.dmaConfig,
              sizeof(sc->tx[prevHead].status.dmaConfig));

          /* restart dma if it stopped before the packet we just
             added.  this is purely to reduce transmit latency,
             as it would be restarted anyway after this loop (and
             needs to be, as there's a very small chance that the
             dma controller had started the last status transfer
             before the new dmaConfig word was written above and
             is still doing that status transfer when we check the
             status below.  this will be caught by the check
             outside the loop as that is guaranteed to run at least
             once after the last dma complete interrupt. */
          if ((BFIN_REG16(txdmaBase, DMA_IRQ_STATUS_OFFSET) &
               DMA_IRQ_STATUS_DMA_RUN) == 0 &&
               BFIN_REG32(txdmaBase, DMA_NEXT_DESC_PTR_OFFSET) !=
               (uint32_t) sc->tx[head].data.next) {
            BFIN_REG16(txdmaBase, DMA_CONFIG_OFFSET) = DMA_MODE_TX;
            BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) |= EMAC_OPMODE_TE;
          }

          if (++head == sc->txDescCount)
            head = 0;
          if (++prevHead == sc->txDescCount)
            prevHead = 0;

          /* if no descriptors are available, try to free one */
          if (sc->tx[head].inUse && txFree(sc, tail)) {
            if (++tail == sc->txDescCount)
              tail = 0;
          }
        } else {
          /* dropping packet: too large */

        }
      } else {
        /* no packets queued */
        ifp->if_flags &= ~IFF_OACTIVE;
      }
    }

    /* if dma stopped and there's more to do, restart it */
    if ((BFIN_REG16(txdmaBase, DMA_IRQ_STATUS_OFFSET) &
         DMA_IRQ_STATUS_DMA_RUN) == 0 &&
        BFIN_REG32(txdmaBase, DMA_NEXT_DESC_PTR_OFFSET) !=
        (uint32_t) &sc->tx[head].data) {
      BFIN_REG16(txdmaBase, DMA_CONFIG_OFFSET) = DMA_MODE_TX;
      BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) |= EMAC_OPMODE_TE;
    }

    /* free up any additional tx descriptors */
    while (txFree(sc, tail)) {
      if (++tail == sc->txDescCount)
        tail = 0;
    }
  }
}
Exemplo n.º 17
0
/* reader task */
void mc9328mxl_enet_rx_task(void *arg)
{
    mc9328mxl_enet_softc_t *sc = (mc9328mxl_enet_softc_t *)arg;
    struct ifnet *ifp = &sc->arpcom.ac_if;
    struct mbuf *m;
    struct ether_header *eh;
    rtems_event_set events;
    int pktlen;
    uint16_t rsw;
    uint16_t bc;
    uint16_t cbyte;
    int i;
    uint16_t int_reg;

    /* Input packet handling loop */
    while (1) {
        rtems_bsdnet_event_receive(
            START_RECEIVE_EVENT,
            RTEMS_EVENT_ANY | RTEMS_WAIT,
            RTEMS_NO_TIMEOUT,
            &events);

        /* Configure for reads from RX data area */
        lan91c11x_write_reg(LAN91C11X_PTR,
                            (LAN91C11X_PTR_AUTOINC |
                             LAN91C11X_PTR_RCV |
                             LAN91C11X_PTR_READ));

        /* read the receive status word */
        rsw = lan91c11x_read_reg(LAN91C11X_DATA);
        /* TBD: Need to check rsw here */

        /* read the byte count */
        bc = lan91c11x_read_reg(LAN91C11X_DATA);
        pktlen = (bc & 0x7ff) - 6;

        /* get an mbuf for this packet */
        MGETHDR(m, M_WAIT, MT_DATA);

        /* now get a cluster pointed to by the mbuf */
        /* since an mbuf by itself is too small */
        MCLGET(m, M_WAIT);

        lan91c11x_lock();

        /* Copy the received packet into an mbuf */
        for (i = 0; i < (pktlen / 2); i++) {
            ((uint16_t*)m->m_ext.ext_buf)[i] =
                lan91c11x_read_reg_fast(LAN91C11X_DATA);
        }

        cbyte = lan91c11x_read_reg_fast(LAN91C11X_DATA);
        if (cbyte & LAN91C11X_PKT_CTRL_ODD) {
            ((uint16_t*)m->m_ext.ext_buf)[i] = cbyte;
            pktlen++;
        }
        lan91c11x_unlock();

        /* Release the packets memory */
        lan91c11x_write_reg(LAN91C11X_MMUCMD,
                            LAN91C11X_MMUCMD_REMTOP);

        /* set the receiving interface */
        m->m_pkthdr.rcvif = ifp;
        m->m_nextpkt = 0;

        /* set the length of the mbuf */
        m->m_len = pktlen - (sizeof(struct ether_header));
        m->m_pkthdr.len = m->m_len;

        /* strip off the ethernet header from the mbuf */
        /* but save the pointer to it */
        eh = mtod (m, struct ether_header *);
        m->m_data += sizeof(struct ether_header);


        softc.stats.rx_packets++;

        /* give all this stuff to the stack */
        ether_input(ifp, eh, m);

        /* renable RX interrupts */
        int_reg = lan91c11x_read_reg(LAN91C11X_INT);
        int_reg |= LAN91C11X_INT_RXMASK;
        lan91c11x_write_reg(LAN91C11X_INT, int_reg);

    }
} /* mc9328mxl_enet_rx_task */
Exemplo n.º 18
0
static void
fec_sendpacket(struct ifnet *ifp, struct mbuf *m)
{
    struct mcf5282_enet_struct *sc = ifp->if_softc;
    volatile mcf5282BufferDescriptor_t *firstTxBd, *txBd;
    uint16_t status;
    int nAdded;

   /*
     * Free up buffer descriptors
     */
    fec_retire_tx_bd(sc);

    /*
     * Set up the transmit buffer descriptors.
     * No need to pad out short packets since the
     * hardware takes care of that automatically.
     * No need to copy the packet to a contiguous buffer
     * since the hardware is capable of scatter/gather DMA.
     */
    nAdded = 0;
    firstTxBd = sc->txBdBase + sc->txBdHead;

    while (m != NULL) {
        /*
         * Wait for buffer descriptor to become available
         */
        if ((sc->txBdActiveCount + nAdded)  == sc->txBdCount) {
            /*
             * Clear old events.
             */
            MCF5282_FEC_EIR = MCF5282_FEC_EIR_TXF;

            /*
             * Wait for buffer descriptor to become available.
             * Check for buffer descriptors before waiting for the event.
             * This catches the case when a buffer became available between
             * the `if' above, and the clearing of the TXF bit in the EIR.
             */
            fec_retire_tx_bd(sc);
            while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
                rtems_event_set events;
                int level;

                rtems_interrupt_disable(level);
                MCF5282_FEC_EIMR |= MCF5282_FEC_EIMR_TXF;
                rtems_interrupt_enable(level);
                sc->txRawWait++;
                rtems_bsdnet_event_receive(TX_INTERRUPT_EVENT,
                                           RTEMS_WAIT|RTEMS_EVENT_ANY,
                                           RTEMS_NO_TIMEOUT,
                                           &events);
                fec_retire_tx_bd(sc);
            }
        }

        /*
         * Don't set the READY flag on the first fragment
         * until the whole packet has been readied.
         */
        status = nAdded ? MCF5282_FEC_TxBD_R : 0;

        /*
         * The IP fragmentation routine in ip_output
         * can produce fragments with zero length.
         */
        txBd = sc->txBdBase + sc->txBdHead;
        if (m->m_len) {
            char *p = mtod(m, char *);
            int offset = (int)p & 0x3;
            if (offset == 0) {
                txBd->buffer = p;
                txBd->length = m->m_len;
                sc->txMbuf[sc->txBdHead] = m;
                m = m->m_next;
            }
            else {
                /*
                 * Stupid FEC can't handle misaligned data!
                 * Move offending bytes to a local buffer.
                 * Use buffer descriptor TO1 bit to indicate this.
                 */
                int nmove = 4 - offset;
                char *d = (char *)&sc->txMbuf[sc->txBdHead];
                status |= MCF5282_FEC_TxBD_TO1;
                sc->txRealign++;
                if (nmove > m->m_len)
                    nmove = m->m_len;
                m->m_data += nmove;
                m->m_len -= nmove;
                txBd->buffer = d;
                txBd->length = nmove;
                while (nmove--)
                    *d++ = *p++;
                if (m->m_len == 0) {
                    struct mbuf *n;
                    sc->txRealignDrop++;
                    MFREE(m, n);
                    m = n;
                }
            }
            nAdded++;
            if (++sc->txBdHead == sc->txBdCount) {
                status |= MCF5282_FEC_TxBD_W;
                sc->txBdHead = 0;
            }
            txBd->status = status;
        }
        else {
Exemplo n.º 19
0
/* SONIC reader task */
void at91rm9200_emac_rxDaemon(void *arg)
{
    at91rm9200_emac_softc_t *sc = (at91rm9200_emac_softc_t *)arg;
    struct ifnet *ifp = &sc->arpcom.ac_if;
    struct mbuf *m;
    struct ether_header *eh;
    rtems_event_set events;
    int pktlen;

    /* Input packet handling loop */
    for (;;) {
        /* turn on RX interrupts, then wait for one */
        EMAC_REG(EMAC_IER) = (EMAC_INT_RCOM |   /* Receive complete */
                              EMAC_INT_RBNA |   /* Receive buf not available */
                              EMAC_INT_ROVR);   /* Receive overrun */

        rtems_bsdnet_event_receive(
            START_RECEIVE_EVENT,
            RTEMS_EVENT_ANY | RTEMS_WAIT,
            RTEMS_NO_TIMEOUT,
            &events);

        if (EMAC_REG(EMAC_RSR) & EMAC_RSR_BNA) {
            printk("1: EMAC_BNA\n");
        }

        if (EMAC_REG(EMAC_RSR) & EMAC_RSR_OVR) {
            printk("1: EMAC_OVR\n");
        }

        /* clear the receive status as we do not use it anyway */
        EMAC_REG(EMAC_RSR) = (EMAC_RSR_REC | EMAC_RSR_OVR | EMAC_RSR_BNA);

        /* scan the buffer descriptors looking for any with data in them */
        while (rxbuf_hdrs[sc->rx_buf_idx].address & RXBUF_ADD_OWNED) {
            pktlen = rxbuf_hdrs[sc->rx_buf_idx].status & RXBUF_STAT_LEN_MASK;

            /* get an mbuf this packet */
            MGETHDR(m, M_WAIT, MT_DATA);

            /* now get a cluster pointed to by the mbuf */
            /* since an mbuf by itself is too small */
            MCLGET(m, M_WAIT);

            /* set the type of mbuf to ifp (ethernet I/F) */
            m->m_pkthdr.rcvif = ifp;
            m->m_nextpkt = 0;

            /* copy the packet into the cluster pointed to by the mbuf */
            memcpy((char *)m->m_ext.ext_buf,
                   (char *)(rxbuf_hdrs[sc->rx_buf_idx].address & 0xfffffffc),
                   pktlen);

            /* Release the buffer ASAP back to the EMAC */
            rxbuf_hdrs[sc->rx_buf_idx].address &= ~RXBUF_ADD_OWNED;

            /* set the length of the mbuf */
            m->m_len = pktlen - (sizeof(struct ether_header) + 4);
            m->m_pkthdr.len = m->m_len;

            /* strip off the ethernet header from the mbuf */
            /* but save the pointer to it */
            eh = mtod (m, struct ether_header *);
            m->m_data += sizeof(struct ether_header);

            /* increment the buffer index */
            sc->rx_buf_idx++;
            if (sc->rx_buf_idx >= NUM_RXBDS) {
                sc->rx_buf_idx = 0;
            }

            /* give all this stuff to the stack */
            ether_input(ifp, eh, m);

        } /* while ADD_OWNED = 0 */

        if (EMAC_REG(EMAC_RSR) & EMAC_RSR_BNA) {
            printk("2:EMAC_BNA\n");
        }
        if (EMAC_REG(EMAC_RSR) & EMAC_RSR_OVR) {
            printk("2:EMAC_OVR\n");
        }


    } /* for (;;) */
} /* at91rm9200_emac_rxDaemon() */
Exemplo n.º 20
0
/*
 * reader task
 */
static void
scc_rxDaemon (void *arg)
{
  struct m8260_hdlc_struct *sc = (struct m8260_hdlc_struct *)arg;
  struct ifnet *ifp = &sc->ac_if;
  struct mbuf *m;
  uint16_t         status;
  m8260BufferDescriptor_t *rxBd;
  int rxBdIndex;

  /*
   * Allocate space for incoming packets and start reception
   */
  for (rxBdIndex = 0 ; ;) {
    rxBd = sc->rxBdBase + rxBdIndex;
    MGETHDR (m, M_WAIT, MT_DATA);
    MCLGET (m, M_WAIT);
    m->m_pkthdr.rcvif = ifp;
    sc->rxMbuf[rxBdIndex] = m;
    rxBd->buffer = mtod (m, void *);
    rxBd->status = M8260_BD_EMPTY | M8260_BD_INTERRUPT;
    if (++rxBdIndex == sc->rxBdCount) {
      rxBd->status |= M8260_BD_WRAP;
      break;
    }
  }

/*
  m8260.scc3.sccm |= M8260_SCCE_RXF;
*/

  /*
   * Input packet handling loop
   */
  rxBdIndex = 0;
  for (;;) {
    rxBd = sc->rxBdBase + rxBdIndex;

    /*
     * Wait for packet if there's not one ready
     */
    if ((status = rxBd->status) & M8260_BD_EMPTY) {
      /*
       * Clear old events
       */

      m8260.scc3.scce = M8260_SCCE_RXF;

      /*
       * Wait for packet
       * Note that the buffer descriptor is checked
       * *before* the event wait -- this catches the
       * possibility that a packet arrived between the
       * `if' above, and the clearing of the event register.
       */
      while ((status = rxBd->status) & M8260_BD_EMPTY) {
        rtems_event_set events;

        /*
         * Unmask RXF (Full frame received) event
         */
        m8260.scc3.sccm |= M8260_SCCE_RXF;

/*        printk( "Rxdwait "); */

        rtems_bsdnet_event_receive (INTERRUPT_EVENT,
                                    RTEMS_WAIT|RTEMS_EVENT_ANY,
                                    RTEMS_NO_TIMEOUT,
                                    &events);

/*        printk( "Rxd " ); */
      }
    }

    /*
     * Check that packet is valid
     */
    if ((status & (M8260_BD_LAST |
                   M8260_BD_FIRST_IN_FRAME |
    		   M8260_BD_LONG |
                   M8260_BD_NONALIGNED |
                   M8260_BD_ABORT |
                   M8260_BD_CRC_ERROR |
                   M8260_BD_OVERRUN /*|
                   M8260_BD_CARRIER_LOST*/)) ==
                   (M8260_BD_LAST |
                   M8260_BD_FIRST_IN_FRAME ) ) {

/*      printk( "RxV " ); */

/*
 * Invalidate the buffer for this descriptor
 */

      rtems_cache_invalidate_multiple_data_lines((void *)rxBd->buffer, rxBd->length);

      m = sc->rxMbuf[rxBdIndex];

      /* strip off HDLC CRC */
      m->m_len = m->m_pkthdr.len = rxBd->length - sizeof(uint16_t);

      hdlc_input( ifp, m );

      /*
       * Allocate a new mbuf
       */
      MGETHDR (m, M_WAIT, MT_DATA);
      MCLGET (m, M_WAIT);
      m->m_pkthdr.rcvif = ifp;
      sc->rxMbuf[rxBdIndex] = m;
      rxBd->buffer = mtod (m, void *);
    }
    else {