svn commit: r288648 - head/sys/dev/usb/wlan

Adrian Chadd adrian at FreeBSD.org
Sun Oct 4 04:44:07 UTC 2015


Author: adrian
Date: Sun Oct  4 04:44:06 2015
New Revision: 288648
URL: https://svnweb.freebsd.org/changeset/base/288648

Log:
  Random zyd(4) fixes to bring TX handling in line with rsu, etc
  
  * don't free buffers in the TX routine, only in transmit/raw_xmit
  * free nodes + references
  * .. and free those nodes/references /before/ net80211 detach
  
  Tested:
  
  * STA mode: zyd0: HMAC ZD1211B, FW 47.25, RF AL2230 S0, PA0 LED 0 BE0 NP1 Gain1 F0

Modified:
  head/sys/dev/usb/wlan/if_zyd.c

Modified: head/sys/dev/usb/wlan/if_zyd.c
==============================================================================
--- head/sys/dev/usb/wlan/if_zyd.c	Sun Oct  4 04:29:44 2015	(r288647)
+++ head/sys/dev/usb/wlan/if_zyd.c	Sun Oct  4 04:44:06 2015	(r288648)
@@ -420,6 +420,22 @@ detach:
 	return (ENXIO);			/* failure */
 }
 
+static void
+zyd_drain_mbufq(struct zyd_softc *sc)
+{
+	struct mbuf *m;
+	struct ieee80211_node *ni;
+
+	ZYD_LOCK_ASSERT(sc, MA_OWNED);
+	while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
+		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+		m->m_pkthdr.rcvif = NULL;
+		ieee80211_free_node(ni);
+		m_freem(m);
+	}
+}
+
+
 static int
 zyd_detach(device_t dev)
 {
@@ -433,6 +449,7 @@ zyd_detach(device_t dev)
 	 */
 	ZYD_LOCK(sc);
 	sc->sc_flags |= ZYD_FLAG_DETACHED;
+	zyd_drain_mbufq(sc);
 	STAILQ_INIT(&sc->tx_q);
 	STAILQ_INIT(&sc->tx_free);
 	ZYD_UNLOCK(sc);
@@ -451,7 +468,6 @@ zyd_detach(device_t dev)
 
 	if (ic->ic_softc == sc)
 		ieee80211_ifdetach(ic);
-	mbufq_drain(&sc->sc_snd);
 	mtx_destroy(&sc->sc_mtx);
 
 	return (0);
@@ -2443,7 +2459,6 @@ zyd_tx_start(struct zyd_softc *sc, struc
 	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
 		k = ieee80211_crypto_encap(ni, m0);
 		if (k == NULL) {
-			m_freem(m0);
 			return (ENOBUFS);
 		}
 		/* packet header may have moved, reset our local pointer */
@@ -2555,6 +2570,7 @@ zyd_start(struct zyd_softc *sc)
 		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
 		if (zyd_tx_start(sc, m, ni) != 0) {
 			ieee80211_free_node(ni);
+			m_freem(m);
 			if_inc_counter(ni->ni_vap->iv_ifp,
 			    IFCOUNTER_OERRORS, 1);
 			break;
@@ -2592,6 +2608,7 @@ zyd_raw_xmit(struct ieee80211_node *ni, 
 	if (zyd_tx_start(sc, m, ni) != 0) {
 		ZYD_UNLOCK(sc);
 		ieee80211_free_node(ni);
+		m_freem(m);
 		return (EIO);
 	}
 	ZYD_UNLOCK(sc);
@@ -2738,6 +2755,7 @@ zyd_stop(struct zyd_softc *sc)
 	ZYD_LOCK_ASSERT(sc, MA_OWNED);
 
 	sc->sc_flags &= ~ZYD_FLAG_RUNNING;
+	zyd_drain_mbufq(sc);
 
 	/*
 	 * Drain all the transfers, if not already drained:


More information about the svn-src-head mailing list