Index: sys/dev/usb/wlan/if_urtwn.c =================================================================== --- sys/dev/usb/wlan/if_urtwn.c +++ sys/dev/usb/wlan/if_urtwn.c @@ -183,7 +183,7 @@ int *); static struct mbuf * urtwn_rxeof(struct usb_xfer *, struct urtwn_data *, int *, int8_t *); -static void urtwn_txeof(struct usb_xfer *, struct urtwn_data *); +static int urtwn_txeof(struct usb_xfer *, int); static int urtwn_alloc_list(struct urtwn_softc *, struct urtwn_data[], int, int); static int urtwn_alloc_rx_list(struct urtwn_softc *); @@ -830,17 +830,30 @@ } } -static void -urtwn_txeof(struct usb_xfer *xfer, struct urtwn_data *data) +static int +urtwn_txeof(struct usb_xfer *xfer, int status) { struct urtwn_softc *sc = usbd_xfer_softc(xfer); + struct urtwn_data *data; URTWN_ASSERT_LOCKED(sc); - /* XXX status? */ - ieee80211_tx_complete(data->ni, data->m, 0); + + data = STAILQ_FIRST(&sc->sc_tx_active); + if (data == NULL) + return 0; + + STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next); + + ieee80211_tx_complete(data->ni, data->m, status); + data->ni = NULL; data->m = NULL; + sc->sc_txtimer = 0; + + STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next); + + return 1; } static int @@ -949,12 +962,7 @@ switch (USB_GET_STATE(xfer)){ case USB_ST_TRANSFERRED: - data = STAILQ_FIRST(&sc->sc_tx_active); - if (data == NULL) - goto tr_setup; - STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next); - urtwn_txeof(xfer, data); - STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next); + urtwn_txeof(xfer, 0); /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: @@ -969,15 +977,8 @@ usbd_transfer_submit(xfer); break; default: - data = STAILQ_FIRST(&sc->sc_tx_active); - if (data == NULL) + if (!urtwn_txeof(xfer, 1)) goto tr_setup; - if (data->ni != NULL) { - if_inc_counter(data->ni->ni_vap->iv_ifp, - IFCOUNTER_OERRORS, 1); - ieee80211_free_node(data->ni); - data->ni = NULL; - } if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); goto tr_setup;