Example #1
0
/*
 * A frame has been uploaded: pass the resulting mbuf up to
 * the higher level protocols.
 */
static void
lgue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
	struct lgue_softc	*sc;
	struct mbuf		*m;
	struct ifnet	*ifp;
	int			total_len;

	sc = priv;
	if (sc->lgue_dying)
		return;

	ifp = &sc->lgue_arpcom.ac_if;

	total_len = 0;

	if (!(ifp->if_flags & IFF_RUNNING))
		return;

	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
			return;
		if (usbd_ratecheck(&sc->lgue_rx_notice)) {
			if_printf(ifp, "usb error on rx:%s\n",
			    usbd_errstr(status));
		}
		if (status == USBD_STALLED)
			usbd_clear_endpoint_stall(sc->lgue_ep[LGUE_ENDPT_RX]);
		goto done;
	}

	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);

	if (total_len < sizeof(struct ether_header)) {
		IFNET_STAT_INC(ifp, ierrors, 1);
		goto done;
	}

	if (lgue_newbuf(sc, total_len, &m) == ENOBUFS) {
		IFNET_STAT_INC(ifp, ierrors, 1);
		return;
	}

	IFNET_STAT_INC(ifp, ipackets, 1);
	m_copyback(m, 0, total_len, sc->lgue_rx_buf);
	m->m_pkthdr.rcvif = ifp;
	m->m_pkthdr.len = m->m_len = total_len;

	usb_ether_input(m);
	lgue_rxstart(ifp);
	return;
done:
	usbd_setup_xfer(sc->lgue_rx_xfer, sc->lgue_ep[LGUE_ENDPT_RX], sc,
	    sc->lgue_rx_buf, LGUE_BUFSZ,
	    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, lgue_rxeof);
	usbd_transfer(sc->lgue_rx_xfer);
}
Example #2
0
void
ugl_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
	struct ugl_softc	*sc = priv;
	struct ifnet		*ifp = GET_IFP(sc);
	int			i;

	DPRINTFN(15,("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__));

	if (usbd_is_dying(sc->sc_udev))
		return;

	if (!(ifp->if_flags & IFF_RUNNING))
		return;

	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
			return;
		}
		sc->sc_intr_errs++;
		if (usbd_ratecheck(&sc->sc_rx_notice)) {
			printf("%s: %u usb errors on intr: %s\n",
			    sc->sc_dev.dv_xname, sc->sc_rx_errs,
			    usbd_errstr(status));
			sc->sc_intr_errs = 0;
		}
		if (status == USBD_STALLED)
			usbd_clear_endpoint_stall_async(sc->sc_ep[UGL_ENDPT_RX]);
		return;
	}

	DPRINTFN(10,("%s: %s:", sc->sc_dev.dv_xname, __func__));
	for (i = 0; i < UGL_INTR_PKTLEN; i++)
		DPRINTFN(10,(" 0x%02x", sc->sc_ibuf[i]));
	DPRINTFN(10,("\n"));

}
Example #3
0
/*
 * A frame has been uploaded: pass the resulting mbuf chain up to
 * the higher level protocols.
 */
void
kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
	struct kue_chain	*c = priv;
	struct kue_softc	*sc = c->kue_sc;
	struct ifnet		*ifp = GET_IFP(sc);
	struct mbuf		*m;
	int			total_len = 0;
	int			s;

	DPRINTFN(10,("%s: %s: enter status=%d\n", sc->kue_dev.dv_xname,
		     __func__, status));

	if (sc->kue_dying)
		return;

	if (!(ifp->if_flags & IFF_RUNNING))
		return;

	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
			return;
		sc->kue_rx_errs++;
		if (usbd_ratecheck(&sc->kue_rx_notice)) {
			printf("%s: %u usb errors on rx: %s\n",
			    sc->kue_dev.dv_xname, sc->kue_rx_errs,
			    usbd_errstr(status));
			sc->kue_rx_errs = 0;
		}
		if (status == USBD_STALLED)
			usbd_clear_endpoint_stall_async(sc->kue_ep[KUE_ENDPT_RX]);
		goto done;
	}

	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);

	DPRINTFN(10,("%s: %s: total_len=%d len=%d\n", sc->kue_dev.dv_xname,
		     __func__, total_len,
		     UGETW(mtod(c->kue_mbuf, u_int8_t *))));

	if (total_len <= 1)
		goto done;

	m = c->kue_mbuf;
	/* copy data to mbuf */
	memcpy(mtod(m, char *), c->kue_buf, total_len);

	/* No errors; receive the packet. */
	total_len = UGETW(mtod(m, u_int8_t *));
	m_adj(m, sizeof(u_int16_t));

	if (total_len < sizeof(struct ether_header)) {
		ifp->if_ierrors++;
		goto done;
	}

	ifp->if_ipackets++;
	m->m_pkthdr.len = m->m_len = total_len;

	m->m_pkthdr.rcvif = ifp;

	s = splnet();

	/* XXX ugly */
	if (kue_newbuf(sc, c, NULL) == ENOBUFS) {
		ifp->if_ierrors++;
		goto done1;
	}

#if NBPFILTER > 0
	/*
	 * Handle BPF listeners. Let the BPF user see the packet, but
	 * don't pass it up to the ether_input() layer unless it's
	 * a broadcast packet, multicast packet, matches our ethernet
	 * address or the interface is in promiscuous mode.
	 */
	if (ifp->if_bpf)
		bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
#endif

	DPRINTFN(10,("%s: %s: deliver %d\n", sc->kue_dev.dv_xname,
		    __func__, m->m_len));
	ether_input_mbuf(ifp, m);
 done1:
	splx(s);

 done:

	/* Setup new transfer. */
	usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
	    c, c->kue_buf, KUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
	    USBD_NO_TIMEOUT, kue_rxeof);
	usbd_transfer(c->kue_xfer);

	DPRINTFN(10,("%s: %s: start rx\n", sc->kue_dev.dv_xname,
		    __func__));
}
Example #4
0
/*
 * A frame has been received.
 */
void
wi_usb_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
	struct wi_usb_chain	*c = priv;
	struct wi_usb_softc	*sc = c->wi_usb_sc;
	wi_usb_usbin		*uin;
	int			total_len = 0;
	u_int16_t		rtype;

	if (usbd_is_dying(sc->wi_usb_udev))
		return;

	DPRINTFN(10,("%s: %s: enter status=%d\n", sc->wi_usb_dev.dv_xname,
		    __func__, status));


	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_IOERROR
		    || status == USBD_CANCELLED) {
			printf("%s: %u usb errors on rx: %s\n",
			    sc->wi_usb_dev.dv_xname, 1,
			    /* sc->wi_usb_rx_errs, */
			    usbd_errstr(status));
			return;
		}
#if 0
		sc->wi_usb_rx_errs++;
		if (usbd_ratecheck(&sc->wi_usb_rx_notice)) {
			printf("%s: %u usb errors on rx: %s\n",
			    sc->wi_usb_dev.dv_xname, sc->wi_usb_rx_errs,
			    usbd_errstr(status));
			sc->wi_usb_rx_errs = 0;
		}
#endif
		if (status == USBD_STALLED) {
			sc->wi_usb_refcnt++;
			usbd_clear_endpoint_stall_async(
			    sc->wi_usb_ep[WI_USB_ENDPT_RX]);
			if (--sc->wi_usb_refcnt < 0)
				usb_detach_wakeup(&sc->wi_usb_dev);
		}
		goto done;
	}

	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);

	if (total_len < 6) /* short XXX */
		goto done;

	uin = (wi_usb_usbin *)(c->wi_usb_buf);

	rtype = letoh16(uin->type);


#if 0
	wi_dump_data(c->wi_usb_buf, total_len);
#endif

	if (WI_USB_ISRXFRM(rtype)) {
		wi_usb_rxfrm(sc, uin, total_len);
		goto done;
	}
	if (WI_USB_ISTXFRM(rtype)) {
		DPRINTFN(2,("%s: %s: txfrm type %x\n",
		    sc->wi_usb_dev.dv_xname, __func__, rtype));
		wi_usb_txfrm(sc, uin, total_len);
		goto done;
	}

	switch (rtype) {
	case WI_USB_INFOFRM:
		/* info packet, INFO_FID hmm */
		DPRINTFN(10,("%s: %s: infofrm type %x\n",
		    sc->wi_usb_dev.dv_xname, __func__, rtype));
		wi_usb_infofrm(c, total_len);
		break;
	case WI_USB_CMDRESP:
		wi_usb_cmdresp(c);
		break;
	case WI_USB_WRIDRESP:
		wi_usb_wridresp(c);
		break;
	case WI_USB_RRIDRESP:
		wi_usb_rridresp(c);
		break;
	case WI_USB_WMEMRESP:
		/* Not currently used */
		DPRINTFN(2,("%s: %s: wmemresp type %x\n",
		    sc->wi_usb_dev.dv_xname, __func__, rtype));
		break;
	case WI_USB_RMEMRESP:
		/* Not currently used */
		DPRINTFN(2,("%s: %s: rmemresp type %x\n",
		    sc->wi_usb_dev.dv_xname, __func__, rtype));
		break;
	case WI_USB_BUFAVAIL:
		printf("wi_usb: received USB_BUFAVAIL packet\n"); /* XXX */
		break;
	case WI_USB_ERROR:
		printf("wi_usb: received USB_ERROR packet\n"); /* XXX */
		break;
#if 0
	default:
		printf("wi_usb: received Unknown packet 0x%x len %x\n",
		    rtype, total_len);
		wi_dump_data(c->wi_usb_buf, total_len);
#endif
	}

 done:
	/* Setup new transfer. */
	usbd_setup_xfer(c->wi_usb_xfer, sc->wi_usb_ep[WI_USB_ENDPT_RX],
	    c, c->wi_usb_buf, WI_USB_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
	    USBD_NO_TIMEOUT, wi_usb_rxeof);
	sc->wi_usb_refcnt++;
	usbd_transfer(c->wi_usb_xfer);
	if (--sc->wi_usb_refcnt < 0)
		usb_detach_wakeup(&sc->wi_usb_dev);

	DPRINTFN(10,("%s: %s: start rx\n", sc->wi_usb_dev.dv_xname,
		    __func__));
}
Example #5
0
Static void
url_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
	struct url_chain *c = priv;
	struct url_softc *sc = c->url_sc;
	struct ifnet *ifp = GET_IFP(sc);
	struct mbuf *m;
	u_int32_t total_len;
	url_rxhdr_t rxhdr;
	int s;

	DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));

	if (sc->sc_dying)
		return;

	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
			return;
		sc->sc_rx_errs++;
		if (usbd_ratecheck(&sc->sc_rx_notice)) {
			printf("%s: %u usb errors on rx: %s\n",
			       USBDEVNAME(sc->sc_dev), sc->sc_rx_errs,
			       usbd_errstr(status));
			sc->sc_rx_errs = 0;
		}
		if (status == USBD_STALLED) {
			sc->sc_refcnt++;
			usbd_clear_endpoint_stall_async(sc->sc_pipe_rx);
			if (--sc->sc_refcnt < 0)
				usb_detach_wakeup(USBDEV(sc->sc_dev));
		}
		goto done;
	}

	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);

	memcpy(mtod(c->url_mbuf, char *), c->url_buf, total_len);

	if (total_len <= ETHER_CRC_LEN) {
		ifp->if_ierrors++;
		goto done;
	}

	memcpy(&rxhdr, c->url_buf + total_len - ETHER_CRC_LEN, sizeof(rxhdr));

	DPRINTF(("%s: RX Status: %dbytes%s%s%s%s packets\n",
		 USBDEVNAME(sc->sc_dev),
		 UGETW(rxhdr) & URL_RXHDR_BYTEC_MASK,
		 UGETW(rxhdr) & URL_RXHDR_VALID_MASK ? ", Valid" : "",
		 UGETW(rxhdr) & URL_RXHDR_RUNTPKT_MASK ? ", Runt" : "",
		 UGETW(rxhdr) & URL_RXHDR_PHYPKT_MASK ? ", Physical match" : "",
		 UGETW(rxhdr) & URL_RXHDR_MCASTPKT_MASK ? ", Multicast" : ""));

	if ((UGETW(rxhdr) & URL_RXHDR_VALID_MASK) == 0) {
		ifp->if_ierrors++;
		goto done;
	}

	ifp->if_ipackets++;
	total_len -= ETHER_CRC_LEN;

	m = c->url_mbuf;
	m->m_pkthdr.len = m->m_len = total_len;
	m->m_pkthdr.rcvif = ifp;

	s = splnet();

	if (url_newbuf(sc, c, NULL) == ENOBUFS) {
		ifp->if_ierrors++;
		goto done1;
	}

#if NBPFILTER > 0
	if (ifp->if_bpf)
		bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
#endif

	DPRINTF(("%s: %s: deliver %d\n", USBDEVNAME(sc->sc_dev),
		 __func__, m->m_len));
	IF_INPUT(ifp, m);

 done1:
	splx(s);

 done:
	/* Setup new transfer */
	usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->url_buf, URL_BUFSZ,
			USBD_SHORT_XFER_OK | USBD_NO_COPY,
			USBD_NO_TIMEOUT, url_rxeof);
	sc->sc_refcnt++;
	usbd_transfer(xfer);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));

	DPRINTF(("%s: %s: start rx\n", USBDEVNAME(sc->sc_dev), __func__));
}
Example #6
0
/*
 * A frame has been uploaded: pass the resulting mbuf chain up to
 * the higher level protocols.
 */
static void
kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
	struct kue_chain	*c = priv;
	struct kue_softc	*sc = c->kue_sc;
	struct ifnet		*ifp = GET_IFP(sc);
	struct mbuf		*m;
	int			total_len, pktlen;
	int			s;

	DPRINTFN(10,("%s: %s: enter status=%d\n", device_xname(sc->kue_dev),
		     __func__, status));

	if (sc->kue_dying)
		return;

	if (!(ifp->if_flags & IFF_RUNNING))
		return;

	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
			return;
		sc->kue_rx_errs++;
		if (usbd_ratecheck(&sc->kue_rx_notice)) {
			printf("%s: %u usb errors on rx: %s\n",
			    device_xname(sc->kue_dev), sc->kue_rx_errs,
			    usbd_errstr(status));
			sc->kue_rx_errs = 0;
		}
		if (status == USBD_STALLED)
			usbd_clear_endpoint_stall_async(sc->kue_ep[KUE_ENDPT_RX]);
		goto done;
	}

	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);

	DPRINTFN(10,("%s: %s: total_len=%d len=%d\n", device_xname(sc->kue_dev),
		     __func__, total_len,
		     le16dec(c->kue_buf)));

	if (total_len <= 1)
		goto done;

	pktlen = le16dec(c->kue_buf);
	if (pktlen > total_len - 2)
		pktlen = total_len - 2;

	if (pktlen < ETHER_MIN_LEN - ETHER_CRC_LEN ||
	    pktlen > MCLBYTES - ETHER_ALIGN) {
		ifp->if_ierrors++;
		goto done;
	}

	/* No errors; receive the packet. */
	MGETHDR(m, M_DONTWAIT, MT_DATA);
	if (m == NULL) {
		ifp->if_ierrors++;
		goto done;
	}
	if (pktlen > MHLEN - ETHER_ALIGN) {
		MCLGET(m, M_DONTWAIT);
		if ((m->m_flags & M_EXT) == 0) {
			m_freem(m);
			ifp->if_ierrors++;
			goto done;
		}
	}
	m->m_data += ETHER_ALIGN;

	/* copy data to mbuf */
	memcpy(mtod(m, uint8_t *), c->kue_buf + 2, pktlen);

	ifp->if_ipackets++;
	m->m_pkthdr.len = m->m_len = pktlen;
	m->m_pkthdr.rcvif = ifp;

	s = splnet();

	/*
	 * Handle BPF listeners. Let the BPF user see the packet, but
	 * don't pass it up to the ether_input() layer unless it's
	 * a broadcast packet, multicast packet, matches our ethernet
	 * address or the interface is in promiscuous mode.
	 */
	bpf_mtap(ifp, m);

	DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->kue_dev),
		    __func__, m->m_len));
	(*ifp->if_input)(ifp, m);

	splx(s);

 done:

	/* Setup new transfer. */
	usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
	    c, c->kue_buf, KUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
	    USBD_NO_TIMEOUT, kue_rxeof);
	usbd_transfer(c->kue_xfer);

	DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->kue_dev),
		    __func__));
}
Example #7
0
/*
 * A frame has been uploaded: pass the resulting mbuf chain up to
 * the higher level protocols.
 */
void
ugl_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
	struct ugl_chain	*c = priv;
	struct ugl_softc	*sc = c->ugl_sc;
	struct ifnet		*ifp = GET_IFP(sc);
	struct mbuf		*m;
	int			total_len = 0;
	unsigned int		packet_len, packet_count;
	int			s;

	if (usbd_is_dying(sc->sc_udev))
		return;

	if (!(ifp->if_flags & IFF_RUNNING))
		return;

	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
			return;
		sc->sc_rx_errs++;
		if (usbd_ratecheck(&sc->sc_rx_notice)) {
			printf("%s: %u usb errors on rx: %s\n",
			    sc->sc_dev.dv_xname, sc->sc_rx_errs,
			    usbd_errstr(status));
			sc->sc_rx_errs = 0;
		}
		if (status == USBD_STALLED)
			usbd_clear_endpoint_stall_async(sc->sc_ep[UGL_ENDPT_RX]);
		goto done;
	}

	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);

	DPRINTFN(9,("%s: %s: enter status=%d length=%d\n",
		    sc->sc_dev.dv_xname, __func__, status, total_len));

	if (total_len < offsetof(struct ugl_packet, pkt_data)) {
		printf("%s: bad header (length=%d)\n",
		    sc->sc_dev.dv_xname, total_len);

		goto done;
	}

	packet_count = UGETDW(c->ugl_buf->pkt_count);
	if (packet_count != UGL_RX_FRAMES) {
		printf("%s: bad packet count (%d)\n",
		    sc->sc_dev.dv_xname, packet_count);

		if (packet_count == 0)
			goto done;
	}

	packet_len = UGETDW(c->ugl_buf->pkt_length);
	if (total_len < packet_len) {
		printf("%s: bad packet size(%d), length=%d\n",
		    sc->sc_dev.dv_xname, packet_len, total_len);

		if (packet_len == 0)
			goto done;
	}

	m = c->ugl_mbuf;
	memcpy(mtod(c->ugl_mbuf, char *), c->ugl_buf->pkt_data, packet_len);

	ifp->if_ipackets++;
	m->m_pkthdr.len = m->m_len = packet_len;

	m->m_pkthdr.rcvif = ifp;

	s = splnet();

	/* XXX ugly */
	if (ugl_newbuf(sc, c, NULL) == ENOBUFS) {
		ifp->if_ierrors++;
		goto done1;
	}

#if NBPFILTER > 0
	/*
	 * Handle BPF listeners. Let the BPF user see the packet, but
	 * don't pass it up to the ether_input() layer unless it's
	 * a broadcast packet, multicast packet, matches our ethernet
	 * address or the interface is in promiscuous mode.
	 */
	if (ifp->if_bpf) {
		bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
	}
#endif

	DPRINTFN(10,("%s: %s: deliver %d\n", sc->sc_dev.dv_xname,
		    __func__, m->m_len));

	ether_input_mbuf(ifp, m);

 done1:
	splx(s);

 done:
	/* Setup new transfer. */
	usbd_setup_xfer(c->ugl_xfer, sc->sc_ep[UGL_ENDPT_RX],
	    c, c->ugl_buf, UGL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
	    USBD_NO_TIMEOUT, ugl_rxeof);
	usbd_transfer(c->ugl_xfer);

	DPRINTFN(10,("%s: %s: start rx\n", sc->sc_dev.dv_xname,
		    __func__));
}
Example #8
0
/*
 * A frame has been uploaded: pass the resulting mbuf chain up to
 * the higher level protocols.
 */
void
kue_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
	struct kue_chain	*c = priv;
	struct kue_softc	*sc = c->kue_sc;
	struct ifnet		*ifp = GET_IFP(sc);
	struct mbuf_list	ml = MBUF_LIST_INITIALIZER();
	struct mbuf		*m;
	int			total_len = 0;
	int			s;

	DPRINTFN(10,("%s: %s: enter status=%d\n", sc->kue_dev.dv_xname,
		     __func__, status));

	if (usbd_is_dying(sc->kue_udev))
		return;

	if (!(ifp->if_flags & IFF_RUNNING))
		return;

	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
			return;
		sc->kue_rx_errs++;
		if (usbd_ratecheck(&sc->kue_rx_notice)) {
			printf("%s: %u usb errors on rx: %s\n",
			    sc->kue_dev.dv_xname, sc->kue_rx_errs,
			    usbd_errstr(status));
			sc->kue_rx_errs = 0;
		}
		if (status == USBD_STALLED)
			usbd_clear_endpoint_stall_async(sc->kue_ep[KUE_ENDPT_RX]);
		goto done;
	}

	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);

	DPRINTFN(10,("%s: %s: total_len=%d len=%d\n", sc->kue_dev.dv_xname,
		     __func__, total_len,
		     UGETW(mtod(c->kue_mbuf, u_int8_t *))));

	if (total_len <= 1)
		goto done;

	m = c->kue_mbuf;
	/* copy data to mbuf */
	memcpy(mtod(m, char *), c->kue_buf, total_len);

	/* No errors; receive the packet. */
	total_len = UGETW(mtod(m, u_int8_t *));
	m_adj(m, sizeof(u_int16_t));

	if (total_len < sizeof(struct ether_header)) {
		ifp->if_ierrors++;
		goto done;
	}

	m->m_pkthdr.len = m->m_len = total_len;
	ml_enqueue(&ml, m);

	if (kue_newbuf(sc, c, NULL) == ENOBUFS) {
		ifp->if_ierrors++;
		goto done;
	}

	s = splnet();
	if_input(ifp, &ml);
	splx(s);

 done:

	/* Setup new transfer. */
	usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
	    c, c->kue_buf, KUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
	    USBD_NO_TIMEOUT, kue_rxeof);
	usbd_transfer(c->kue_xfer);

	DPRINTFN(10,("%s: %s: start rx\n", sc->kue_dev.dv_xname,
		    __func__));
}