Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Nov 2016 17:58:37 +0000 (UTC)
From:      Andriy Voskoboinyk <avos@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r308575 - in head: share/man/man4 sys/dev/rtwn sys/dev/rtwn/pci sys/dev/rtwn/rtl8192c/pci sys/dev/rtwn/usb
Message-ID:  <201611121758.uACHwbgO041250@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avos
Date: Sat Nov 12 17:58:37 2016
New Revision: 308575
URL: https://svnweb.freebsd.org/changeset/base/308575

Log:
  rtwn: enable 11n support for RTL8188CE.
  
  - Increase Rx buffer size from MCLBYTES to MJUMPAGESIZE.
  - Provide an additional defragmentation routine for frames larger
  than MCLBYTES; that is required by A-MSDU / Atheros Fast-Frames
  support to work with current Tx path implementation.
  
  Enabled features list for RTL8188CE:
  - Atheros Fast-Frames;
  - A-MPDU (Tx / Rx);
  - A-MSDU (Tx / Rx; 4k only);
  - Short Guard Interval.
  
  Tested with:
  - RTL8188CE (STA+AP) + RTL8821AU (STA).
  - RTL8188CE (STA) + RTL8188CUS (AP).
  
  Relnotes:	yes

Modified:
  head/share/man/man4/rtwn_pci.4
  head/sys/dev/rtwn/if_rtwn_tx.h
  head/sys/dev/rtwn/pci/rtwn_pci_attach.c
  head/sys/dev/rtwn/pci/rtwn_pci_rx.c
  head/sys/dev/rtwn/pci/rtwn_pci_tx.c
  head/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
  head/sys/dev/rtwn/usb/rtwn_usb_rx.c

Modified: head/share/man/man4/rtwn_pci.4
==============================================================================
--- head/share/man/man4/rtwn_pci.4	Sat Nov 12 17:36:28 2016	(r308574)
+++ head/share/man/man4/rtwn_pci.4	Sat Nov 12 17:58:37 2016	(r308575)
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"/
-.Dd October 17, 2016
+.Dd November 12, 2016
 .Dt RTWN_PCI 4
 .Os
 .Sh NAME
@@ -58,6 +58,3 @@ It operates in the 2GHz spectrum only.
 .Xr rtwnfw 4 ,
 .Xr rtwn_usb 4 ,
 .Xr pci 4
-.Sh CAVEATS
-Most 802.11 capabilities were turned off; some more testing
-is required to re-enable them.

Modified: head/sys/dev/rtwn/if_rtwn_tx.h
==============================================================================
--- head/sys/dev/rtwn/if_rtwn_tx.h	Sat Nov 12 17:36:28 2016	(r308574)
+++ head/sys/dev/rtwn/if_rtwn_tx.h	Sat Nov 12 17:58:37 2016	(r308575)
@@ -20,7 +20,9 @@
 #define IF_RTWN_TX_H
 
 void	rtwn_drain_mbufq(struct rtwn_softc *);
+#ifdef IEEE80211_SUPPORT_SUPERG
 void	rtwn_ff_flush_all(struct rtwn_softc *, union sec_param *);
+#endif
 int	rtwn_transmit(struct ieee80211com *, struct mbuf *);
 void	rtwn_start(struct rtwn_softc *);
 int	rtwn_raw_xmit(struct ieee80211_node *, struct mbuf *,

Modified: head/sys/dev/rtwn/pci/rtwn_pci_attach.c
==============================================================================
--- head/sys/dev/rtwn/pci/rtwn_pci_attach.c	Sat Nov 12 17:36:28 2016	(r308574)
+++ head/sys/dev/rtwn/pci/rtwn_pci_attach.c	Sat Nov 12 17:58:37 2016	(r308575)
@@ -149,8 +149,8 @@ rtwn_pci_alloc_rx_list(struct rtwn_softc
 
 	/* Create RX buffer DMA tag. */
 	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
-	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
-	    1, MCLBYTES, 0, NULL, NULL, &rx_ring->data_dmat);
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    MJUMPAGESIZE, 1, MJUMPAGESIZE, 0, NULL, NULL, &rx_ring->data_dmat);
 	if (error != 0) {
 		device_printf(sc->sc_dev, "could not create rx buf DMA tag\n");
 		goto fail;
@@ -166,7 +166,8 @@ rtwn_pci_alloc_rx_list(struct rtwn_softc
 			goto fail;
 		}
 
-		rx_data->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+		rx_data->m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
+		    MJUMPAGESIZE);
 		if (rx_data->m == NULL) {
 			device_printf(sc->sc_dev,
 			    "could not allocate rx mbuf\n");
@@ -175,8 +176,8 @@ rtwn_pci_alloc_rx_list(struct rtwn_softc
 		}
 
 		error = bus_dmamap_load(rx_ring->data_dmat, rx_data->map,
-		    mtod(rx_data->m, void *), MCLBYTES, rtwn_pci_dma_map_addr,
-		    &rx_data->paddr, BUS_DMA_NOWAIT);
+		    mtod(rx_data->m, void *), MJUMPAGESIZE,
+		    rtwn_pci_dma_map_addr, &rx_data->paddr, BUS_DMA_NOWAIT);
 		if (error != 0) {
 			device_printf(sc->sc_dev,
 			    "could not load rx buf DMA map");
@@ -184,7 +185,7 @@ rtwn_pci_alloc_rx_list(struct rtwn_softc
 		}
 
 		rtwn_pci_setup_rx_desc(pc, &rx_ring->desc[i], rx_data->paddr,
-		    MCLBYTES, i);
+		    MJUMPAGESIZE, i);
 	}
 	rx_ring->cur = 0;
 
@@ -206,7 +207,7 @@ rtwn_pci_reset_rx_list(struct rtwn_softc
 	for (i = 0; i < RTWN_PCI_RX_LIST_COUNT; i++) {
 		rx_data = &rx_ring->rx_data[i];
 		rtwn_pci_setup_rx_desc(pc, &rx_ring->desc[i],
-		    rx_data->paddr, MCLBYTES, i);
+		    rx_data->paddr, MJUMPAGESIZE, i);
 	}
 	rx_ring->cur = 0;
 }
@@ -287,8 +288,8 @@ rtwn_pci_alloc_tx_list(struct rtwn_softc
 	    BUS_DMASYNC_PREWRITE);
 
 	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
-	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
-	    1, MCLBYTES, 0, NULL, NULL, &tx_ring->data_dmat);
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    MJUMPAGESIZE, 1, MJUMPAGESIZE, 0, NULL, NULL, &tx_ring->data_dmat);
 	if (error != 0) {
 		device_printf(sc->sc_dev, "could not create tx buf DMA tag\n");
 		goto fail;

Modified: head/sys/dev/rtwn/pci/rtwn_pci_rx.c
==============================================================================
--- head/sys/dev/rtwn/pci/rtwn_pci_rx.c	Sat Nov 12 17:36:28 2016	(r308574)
+++ head/sys/dev/rtwn/pci/rtwn_pci_rx.c	Sat Nov 12 17:58:37 2016	(r308575)
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/rtwn/if_rtwnvar.h>
 #include <dev/rtwn/if_rtwn_debug.h>
 #include <dev/rtwn/if_rtwn_rx.h>
+#include <dev/rtwn/if_rtwn_task.h>
 #include <dev/rtwn/if_rtwn_tx.h>
 
 #include <dev/rtwn/pci/rtwn_pci_var.h>
@@ -120,7 +121,7 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc,
 
 	pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
 	if (__predict_false(pktlen < sizeof(struct ieee80211_frame_ack) ||
-	    pktlen > MCLBYTES)) {
+	    pktlen > MJUMPAGESIZE)) {
 		RTWN_DPRINTF(sc, RTWN_DEBUG_RECV,
 		    "%s: frame is too short/long: %d\n", __func__, pktlen);
 		goto fail;
@@ -129,7 +130,7 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc,
 	infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
 	shift = MS(rxdw0, R92C_RXDW0_SHIFT);
 
-	m1 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+	m1 = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
 	if (__predict_false(m1 == NULL)) {
 		device_printf(sc->sc_dev, "%s: could not allocate RX mbuf\n",
 		    __func__);
@@ -139,20 +140,20 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc,
 	bus_dmamap_unload(ring->data_dmat, rx_data->map);
 
 	error = bus_dmamap_load(ring->data_dmat, rx_data->map, mtod(m1, void *),
-	    MCLBYTES, rtwn_pci_dma_map_addr, &rx_data->paddr, 0);
+	    MJUMPAGESIZE, rtwn_pci_dma_map_addr, &rx_data->paddr, 0);
 	if (error != 0) {
 		m_freem(m1);
 
 		error = bus_dmamap_load(ring->data_dmat, rx_data->map,
-		    mtod(rx_data->m, void *), MCLBYTES, rtwn_pci_dma_map_addr,
-		    &rx_data->paddr, BUS_DMA_NOWAIT);
+		    mtod(rx_data->m, void *), MJUMPAGESIZE,
+		    rtwn_pci_dma_map_addr, &rx_data->paddr, BUS_DMA_NOWAIT);
 		if (error != 0)
 			panic("%s: could not load old RX mbuf",
 			    device_get_name(sc->sc_dev));
 
 		/* Physical address may have changed. */
-		rtwn_pci_setup_rx_desc(pc, rx_desc, rx_data->paddr, MCLBYTES,
-		    desc_idx);
+		rtwn_pci_setup_rx_desc(pc, rx_desc, rx_data->paddr,
+		    MJUMPAGESIZE, desc_idx);
 		goto fail;
 	}
 
@@ -169,7 +170,7 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc,
 	    __func__, pktlen, infosz, shift, rssi);
 
 	/* Update RX descriptor. */
-	rtwn_pci_setup_rx_desc(pc, rx_desc, rx_data->paddr, MCLBYTES,
+	rtwn_pci_setup_rx_desc(pc, rx_desc, rx_data->paddr, MJUMPAGESIZE,
 	    desc_idx);
 
 	/* Send the frame to the 802.11 layer. */
@@ -222,6 +223,8 @@ rtwn_pci_tx_done(struct rtwn_softc *sc, 
 
 			data->ni = NULL;
 			ring->queued--;
+			KASSERT(ring->queued >= 0,
+			    ("ring->queued (qid %d) underflow!\n", qid));
 		} else
 			m_freem(data->m);
 
@@ -235,9 +238,27 @@ rtwn_pci_tx_done(struct rtwn_softc *sc, 
 #endif
 	}
 
-	if (ring->queued < (RTWN_PCI_TX_LIST_COUNT - 1))
+	if ((sc->qfullmsk & (1 << qid)) != 0 &&
+	    ring->queued < (RTWN_PCI_TX_LIST_COUNT - 1)) {
 		sc->qfullmsk &= ~(1 << qid);
-	rtwn_start(sc);
+		rtwn_start(sc);
+	}
+
+#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_ratectl != RTWN_RATECTL_NET80211 && ring->queued <= 1) {
+		/*
+		 * XXX TODO: just make this a callout timer schedule
+		 * so we can flush the FF staging queue if we're
+		 * approaching idle.
+		 */
+		rtwn_cmd_sleepable(sc, NULL, 0, rtwn_ff_flush_all);
+	}
+#endif
 }
 
 static void
@@ -261,6 +282,17 @@ rtwn_pci_rx_done(struct rtwn_softc *sc)
 
 		ring->cur = (ring->cur + 1) % RTWN_PCI_RX_LIST_COUNT;
 	}
+
+	/* 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
+	if (!(sc->sc_flags & RTWN_FW_LOADED) ||
+	    sc->sc_ratectl != RTWN_RATECTL_NET80211)
+		rtwn_cmd_sleepable(sc, NULL, 0, rtwn_ff_flush_all);
+#endif
 }
 
 void

Modified: head/sys/dev/rtwn/pci/rtwn_pci_tx.c
==============================================================================
--- head/sys/dev/rtwn/pci/rtwn_pci_tx.c	Sat Nov 12 17:36:28 2016	(r308574)
+++ head/sys/dev/rtwn/pci/rtwn_pci_tx.c	Sat Nov 12 17:58:37 2016	(r308575)
@@ -58,6 +58,37 @@ __FBSDID("$FreeBSD$");
 #include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
 
 
+static struct mbuf *
+rtwn_mbuf_defrag(struct mbuf *m0, int how)
+{
+	struct mbuf *m = NULL;
+
+	KASSERT(m0->m_flags & M_PKTHDR,
+	    ("M_PKTHDR flag is absent (m %p)!", m0));
+
+	/* NB: we need _exactly_ one mbuf (no less, no more). */
+	if (m0->m_pkthdr.len > MJUMPAGESIZE) {
+		/* XXX MJUM9BYTES? */
+		return (NULL);
+	} else if (m0->m_pkthdr.len > MCLBYTES) {
+		m = m_getjcl(how, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
+		if (m == NULL)
+			return (NULL);
+
+		if (m_dup_pkthdr(m, m0, how) == 0) {
+			m_freem(m);
+			return (NULL);
+		}
+
+		m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
+		m->m_len = m->m_pkthdr.len;
+		m_freem(m0);
+
+		return (m);
+	} else
+		return (m_defrag(m0, how));
+}
+
 static int
 rtwn_pci_tx_start_frame(struct rtwn_softc *sc, struct ieee80211_node *ni,
     struct mbuf *m, uint8_t *tx_desc, uint8_t type)
@@ -114,7 +145,7 @@ rtwn_pci_tx_start_frame(struct rtwn_soft
 	if (error != 0) {
 		struct mbuf *mnew;
 
-		mnew = m_defrag(m, M_NOWAIT);
+		mnew = rtwn_mbuf_defrag(m, M_NOWAIT);
 		if (mnew == NULL) {
 			device_printf(sc->sc_dev, "can't defragment mbuf\n");
 			return (ENOBUFS);

Modified: head/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
==============================================================================
--- head/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c	Sat Nov 12 17:36:28 2016	(r308574)
+++ head/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c	Sat Nov 12 17:58:37 2016	(r308575)
@@ -138,15 +138,11 @@ r92ce_adj_devcaps(struct rtwn_softc *sc)
 {
 	struct ieee80211com *ic = &sc->sc_ic;
 
-	/* XXX TODO: test everything that removed here before enabling. */
-	/* XX do NOT enable PMGT until RSVD_PAGE command will not be fixed. */
-	ic->ic_caps &= ~(
-		  IEEE80211_C_PMGT	/* check null frame / device usability */
-		| IEEE80211_C_SWAMSDUTX
-		| IEEE80211_C_FF
-	);
-
-	ic->ic_htcaps = 0;
+	/*
+	 * XXX do NOT enable PMGT until RSVD_PAGE command
+	 * will not be tested / fixed + HRPWM register must be set too.
+	 */
+	ic->ic_caps &= ~IEEE80211_C_PMGT;
 }
 
 void

Modified: head/sys/dev/rtwn/usb/rtwn_usb_rx.c
==============================================================================
--- head/sys/dev/rtwn/usb/rtwn_usb_rx.c	Sat Nov 12 17:36:28 2016	(r308574)
+++ head/sys/dev/rtwn/usb/rtwn_usb_rx.c	Sat Nov 12 17:58:37 2016	(r308575)
@@ -326,7 +326,8 @@ finish:
 	 * flush the FF staging queue if we're approaching idle.
 	 */
 #ifdef	IEEE80211_SUPPORT_SUPERG
-	if (!(sc->sc_flags & RTWN_FW_LOADED))
+	if (!(sc->sc_flags & RTWN_FW_LOADED) ||
+	    sc->sc_ratectl != RTWN_RATECTL_NET80211)
 		rtwn_cmd_sleepable(sc, NULL, 0, rtwn_ff_flush_all);
 #endif
 



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