Date: Tue, 29 Sep 2015 05:03:25 +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: r288353 - head/sys/dev/usb/wlan Message-ID: <201509290503.t8T53P6w082230@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 <sys/param.h> #include <sys/sockio.h> #include <sys/sysctl.h> @@ -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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201509290503.t8T53P6w082230>