From owner-svn-src-all@freebsd.org Tue Apr 5 22:14:23 2016 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 19CD6B04FE6; Tue, 5 Apr 2016 22:14:23 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::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 E7E2C1AE0; Tue, 5 Apr 2016 22:14:22 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u35MEMh8070722; Tue, 5 Apr 2016 22:14:22 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u35MEMJM070720; Tue, 5 Apr 2016 22:14:22 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201604052214.u35MEMJM070720@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Tue, 5 Apr 2016 22:14:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r297596 - head/sys/dev/urtwn 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.21 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, 05 Apr 2016 22:14:23 -0000 Author: adrian Date: Tue Apr 5 22:14:21 2016 New Revision: 297596 URL: https://svnweb.freebsd.org/changeset/base/297596 Log: [urtwn] first cut of getting the fast-frames / amsdu support in shape. The urtwn hardware transmits FF/A-MSDU just fine - it takes an 802.11 frame and will dutifully send the thing. So: * bump RX queue up from 1. Why's it 1? That's really silly. * Add the "software A-MSDU" encap capability bit. * bump the TX buffer size up so we can at least send A-MSDU frames. * track active frames submitted to the NIC - we can't make assumptions about how many are in flight in the NIC though. For 88E parts we could use per-packet TX indication, but for R92 parts we can't. So, just fake it somewhat. * Kick the transmit queue when we finish reception; try to avoid stalls. * Kick the FF queue a little more regularly. A-MSDU TX won't happen until the net80211 side is done, but atheros fast-frames support should now work. Tested: * urtwn0: MAC/BB RTL8188EU, RF 6052 1T1R ; A-MSDU transmit. Modified: head/sys/dev/urtwn/if_urtwn.c head/sys/dev/urtwn/if_urtwnvar.h Modified: head/sys/dev/urtwn/if_urtwn.c ============================================================================== --- head/sys/dev/urtwn/if_urtwn.c Tue Apr 5 22:01:56 2016 (r297595) +++ head/sys/dev/urtwn/if_urtwn.c Tue Apr 5 22:14:21 2016 (r297596) @@ -70,6 +70,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef IEEE80211_SUPPORT_SUPERG +#include +#endif #include #include @@ -577,6 +580,8 @@ urtwn_attach(device_t self) #endif | IEEE80211_C_WPA /* 802.11i */ | IEEE80211_C_WME /* 802.11e */ + | IEEE80211_C_SWAMSDUTX /* Do software A-MSDU TX */ + | IEEE80211_C_FF /* Atheros fast-frames */ ; ic->ic_cryptocaps = @@ -894,6 +899,15 @@ urtwn_report_intr(struct usb_xfer *xfer, buf = data->buf; stat = (struct r92c_rx_stat *)buf; + /* + * For 88E chips we can tie the FF flushing here; + * this is where we do know exactly how deep the + * transmit queue is. + * + * But it won't work for R92 chips, so we can't + * take the easy way out. + */ + if (sc->chip & URTWN_CHIP_88E) { int report_sel = MS(le32toh(stat->rxdw3), R88E_RXDW3_RPT); @@ -1101,7 +1115,7 @@ tr_setup: data = STAILQ_FIRST(&sc->sc_rx_inactive); if (data == NULL) { KASSERT(m == NULL, ("mbuf isn't NULL")); - return; + goto finish; } STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next); STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next); @@ -1131,7 +1145,6 @@ tr_setup: (void)ieee80211_input_all(ic, m, rssi - nf, nf); } - URTWN_LOCK(sc); m = next; } @@ -1150,6 +1163,20 @@ tr_setup: } break; } +finish: + /* Finished receive; age anything left on the FF queue by a little bump */ + /* + * XXX TODO: just make this a callout timer schedule so we can + * flush the FF staging queue if we're approaching idle. + */ +#ifdef IEEE80211_SUPPORT_SUPERG + URTWN_UNLOCK(sc); + ieee80211_ff_age_all(ic, 1); + URTWN_LOCK(sc); +#endif + + /* Kick-start more transmit in case we stalled */ + urtwn_start(sc); } static void @@ -1161,6 +1188,9 @@ urtwn_txeof(struct urtwn_softc *sc, stru if (data->ni != NULL) /* not a beacon frame */ ieee80211_tx_complete(data->ni, data->m, status); + if (sc->sc_tx_n_active > 0) + sc->sc_tx_n_active--; + data->ni = NULL; data->m = NULL; @@ -1269,6 +1299,9 @@ static void urtwn_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) { struct urtwn_softc *sc = usbd_xfer_softc(xfer); +#ifdef IEEE80211_SUPPORT_SUPERG + struct ieee80211com *ic = &sc->sc_ic; +#endif struct urtwn_data *data; URTWN_ASSERT_LOCKED(sc); @@ -1287,12 +1320,14 @@ tr_setup: if (data == NULL) { URTWN_DPRINTF(sc, URTWN_DEBUG_XMIT, "%s: empty pending queue\n", __func__); + sc->sc_tx_n_active = 0; 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); + sc->sc_tx_n_active++; break; default: data = STAILQ_FIRST(&sc->sc_tx_active); @@ -1307,6 +1342,35 @@ tr_setup: break; } 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 <= 1) { + /* XXX ew - net80211 should defer this for us! */ + + /* + * Note: this sc_tx_n_active currently tracks + * the number of pending transmit submissions + * and not the actual depth of the TX frames + * pending to the hardware. That means that + * we're going to end up with some sub-optimal + * aggregation behaviour. + */ + /* + * XXX TODO: just make this a callout timer schedule so we can + * flush the FF staging queue if we're approaching idle. + */ + URTWN_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); + URTWN_LOCK(sc); + } +#endif /* Kick-start more transmit */ urtwn_start(sc); } @@ -3153,6 +3217,11 @@ urtwn_start(struct urtwn_softc *sc) } ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; m->m_pkthdr.rcvif = NULL; + + URTWN_DPRINTF(sc, URTWN_DEBUG_XMIT, "%s: called; m=%p\n", + __func__, + m); + if (urtwn_tx_data(sc, ni, m, bf) != 0) { if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); @@ -5326,6 +5395,10 @@ urtwn_raw_xmit(struct ieee80211_node *ni struct urtwn_data *bf; int error; + URTWN_DPRINTF(sc, URTWN_DEBUG_XMIT, "%s: called; m=%p\n", + __func__, + m); + /* prevent management frames from being sent if we're not ready */ URTWN_LOCK(sc); if (!(sc->sc_flags & URTWN_RUNNING)) { Modified: head/sys/dev/urtwn/if_urtwnvar.h ============================================================================== --- head/sys/dev/urtwn/if_urtwnvar.h Tue Apr 5 22:01:56 2016 (r297595) +++ head/sys/dev/urtwn/if_urtwnvar.h Tue Apr 5 22:14:21 2016 (r297596) @@ -17,12 +17,14 @@ * $FreeBSD$ */ -#define URTWN_RX_LIST_COUNT 1 +#define URTWN_RX_LIST_COUNT 64 #define URTWN_TX_LIST_COUNT 8 #define URTWN_HOST_CMD_RING_COUNT 32 -#define URTWN_RXBUFSZ (16 * 1024) -#define URTWN_TXBUFSZ (sizeof(struct r92c_tx_desc) + IEEE80211_MAX_LEN) +#define URTWN_RXBUFSZ (8 * 1024) +//#define URTWN_TXBUFSZ (sizeof(struct r92c_tx_desc) + IEEE80211_MAX_LEN) +/* Leave enough space for an A-MSDU frame */ +#define URTWN_TXBUFSZ (16 * 1024) #define URTWN_RX_DESC_SIZE (sizeof(struct r92c_rx_stat)) #define URTWN_TX_DESC_SIZE (sizeof(struct r92c_tx_desc)) @@ -195,6 +197,7 @@ struct urtwn_softc { urtwn_datahead sc_rx_inactive; struct urtwn_data sc_tx[URTWN_TX_LIST_COUNT]; urtwn_datahead sc_tx_active; + int sc_tx_n_active; urtwn_datahead sc_tx_inactive; urtwn_datahead sc_tx_pending;