From owner-svn-src-all@freebsd.org Tue Sep 29 05:03:25 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 70AE3A0AE0B; Tue, 29 Sep 2015 05:03:25 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5E9871637; Tue, 29 Sep 2015 05:03:25 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t8T53PJr082231; Tue, 29 Sep 2015 05:03:25 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t8T53P6w082230; Tue, 29 Sep 2015 05:03:25 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201509290503.t8T53P6w082230@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Tue, 29 Sep 2015 05:03:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r288353 - head/sys/dev/usb/wlan X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Sep 2015 05:03:25 -0000 Author: adrian Date: Tue Sep 29 05:03:24 2015 New Revision: 288353 URL: https://svnweb.freebsd.org/changeset/base/288353 Log: urtwn driver fixes - missing include, free node references, shut down xfers first * include opt_wlan.h like a good little wlan driver; * add a function to free the mbufq /and/ the node references on it, or we will leak said node references; * free the mbufq upon NIC shutdown otherwise we may end up with a full list that we never begin transmit work on, and thus never drain it; * .. which frees it upon NIC detach too; * ensure urtwn_start() gets called after the completion of frame TX even if the pending queue is empty, otherwise transmit will stall. It's highly unlikely that the usb tx queue would be empty whilst the incoming send queue is full, but hey, who knows. This passes some iperf testing with and without the NIC being actively removed during said active iperf test. Tested: * urtwn0: MAC/BB RTL8188EU, RF 6052 1T1R ; STA mode Modified: head/sys/dev/usb/wlan/if_urtwn.c Modified: head/sys/dev/usb/wlan/if_urtwn.c ============================================================================== --- head/sys/dev/usb/wlan/if_urtwn.c Tue Sep 29 04:56:27 2015 (r288352) +++ head/sys/dev/usb/wlan/if_urtwn.c Tue Sep 29 05:03:24 2015 (r288353) @@ -24,6 +24,8 @@ __FBSDID("$FreeBSD$"); * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188EU/RTL8188RU/RTL8192CU. */ +#include "opt_wlan.h" + #include #include #include @@ -169,6 +171,7 @@ static device_detach_t urtwn_detach; static usb_callback_t urtwn_bulk_tx_callback; static usb_callback_t urtwn_bulk_rx_callback; +static void urtwn_drain_mbufq(struct urtwn_softc *sc); static usb_error_t urtwn_do_request(struct urtwn_softc *, struct usb_device_request *, void *); static struct ieee80211vap *urtwn_vap_create(struct ieee80211com *, @@ -467,6 +470,20 @@ detach: return (ENXIO); /* failure */ } +static void +urtwn_drain_mbufq(struct urtwn_softc *sc) +{ + struct mbuf *m; + struct ieee80211_node *ni; + URTWN_ASSERT_LOCKED(sc); + 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 urtwn_detach(device_t self) { @@ -482,6 +499,9 @@ urtwn_detach(device_t self) callout_drain(&sc->sc_watchdog_ch); + /* stop all USB transfers */ + usbd_transfer_unsetup(sc->sc_xfer, URTWN_N_TRANSFER); + /* Prevent further allocations from RX/TX data lists. */ URTWN_LOCK(sc); STAILQ_INIT(&sc->sc_tx_active); @@ -502,10 +522,7 @@ urtwn_detach(device_t self) urtwn_free_rx_list(sc); URTWN_UNLOCK(sc); - /* stop all USB transfers */ - usbd_transfer_unsetup(sc->sc_xfer, URTWN_N_TRANSFER); ieee80211_ifdetach(ic); - mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); @@ -879,13 +896,12 @@ tr_setup: data = STAILQ_FIRST(&sc->sc_tx_pending); if (data == NULL) { DPRINTF("%s: empty pending queue\n", __func__); - return; + goto finish; } STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next); STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next); usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen); usbd_transfer_submit(xfer); - urtwn_start(sc); break; default: data = STAILQ_FIRST(&sc->sc_tx_active); @@ -903,6 +919,9 @@ tr_setup: } break; } +finish: + /* Kick-start more transmit */ + urtwn_start(sc); } static struct urtwn_data * @@ -1778,7 +1797,6 @@ urtwn_tx_start(struct urtwn_softc *sc, s device_printf(sc->sc_dev, "ieee80211_crypto_encap returns NULL.\n"); /* XXX we don't expect the fragmented frames */ - m_freem(m0); return (ENOBUFS); } @@ -1931,6 +1949,7 @@ urtwn_start(struct urtwn_softc *sc) if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); + m_freem(m); ieee80211_free_node(ni); break; } @@ -3417,6 +3436,8 @@ urtwn_stop(struct urtwn_softc *sc) sc->sc_flags &= ~URTWN_RUNNING; callout_stop(&sc->sc_watchdog_ch); urtwn_abort_xfers(sc); + + urtwn_drain_mbufq(sc); } static void @@ -3455,14 +3476,15 @@ urtwn_raw_xmit(struct ieee80211_node *ni } if (urtwn_tx_start(sc, ni, m, bf) != 0) { + m_freem(m); ieee80211_free_node(ni); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); URTWN_UNLOCK(sc); return (EIO); } + sc->sc_txtimer = 5; URTWN_UNLOCK(sc); - sc->sc_txtimer = 5; return (0); }