FreeBSD/sys/dev/wl/if_wl.c
/*
 * wlrcv:
 *
 *	This routine is called by the interrupt handler to initiate a
 *	packet transfer from the board to the "if" layer above this
 *	driver.  This routine checks if a buffer has been successfully
 *	received by the WaveLAN.  If so, the routine wlread is called
 *	to do the actual transfer of the board data (including the
 *	ethernet header) into a packet (consisting of an mbuf chain).
 *
 * input	: number of the board to check
 * output	: if a packet is available, it is "sent up"
 *
 */
This routine is called by the interrupt handler to initiate a
packet transfer from the board to the "if" layer above this
driver.  This routine checks if a buffer has been successfully
received by the WaveLAN.  If so, the routine wlread is called
to do the actual transfer of the board data (including the
ethernet header) into a packet (consisting of an mbuf chain).

input        : number of the board to check
output       : if a packet is available, it is "sent up"
This routine is called by the interrupt handler to initiate a packet transfer from the board to the " if " layer above this driver . This routine checks if a buffer has been successfully received by the WaveLAN . If so the routine wlread is called to do the actual transfer of the board data ( including the ethernet header ) into a packet ( consisting of an mbuf chain ) . input : number of the board to check output : if a packet is available it is " sent up "
static void
wlrcv(struct wl_softc *sc)
{
    u_short	fd_p, status, offset, link_offset;
#ifdef WLDEBUG
    if (sc->ifp->if_flags & IFF_DEBUG)
	if_printf(sc->ifp, "entered wlrcv()\n");
#endif
    for (fd_p = sc->begin_fd; fd_p != I82586NULL; fd_p = sc->begin_fd) {
	WL_WRITE_2(sc, PIOR0, fd_p + 0);	
	status = WL_READ_2(sc, PIOP0);
	WL_WRITE_2(sc, PIOR1, fd_p + 4);	
	link_offset = WL_READ_2(sc, PIOP1);
	offset = WL_READ_2(sc, PIOP1);	
	if (status == 0xffff || offset == 0xffff ) {
	    if (wlhwrst(sc) != TRUE)
		if_printf(sc->ifp, "rcv(): hwrst ffff trouble.\n");
	    return;
	} else if (status & AC_SW_C) {
	    if (status == (RFD_DONE|RFD_RSC)) {
#ifdef	WLDEBUG
		if (sc->ifp->if_flags & IFF_DEBUG)
		    if_printf(sc->ifp, "RCV: RSC %x\n", status);
#endif
		if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
	    } else if (!(status & RFD_OK)) {
		if_printf(sc->ifp, "RCV: !OK %x\n", status);
		if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
	    } else if (status & 0xfff) {	
		if_printf(sc->ifp, "RCV: ERRs %x\n", status);
		if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
	    } else if (!wlread(sc, fd_p))
		return;
	    if (!wlrequeue(sc, fd_p)) {
		if (wlhwrst(sc) != TRUE)
		    if_printf(sc->ifp, "rcv(): hwrst trouble.\n");
		return;
	    }
	    sc->begin_fd = link_offset;
	} else {
	    break;
	}
    }
    return;
}
static void wlrcv ( struct wl_softc * sc ) { u_short fd_p , status , offset , link_offset ; #ifdef WLDEBUG if ( sc -> ifp -> if_flags & IFF_DEBUG ) if_printf ( sc -> ifp , " \n " ) ; #endif for ( fd_p = sc -> begin_fd ; fd_p != I82586NULL ; fd_p = sc -> begin_fd ) { WL_WRITE_2 ( sc , PIOR0 , fd_p + 0 ) ; status = WL_READ_2 ( sc , PIOP0 ) ; WL_WRITE_2 ( sc , PIOR1 , fd_p + 4 ) ; link_offset = WL_READ_2 ( sc , PIOP1 ) ; offset = WL_READ_2 ( sc , PIOP1 ) ; if ( status == 0xffff || offset == 0xffff ) { if ( wlhwrst ( sc ) != TRUE ) if_printf ( sc -> ifp , " \n " ) ; return ; } else if ( status & AC_SW_C ) { if ( status == ( RFD_DONE | RFD_RSC ) ) { #ifdef WLDEBUG if ( sc -> ifp -> if_flags & IFF_DEBUG ) if_printf ( sc -> ifp , " \n " , status ) ; #endif if_inc_counter ( sc -> ifp , IFCOUNTER_IERRORS , 1 ) ; } else if ( ! ( status & RFD_OK ) ) { if_printf ( sc -> ifp , " \n " , status ) ; if_inc_counter ( sc -> ifp , IFCOUNTER_IERRORS , 1 ) ; } else if ( status & 0xfff ) { if_printf ( sc -> ifp , " \n " , status ) ; if_inc_counter ( sc -> ifp , IFCOUNTER_IERRORS , 1 ) ; } else if ( ! wlread ( sc , fd_p ) ) return ; if ( ! wlrequeue ( sc , fd_p ) ) { if ( wlhwrst ( sc ) != TRUE ) if_printf ( sc -> ifp , " \n " ) ; return ; } sc -> begin_fd = link_offset ; } else { break ; } } return ; }
wlrcv:
      This routine is called by the interrupt handler to initiate a
      packet transfer from the board to the "if" layer above this
      driver.
wlrcv : This routine is called by the interrupt handler to initiate a packet transfer from the board to the " if " layer above this driver .
/* address of status */ /* address of link_offset */ /* rbd_offset */ /*I82586NULL*/ /* lost one */ /* can't happen */ /* abort on chain error */