13.2.2 Pulling the Packets from the FIFO Buffer
The following code shows how the
el_rint( )
routine pulls the packets
from the first-in/first-out (FIFO) buffer. This task is specific to the hardware
device that is associated with the
if_el
device driver. If you need to perform
a similar task with your hardware device, use this example as a model.
while ((status > 0) && (count-- > 0)) {
1
len = status & RX_BYTES;
if ((status & RX_ER) || (len > 1518) || (len < 60)) {
2
if (status & RX_ER) {
3
status &= RX_EM;
if (sc->ctrblk.est_recvfail != 0xffff)
sc->ctrblk.est_r+;
switch (status) {
case RX_EOR:
4
if (sc->ctrblk.est_overrun != 0xffff)
sc->ctrblk.est_+;
if (sc->debug)
printf("el%d: Overrun\n", ifp->if_unit);
break;
case RX_ERT:
5
case RX_EOS:
sc->ctrblk.est_recvfail_bm |= 4;
if (sc->debug)
printf("el%d: Bad Sized packet\n", ifp->if_unit);
break;
case RX_ECR:
6
sc->ctrblk.est_recvfail_bm |= 1;
if (sc->debug)
printf("el%d: CRC\n", ifp->if_unit);
break;
case RX_EAL:
7
default:
sc->ctrblk.est_recvfail_bm |= 2;
if (sc->debug)
printf("el%d: Alignment\n", ifp->if_unit);
break;
}
} else
if ((sc->debug) && (len != 0))
8
printf("el%d: Received illegal size packet (%d)\n",
ifp->if_unit, len);
} else {
if (len <= MHLEN-2-4) {
9
MGETHDR(m, M_DONTWAIT, MT_DATA);
} else {
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m) {
MCLGET2(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
m_freem(m);
m = (struct mbuf *)NULL;
}
}
}
1
Sets up a
while
loop that executes as long as there are complete
packets.
13–6 Implementing the Interrupt Section