Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Sep 2015 01:09:48 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r288319 - head/sys/dev/otus
Message-ID:  <201509280109.t8S19mH8083335@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Mon Sep 28 01:09:48 2015
New Revision: 288319
URL: https://svnweb.freebsd.org/changeset/base/288319

Log:
  if_otus fixes; add fast-frames support.
  
  Fast-frames:
  
  * include opt_wlan.h ; tsk to not doing it earlier;
  * add a tx pending tracking counter for seeing how deep
    the hardware TX queue is;
  * add the frame aging code from if_ath;
  * add fast-frames capability to the driver setup.
  
  Bugs:
  
  * free the buffers (and node references) before
    detaching net80211 state.  This prevents a use-after-free in
    the node free path where we've destroyed net80211 underneath it.

Modified:
  head/sys/dev/otus/if_otus.c
  head/sys/dev/otus/if_otusreg.h

Modified: head/sys/dev/otus/if_otus.c
==============================================================================
--- head/sys/dev/otus/if_otus.c	Mon Sep 28 00:59:07 2015	(r288318)
+++ head/sys/dev/otus/if_otus.c	Mon Sep 28 01:09:48 2015	(r288319)
@@ -24,6 +24,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_wlan.h"
+
 #include <sys/param.h>
 #include <sys/endian.h>
 #include <sys/sockio.h>
@@ -60,6 +62,9 @@ __FBSDID("$FreeBSD$");
 #include <net80211/ieee80211_radiotap.h>
 #include <net80211/ieee80211_ratectl.h>
 #include <net80211/ieee80211_input.h>
+#ifdef	IEEE80211_SUPPORT_SUPERG
+#include <net80211/ieee80211_superg.h>
+#endif
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
@@ -340,6 +345,7 @@ otus_detach(device_t self)
 	taskqueue_drain(taskqueue_thread, &sc->tx_task);
 	taskqueue_drain(taskqueue_thread, &sc->wme_update_task);
 
+	otus_close_pipes(sc);
 #if 0
 	/* Wait for all queued asynchronous commands to complete. */
 	usb_rem_wait_task(sc->sc_udev, &sc->sc_task);
@@ -348,7 +354,6 @@ otus_detach(device_t self)
 #endif
 
 	ieee80211_ifdetach(ic);
-	otus_close_pipes(sc);
 	mtx_destroy(&sc->sc_mtx);
 	return 0;
 }
@@ -949,9 +954,12 @@ fail:	otus_close_pipes(sc);
 void
 otus_close_pipes(struct otus_softc *sc)
 {
+
+	OTUS_LOCK(sc);
 	otus_free_tx_cmd_list(sc);
 	otus_free_tx_list(sc);
 	otus_free_rx_list(sc);
+	OTUS_UNLOCK(sc);
 
 	usbd_transfer_unsetup(sc->sc_xfer, OTUS_N_XFER);
 }
@@ -1838,6 +1846,9 @@ tr_setup:
 			} else
 				(void)ieee80211_input_mimo_all(ic, m, NULL);
 		}
+#ifdef	IEEE80211_SUPPORT_SUPERG
+		ieee80211_ff_age_all(ic, 100);
+#endif
 		OTUS_LOCK(sc);
 		break;
 	default:
@@ -1866,6 +1877,14 @@ otus_txeof(struct usb_xfer *xfer, struct
 
 	OTUS_LOCK_ASSERT(sc);
 
+	if (sc->sc_tx_n_active == 0) {
+		device_printf(sc->sc_dev,
+		    "%s: completed but tx_active=0\n",
+		    __func__);
+	} else {
+		sc->sc_tx_n_active--;
+	}
+
 	if (data->m) {
 		/* XXX status? */
 		/* XXX we get TX status via the RX path.. */
@@ -1926,6 +1945,7 @@ tr_setup:
 		if (data == NULL) {
 			OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT,
 			    "%s: empty pending queue sc %p\n", __func__, sc);
+			sc->sc_tx_n_active = 0;
 			goto finish;
 		}
 		STAILQ_REMOVE_HEAD(&sc->sc_tx_pending[which], next);
@@ -1934,6 +1954,7 @@ tr_setup:
 		OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT,
 		    "%s: submitting transfer %p\n", __func__, data);
 		usbd_transfer_submit(xfer);
+		sc->sc_tx_n_active++;
 		break;
 	default:
 		data = STAILQ_FIRST(&sc->sc_tx_active[which]);
@@ -1952,6 +1973,22 @@ tr_setup:
 	}
 
 finish:
+#ifdef	IEEE80211_SUPPORT_SUPERG
+	/*
+	 * If the TX active queue drops below a certain
+	 * threshold, ensure we age fast-frames out so they're
+	 * transmitted.
+	 */
+	if (sc->sc_tx_n_active < 2) {
+		/* XXX ew - net80211 should defer this for us! */
+		OTUS_UNLOCK(sc);
+		ieee80211_ff_flush(ic, WME_AC_VO);
+		ieee80211_ff_flush(ic, WME_AC_VI);
+		ieee80211_ff_flush(ic, WME_AC_BE);
+		ieee80211_ff_flush(ic, WME_AC_BK);
+		OTUS_LOCK(sc);
+	}
+#endif
 	/* Kick TX */
 	otus_tx_start(sc);
 }

Modified: head/sys/dev/otus/if_otusreg.h
==============================================================================
--- head/sys/dev/otus/if_otusreg.h	Mon Sep 28 00:59:07 2015	(r288318)
+++ head/sys/dev/otus/if_otusreg.h	Mon Sep 28 01:09:48 2015	(r288319)
@@ -984,6 +984,10 @@ struct otus_softc {
 	/* current noisefloor, from SET_FREQUENCY */
 	int				sc_nf[OTUS_NUM_CHAINS];
 
+	/* How many pending, active transmit frames */
+	int				sc_tx_n_pending;
+	int				sc_tx_n_active;
+
 	const uint32_t			*phy_vals;
 
 	struct {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201509280109.t8S19mH8083335>