diff -r d950fa65e8d8 sys/dev/usb/if_urtwn.c
--- a/sys/dev/usb/if_urtwn.c	Wed Aug 13 06:47:28 2025 +0000
+++ b/sys/dev/usb/if_urtwn.c	Wed Aug 13 22:45:47 2025 +1000
@@ -2659,7 +2659,10 @@ urtwn_txeof(struct usbd_xfer *xfer, void
 	urtwn_put_tx_data(sc, data);
 
 	s = splnet();
+	mutex_enter(&sc->sc_tx_mtx);
+	sc->sc_numxfers--;
 	sc->tx_timer = 0;
+	mutex_exit(&sc->sc_tx_mtx);
 	ifp->if_flags &= ~IFF_OACTIVE;
 
 	if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
@@ -2697,6 +2700,12 @@ urtwn_tx(struct urtwn_softc *sc, struct 
 
 	URTWNHIST_FUNC(); URTWNHIST_CALLED();
 
+	mutex_enter(&sc->sc_tx_mtx);
+	if (sc->sc_numxfers > (sc->tx_npipe - 1)) {
+		mutex_exit(&sc->sc_tx_mtx);
+		return EAGAIN;
+	}
+
 	wh = mtod(m, struct ieee80211_frame *);
 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 	txd_len = sizeof(*txd);
@@ -2707,6 +2716,7 @@ urtwn_tx(struct urtwn_softc *sc, struct 
 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
 		k = ieee80211_crypto_encap(ic, ni, m);
 		if (k == NULL) {
+			mutex_exit(&sc->sc_tx_mtx);
 			urtwn_put_tx_data(sc, data);
 			m_free(m);
 			return ENOBUFS;
@@ -2874,14 +2884,17 @@ urtwn_tx(struct urtwn_softc *sc, struct 
 	usbd_setup_xfer(data->xfer, data, data->buf, xferlen,
 	    USBD_FORCE_SHORT_XFER, URTWN_TX_TIMEOUT,
 	    urtwn_txeof);
+	sc->sc_numxfers++;
 	error = usbd_transfer(data->xfer);
 	if (__predict_false(error != USBD_NORMAL_COMPLETION &&
 	    error != USBD_IN_PROGRESS)) {
 		splx(s);
 		DPRINTFN(DBG_TX, "transfer failed %jd", error, 0, 0, 0);
+		mutex_exit(&sc->sc_tx_mtx);
 		return error;
 	}
 	splx(s);
+	mutex_exit(&sc->sc_tx_mtx);
 	return 0;
 }
 
diff -r d950fa65e8d8 sys/dev/usb/if_urtwnvar.h
--- a/sys/dev/usb/if_urtwnvar.h	Wed Aug 13 06:47:28 2025 +0000
+++ b/sys/dev/usb/if_urtwnvar.h	Wed Aug 13 22:45:47 2025 +1000
@@ -140,6 +140,7 @@ struct urtwn_softc {
 	int				rx_npipe;
 	struct usbd_pipe *		tx_pipe[R92C_MAX_EPOUT];
 	int				tx_npipe;
+	int				sc_numxfers;
 	int				ac2idx[WME_NUM_AC];
 
 	u_int				chip;
