Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 17 Jan 2017 00:35:23 +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: r312315 - in head/sys/dev/rtwn: . pci rtl8188e rtl8188e/usb rtl8192c rtl8192c/pci rtl8192c/usb rtl8812a rtl8812a/usb rtl8821a/usb usb
Message-ID:  <201701170035.v0H0ZNUu042297@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avos
Date: Tue Jan 17 00:35:23 2017
New Revision: 312315
URL: https://svnweb.freebsd.org/changeset/base/312315

Log:
  rtwn: export more stats to net80211
  
  Setup more ieee80211_rx_stats fields for received frames:
   - pktflags:
    * IEEE80211_RX_F_FAIL_FCSCRC;
    * IEEE80211_RX_F_AMPDU;
    * IEEE80211_RX_F_AMPDU_MORE;
    * IEEE80211_RX_F_SHORTGI;
   - rate flags (CCK, OFDM, HT);
   - width;
   - phytype;
   - rate;
   - rx_tsf;
   - rssi;
   - nf;
   - ieee, freq (RTL8188EU only, when ht40 support is disabled).
  
  Tested with:
   - RTL8188CE, RTL8188EU, RTL8821AU (STA / AP modes, i386)
   - (by kevlo) RTL8188EU and RTL8812AU (amd64)
  
  Reviewed by:	adrian (previous version), kevlo
  Differential Revision:	https://reviews.freebsd.org/D9021

Modified:
  head/sys/dev/rtwn/if_rtwn.c
  head/sys/dev/rtwn/if_rtwn_rx.c
  head/sys/dev/rtwn/if_rtwn_rx.h
  head/sys/dev/rtwn/if_rtwnvar.h
  head/sys/dev/rtwn/pci/rtwn_pci_rx.c
  head/sys/dev/rtwn/rtl8188e/r88e.h
  head/sys/dev/rtwn/rtl8188e/r88e_rx.c
  head/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
  head/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
  head/sys/dev/rtwn/rtl8192c/r92c.h
  head/sys/dev/rtwn/rtl8192c/r92c_reg.h
  head/sys/dev/rtwn/rtl8192c/r92c_rx.c
  head/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h
  head/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
  head/sys/dev/rtwn/rtl8812a/r12a.h
  head/sys/dev/rtwn/rtl8812a/r12a_rx.c
  head/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h
  head/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
  head/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
  head/sys/dev/rtwn/usb/rtwn_usb_rx.c

Modified: head/sys/dev/rtwn/if_rtwn.c
==============================================================================
--- head/sys/dev/rtwn/if_rtwn.c	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/if_rtwn.c	Tue Jan 17 00:35:23 2017	(r312315)
@@ -1999,6 +1999,7 @@ rtwn_stop(struct rtwn_softc *sc)
 	sc->fwver = 0;
 	sc->thcal_temp = 0;
 	sc->cur_bcnq_id = RTWN_VAP_ID_INVALID;
+	bzero(&sc->last_physt, sizeof(sc->last_physt));
 
 #ifdef D4054
 	ieee80211_tx_watchdog_stop(&sc->sc_ic);

Modified: head/sys/dev/rtwn/if_rtwn_rx.c
==============================================================================
--- head/sys/dev/rtwn/if_rtwn_rx.c	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/if_rtwn_rx.c	Tue Jan 17 00:35:23 2017	(r312315)
@@ -117,18 +117,19 @@ rtwn_set_basicrates(struct rtwn_softc *s
 }
 
 static void
-rtwn_update_avgrssi(struct rtwn_softc *sc, struct rtwn_node *un, int rate)
+rtwn_update_avgrssi(struct rtwn_softc *sc, struct rtwn_node *un, int8_t rssi,
+    int is_cck)
 {
 	int pwdb;
 
 	/* Convert antenna signal to percentage. */
-	if (un->last_rssi <= -100 || un->last_rssi >= 20)
+	if (rssi <= -100 || rssi >= 20)
 		pwdb = 0;
-	else if (un->last_rssi >= 0)
+	else if (rssi >= 0)
 		pwdb = 100;
 	else
-		pwdb = 100 + un->last_rssi;
-	if (RTWN_RATE_IS_CCK(rate)) {
+		pwdb = 100 + rssi;
+	if (is_cck) {
 		/* CCK gain is smaller than OFDM/MCS gain. */
 		pwdb += 6;
 		if (pwdb > 100)
@@ -155,11 +156,11 @@ rtwn_update_avgrssi(struct rtwn_softc *s
 }
 
 static int8_t
-rtwn_get_rssi(struct rtwn_softc *sc, int rate, void *physt)
+rtwn_get_rssi(struct rtwn_softc *sc, void *physt, int is_cck)
 {
 	int8_t rssi;
 
-	if (RTWN_RATE_IS_CCK(rate))
+	if (is_cck)
 		rssi = rtwn_get_rssi_cck(sc, physt);
 	else	/* OFDM/HT. */
 		rssi = rtwn_get_rssi_ofdm(sc, physt);
@@ -188,81 +189,133 @@ rtwn_get_tsf(struct rtwn_softc *sc, uint
 	*buf += rtwn_get_tsf_low(sc, id);
 }
 
+static uint64_t
+rtwn_extend_rx_tsf(struct rtwn_softc *sc, const struct r92c_rx_stat *stat)
+{
+	uint64_t tsft;
+	uint32_t rxdw3, tsfl, tsfl_curr;
+	int id;
+
+	rxdw3 = le32toh(stat->rxdw3);
+	tsfl = le32toh(stat->tsf_low);
+	id = MS(rxdw3, R92C_RXDW3_BSSID_FIT);
+
+	switch (id) {
+	case 1:
+	case 2:
+		id >>= 1;
+		tsfl_curr = rtwn_get_tsf_low(sc, id);
+		break;
+	default:
+	{
+		uint32_t tsfl0, tsfl1;
+
+		tsfl0 = rtwn_get_tsf_low(sc, 0);
+		tsfl1 = rtwn_get_tsf_low(sc, 1);
+
+		if (abs(tsfl0 - tsfl) < abs(tsfl1 - tsfl)) {
+			id = 0;
+			tsfl_curr = tsfl0;
+		} else {
+			id = 1;
+			tsfl_curr = tsfl1;
+		}
+		break;
+	}
+	}
+
+	tsft = rtwn_get_tsf_high(sc, id);
+	if (tsfl > tsfl_curr && tsfl > 0xffff0000)
+		tsft--;
+	tsft <<= 32;
+	tsft += tsfl;
+
+	return (tsft);
+}
+
 struct ieee80211_node *
-rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc,
-    int8_t *rssi)
+rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc)
 {
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ieee80211_node *ni;
 	struct ieee80211_frame_min *wh;
+	struct ieee80211_rx_stats rxs;
 	struct rtwn_node *un;
 	struct r92c_rx_stat *stat;
-	uint32_t rxdw0, rxdw3;
-	int cipher, infosz, pktlen, rate, shift;
+	void *physt;
+	uint32_t rxdw0;
+	int8_t rssi;
+	int cipher, infosz, is_cck, pktlen, shift;
 
 	stat = desc;
 	rxdw0 = le32toh(stat->rxdw0);
-	rxdw3 = le32toh(stat->rxdw3);
 
 	cipher = MS(rxdw0, R92C_RXDW0_CIPHER);
 	infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
 	pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
 	shift = MS(rxdw0, R92C_RXDW0_SHIFT);
-	rate = MS(rxdw3, R92C_RXDW3_RATE);
 
 	wh = (struct ieee80211_frame_min *)(mtodo(m, shift + infosz));
 	if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
 	    cipher != R92C_CAM_ALGO_NONE)
 		m->m_flags |= M_WEP;
 
-	if (pktlen >= sizeof(*wh))
+	if (pktlen >= sizeof(*wh)) {
 		ni = ieee80211_find_rxnode(ic, wh);
-	else
+		if (ni != NULL && (ni->ni_flags & IEEE80211_NODE_HT))
+			m->m_flags |= M_AMPDU;
+	} else
 		ni = NULL;
 	un = RTWN_NODE(ni);
 
-	/* Get RSSI from PHY status descriptor if present. */
-	if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
-		*rssi = rtwn_get_rssi(sc, rate, mtod(m, void *));
-		RTWN_DPRINTF(sc, RTWN_DEBUG_RSSI, "%s: rssi %d, ridx %d\n",
-		    __func__, *rssi, rate);
-
-		sc->last_rssi = *rssi;
-		if (un != NULL) {
-			un->last_rssi = *rssi;
+	if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST))
+		physt = (void *)mtodo(m, shift);
+	else
+		physt = (un != NULL) ? &un->last_physt : &sc->last_physt;
 
-			/* Update our average RSSI. */
-			rtwn_update_avgrssi(sc, un, rate);
-		}
-	} else
-		*rssi = (un != NULL) ? un->last_rssi : sc->last_rssi;
+	bzero(&rxs, sizeof(rxs));
+	rtwn_get_rx_stats(sc, &rxs, desc, physt);
+	if (rxs.c_pktflags & IEEE80211_RX_F_AMPDU) {
+		/* Next MPDU will come without PHY info. */
+		memcpy(&sc->last_physt, physt, sizeof(sc->last_physt));
+		if (un != NULL)
+			memcpy(&un->last_physt, physt, sizeof(sc->last_physt));
+	}
+
+	/* Add some common bits. */
+	/* NB: should not happen. */
+	if (rxdw0 & R92C_RXDW0_CRCERR)
+		rxs.c_pktflags |= IEEE80211_RX_F_FAIL_FCSCRC;
+
+	rxs.r_flags |= IEEE80211_R_TSF_START;	/* XXX undocumented */
+	rxs.r_flags |= IEEE80211_R_TSF64;
+	rxs.c_rx_tsf = rtwn_extend_rx_tsf(sc, stat);
+
+	/* Get RSSI from PHY status descriptor. */
+	is_cck = (rxs.c_pktflags & IEEE80211_RX_F_CCK) != 0;
+	rssi = rtwn_get_rssi(sc, physt, is_cck);
+
+	/* XXX TODO: we really need a rate-to-string method */
+	RTWN_DPRINTF(sc, RTWN_DEBUG_RSSI, "%s: rssi %d, rate %d\n",
+	    __func__, rssi, rxs.c_rate);
+	if (un != NULL && infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
+		/* Update our average RSSI. */
+		rtwn_update_avgrssi(sc, un, rssi, is_cck);
+	}
+
+	rxs.r_flags |= IEEE80211_R_NF | IEEE80211_R_RSSI;
+	rxs.c_nf = RTWN_NOISE_FLOOR;
+	rxs.c_rssi = rssi - rxs.c_nf;
+	(void) ieee80211_add_rx_params(m, &rxs);
 
 	if (ieee80211_radiotap_active(ic)) {
 		struct rtwn_rx_radiotap_header *tap = &sc->sc_rxtap;
-		int id = RTWN_VAP_ID_INVALID;
-
-		if (ni != NULL)
-			id = RTWN_VAP(ni->ni_vap)->id;
-		if (id == RTWN_VAP_ID_INVALID)
-			id = 0;
 
 		tap->wr_flags = rtwn_rx_radiotap_flags(sc, desc);
-		tap->wr_tsft = rtwn_get_tsf_high(sc, id);
-		if (le32toh(stat->tsf_low) > rtwn_get_tsf_low(sc, id))
-			tap->wr_tsft--;
-		tap->wr_tsft = (uint64_t)htole32(tap->wr_tsft) << 32;
-		tap->wr_tsft += stat->tsf_low;
-
-		/* XXX 20/40? */
-
-		/* Map HW rate index to 802.11 rate. */
-		if (rate < RTWN_RIDX_MCS(0))
-			tap->wr_rate = ridx2rate[rate];
-		else	/* MCS0~15. */
-			tap->wr_rate = IEEE80211_RATE_MCS | (rate - 12);
-
-		tap->wr_dbm_antsignal = *rssi;
-		tap->wr_dbm_antnoise = RTWN_NOISE_FLOOR;
+		tap->wr_tsft = htole64(rxs.c_rx_tsf);
+		tap->wr_rate = rxs.c_rate;
+		tap->wr_dbm_antsignal = rssi;
+		tap->wr_dbm_antnoise = rxs.c_nf;
 	}
 
 	/* Drop PHY descriptor. */

Modified: head/sys/dev/rtwn/if_rtwn_rx.h
==============================================================================
--- head/sys/dev/rtwn/if_rtwn_rx.h	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/if_rtwn_rx.h	Tue Jan 17 00:35:23 2017	(r312315)
@@ -26,7 +26,7 @@ void	rtwn_get_rates(struct rtwn_softc *,
 	    const struct ieee80211_htrateset *, uint32_t *, int *, int);
 void	rtwn_set_basicrates(struct rtwn_softc *, uint32_t);
 struct ieee80211_node *	rtwn_rx_common(struct rtwn_softc *, struct mbuf *,
-	    void *, int8_t *);
+	    void *);
 void	rtwn_adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
 	    const struct ieee80211_rx_stats *, int, int);
 void	rtwn_set_multi(struct rtwn_softc *);

Modified: head/sys/dev/rtwn/if_rtwnvar.h
==============================================================================
--- head/sys/dev/rtwn/if_rtwnvar.h	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/if_rtwnvar.h	Tue Jan 17 00:35:23 2017	(r312315)
@@ -76,6 +76,12 @@ struct rtwn_tx_buf {
 	uint8_t		txd[RTWN_TX_DESC_SIZE];
 } __attribute__((aligned(4)));
 
+#define RTWN_PHY_STATUS_SIZE	32
+struct rtwn_tx_phystat {
+	uint32_t	phydw[RTWN_PHY_STATUS_SIZE / sizeof(uint32_t)];
+};
+
+
 struct rtwn_softc;
 
 union sec_param {
@@ -95,7 +101,8 @@ struct rtwn_cmdq {
 struct rtwn_node {
 	struct ieee80211_node	ni;	/* must be the first */
 	int			id;
-	int8_t			last_rssi;
+
+	struct rtwn_tx_phystat	last_physt;
 	int			avg_pwdb;
 };
 #define RTWN_NODE(ni)		((struct rtwn_node *)(ni))
@@ -195,7 +202,7 @@ struct rtwn_softc {
 	const char		*name;
 	int			sc_ant;
 
-	int8_t			last_rssi;
+	struct rtwn_tx_phystat	last_physt;
 	uint8_t			thcal_temp;
 	int			cur_bcnq_id;
 
@@ -336,6 +343,9 @@ struct rtwn_softc {
 			    struct ieee80211vap *, int);
 	void		(*sc_set_rssi)(struct rtwn_softc *);
 #endif
+	void		(*sc_get_rx_stats)(struct rtwn_softc *,
+			    struct ieee80211_rx_stats *, const void *,
+			    const void *);
 	int8_t		(*sc_get_rssi_cck)(struct rtwn_softc *, void *);
 	int8_t		(*sc_get_rssi_ofdm)(struct rtwn_softc *, void *);
 	int		(*sc_classify_intr)(struct rtwn_softc *, void *, int);
@@ -478,6 +488,8 @@ void	rtwn_suspend(struct rtwn_softc *);
 	(((_sc)->sc_parse_rom)((_sc), (_rom)))
 #define rtwn_set_led(_sc, _led, _on) \
 	(((_sc)->sc_set_led)((_sc), (_led), (_on)))
+#define rtwn_get_rx_stats(_sc, _rxs, _desc, _physt) \
+	(((_sc)->sc_get_rx_stats((_sc), (_rxs), (_desc), (_physt))))
 #define rtwn_get_rssi_cck(_sc, _physt) \
 	(((_sc)->sc_get_rssi_cck)((_sc), (_physt)))
 #define rtwn_get_rssi_ofdm(_sc, _physt) \

Modified: head/sys/dev/rtwn/pci/rtwn_pci_rx.c
==============================================================================
--- head/sys/dev/rtwn/pci/rtwn_pci_rx.c	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/pci/rtwn_pci_rx.c	Tue Jan 17 00:35:23 2017	(r312315)
@@ -95,7 +95,6 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc,
 	struct ieee80211_node *ni;
 	uint32_t rxdw0;
 	struct mbuf *m, *m1;
-	int8_t rssi = 0, nf;
 	int infosz, pktlen, shift, error;
 
 	/* Dump Rx descriptor. */
@@ -162,12 +161,11 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc,
 	rx_data->m = m1;
 	m->m_pkthdr.len = m->m_len = pktlen + infosz + shift;
 
-	nf = RTWN_NOISE_FLOOR;
-	ni = rtwn_rx_common(sc, m, rx_desc, &rssi);
+	ni = rtwn_rx_common(sc, m, rx_desc);
 
 	RTWN_DPRINTF(sc, RTWN_DEBUG_RECV,
-	    "%s: Rx frame len %d, infosz %d, shift %d, rssi %d\n",
-	    __func__, pktlen, infosz, shift, rssi);
+	    "%s: Rx frame len %d, infosz %d, shift %d\n",
+	    __func__, pktlen, infosz, shift);
 
 	/* Update RX descriptor. */
 	rtwn_pci_setup_rx_desc(pc, rx_desc, rx_data->paddr, MJUMPAGESIZE,
@@ -176,11 +174,11 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc,
 	/* Send the frame to the 802.11 layer. */
 	RTWN_UNLOCK(sc);
 	if (ni != NULL) {
-		(void)ieee80211_input(ni, m, rssi - nf, nf);
+		(void)ieee80211_input_mimo(ni, m);
 		/* Node is no longer needed. */
 		ieee80211_free_node(ni);
 	} else
-		(void)ieee80211_input_all(ic, m, rssi - nf, nf);
+		(void)ieee80211_input_mimo_all(ic, m);
 
 	RTWN_LOCK(sc);
 

Modified: head/sys/dev/rtwn/rtl8188e/r88e.h
==============================================================================
--- head/sys/dev/rtwn/rtl8188e/r88e.h	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8188e/r88e.h	Tue Jan 17 00:35:23 2017	(r312315)
@@ -85,6 +85,8 @@ void	r88e_ratectl_tx_complete(struct rtw
 void	r88e_handle_c2h_report(struct rtwn_softc *, uint8_t *, int);
 int8_t	r88e_get_rssi_cck(struct rtwn_softc *, void *);
 int8_t	r88e_get_rssi_ofdm(struct rtwn_softc *, void *);
+void	r88e_get_rx_stats(struct rtwn_softc *, struct ieee80211_rx_stats *,
+	    const void *, const void *);
 
 /* r88e_tx.c */
 void	r88e_tx_enable_ampdu(void *, int);

Modified: head/sys/dev/rtwn/rtl8188e/r88e_rx.c
==============================================================================
--- head/sys/dev/rtwn/rtl8188e/r88e_rx.c	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8188e/r88e_rx.c	Tue Jan 17 00:35:23 2017	(r312315)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/rtwn/if_rtwn_debug.h>
 #include <dev/rtwn/if_rtwn_ridx.h>
 
+#include <dev/rtwn/rtl8192c/r92c.h>
 #include <dev/rtwn/rtl8188e/r88e.h>
 #include <dev/rtwn/rtl8188e/r88e_rx_desc.h>
 
@@ -209,3 +210,19 @@ r88e_get_rssi_ofdm(struct rtwn_softc *sc
 
 	return (rssi);
 }
+
+void
+r88e_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
+    const void *desc, const void *physt_ptr)
+{
+	const struct r88e_rx_phystat *physt = physt_ptr;
+
+	r92c_get_rx_stats(sc, rxs, desc, physt_ptr);
+
+	if (!sc->sc_ht40) {	/* XXX center channel */
+		rxs->r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
+		rxs->c_ieee = le16toh(physt->chan);
+		rxs->c_freq = ieee80211_ieee2mhz(rxs->c_ieee,
+		    IEEE80211_CHAN_2GHZ);
+	}
+}

Modified: head/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
==============================================================================
--- head/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c	Tue Jan 17 00:35:23 2017	(r312315)
@@ -127,6 +127,7 @@ r88eu_attach(struct rtwn_usb_softc *uc)
 	sc->sc_dump_tx_desc		= r92cu_dump_tx_desc;
 	sc->sc_tx_radiotap_flags	= r92c_tx_radiotap_flags;
 	sc->sc_rx_radiotap_flags	= r92c_rx_radiotap_flags;
+	sc->sc_get_rx_stats		= r88e_get_rx_stats;
 	sc->sc_get_rssi_cck		= r88e_get_rssi_cck;
 	sc->sc_get_rssi_ofdm		= r88e_get_rssi_ofdm;
 	sc->sc_classify_intr		= r88eu_classify_intr;

Modified: head/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
==============================================================================
--- head/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c	Tue Jan 17 00:35:23 2017	(r312315)
@@ -172,6 +172,7 @@ r92ce_attach(struct rtwn_pci_softc *pc)
 	sc->sc_dump_tx_desc		= r92ce_dump_tx_desc;
 	sc->sc_tx_radiotap_flags	= r92c_tx_radiotap_flags;
 	sc->sc_rx_radiotap_flags	= r92c_rx_radiotap_flags;
+	sc->sc_get_rx_stats		= r92c_get_rx_stats;
 	sc->sc_get_rssi_cck		= r92c_get_rssi_cck;
 	sc->sc_get_rssi_ofdm		= r92c_get_rssi_ofdm;
 	sc->sc_classify_intr		= r92ce_classify_intr;

Modified: head/sys/dev/rtwn/rtl8192c/r92c.h
==============================================================================
--- head/sys/dev/rtwn/rtl8192c/r92c.h	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8192c/r92c.h	Tue Jan 17 00:35:23 2017	(r312315)
@@ -99,6 +99,8 @@ void	r92c_parse_rom(struct rtwn_softc *,
 int8_t	r92c_get_rssi_cck(struct rtwn_softc *, void *);
 int8_t	r92c_get_rssi_ofdm(struct rtwn_softc *, void *);
 uint8_t	r92c_rx_radiotap_flags(const void *);
+void	r92c_get_rx_stats(struct rtwn_softc *, struct ieee80211_rx_stats *,
+	    const void *, const void *);
 
 /* r92c_tx.c */
 void	r92c_tx_enable_ampdu(void *, int);

Modified: head/sys/dev/rtwn/rtl8192c/r92c_reg.h
==============================================================================
--- head/sys/dev/rtwn/rtl8192c/r92c_reg.h	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8192c/r92c_reg.h	Tue Jan 17 00:35:23 2017	(r312315)
@@ -420,6 +420,7 @@
 #define R92C_PBP_1024		4
 
 /* Bits for R92C_TRXDMA_CTRL. */
+#define R92C_TRXDMA_CTRL_RX_SHIFT_EN		0x0002
 #define R92C_TRXDMA_CTRL_RXDMA_AGG_EN		0x0004
 #define R92C_TRXDMA_CTRL_TXDMA_VOQ_MAP_M	0x0030
 #define R92C_TRXDMA_CTRL_TXDMA_VOQ_MAP_S	4
@@ -593,7 +594,8 @@
 #define R92C_RCR_APPFCS		0x80000000
 
 /* Bits for R92C_RX_DRVINFO_SZ. */
-#define R92C_RX_DRVINFO_SZ_DEF	4	/* XXX other values will not work */
+/* XXX other values will not work */
+#define R92C_RX_DRVINFO_SZ_DEF	((RTWN_PHY_STATUS_SIZE) / 8)
 
 /* Bits for R92C_WMAC_TRXPTCL_CTL. */
 #define R92C_WMAC_TRXPTCL_SHPRE	0x00020000

Modified: head/sys/dev/rtwn/rtl8192c/r92c_rx.c
==============================================================================
--- head/sys/dev/rtwn/rtl8192c/r92c_rx.c	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8192c/r92c_rx.c	Tue Jan 17 00:35:23 2017	(r312315)
@@ -100,3 +100,47 @@ r92c_rx_radiotap_flags(const void *buf)
 		flags = IEEE80211_RADIOTAP_F_SHORTGI;
 	return (flags);
 }
+
+void
+r92c_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
+    const void *desc, const void *physt_ptr)
+{
+	const struct r92c_rx_stat *stat = desc;
+	uint32_t rxdw1, rxdw3;
+	uint8_t rate;
+
+	rxdw1 = le32toh(stat->rxdw1);
+	rxdw3 = le32toh(stat->rxdw3);
+	rate = MS(rxdw3, R92C_RXDW3_RATE);
+
+	if (rxdw1 & R92C_RXDW1_AMPDU)
+		rxs->c_pktflags |= IEEE80211_RX_F_AMPDU;
+	else if (rxdw1 & R92C_RXDW1_AMPDU_MORE)
+		rxs->c_pktflags |= IEEE80211_RX_F_AMPDU_MORE;
+	if ((rxdw3 & R92C_RXDW3_SPLCP) && rate >= RTWN_RIDX_MCS(0))
+		rxs->c_pktflags |= IEEE80211_RX_F_SHORTGI;
+
+	if (rxdw3 & R92C_RXDW3_HT40)
+		rxs->c_width = IEEE80211_RX_FW_40MHZ;
+	else
+		rxs->c_width = IEEE80211_RX_FW_20MHZ;
+
+	if (RTWN_RATE_IS_CCK(rate))
+		rxs->c_phytype = IEEE80211_RX_FP_11B;
+	else if (rate < RTWN_RIDX_MCS(0))
+		rxs->c_phytype = IEEE80211_RX_FP_11G;
+	else
+		rxs->c_phytype = IEEE80211_RX_FP_11NG;
+
+	/* Map HW rate index to 802.11 rate. */
+	if (rate < RTWN_RIDX_MCS(0)) {
+		rxs->c_rate = ridx2rate[rate];
+		if (RTWN_RATE_IS_CCK(rate))
+			rxs->c_pktflags |= IEEE80211_RX_F_CCK;
+		else
+			rxs->c_pktflags |= IEEE80211_RX_F_OFDM;
+	} else {	/* MCS0~15. */
+		rxs->c_rate = IEEE80211_RATE_MCS | (rate - 12);
+		rxs->c_pktflags |= IEEE80211_RX_F_HT;
+	}
+}

Modified: head/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h
==============================================================================
--- head/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h	Tue Jan 17 00:35:23 2017	(r312315)
@@ -45,6 +45,9 @@ struct r92c_rx_stat {
 	uint32_t	rxdw1;
 #define R92C_RXDW1_MACID_M	0x0000001f
 #define R92C_RXDW1_MACID_S	0
+#define R92C_RXDW1_AMSDU	0x00002000
+#define R92C_RXDW1_AMPDU_MORE	0x00004000
+#define R92C_RXDW1_AMPDU	0x00008000
 #define R92C_RXDW1_MC		0x40000000
 #define R92C_RXDW1_BC		0x80000000
 
@@ -56,6 +59,8 @@ struct r92c_rx_stat {
 #define R92C_RXDW3_SPLCP	0x00000100
 #define R92C_RXDW3_HT40		0x00000200
 #define R92C_RXDW3_HTC		0x00000400
+#define R92C_RXDW3_BSSID_FIT_M	0x00003000
+#define R92C_RXDW3_BSSID_FIT_S	12
 
 	uint32_t	rxdw4;
 	uint32_t	tsf_low;

Modified: head/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
==============================================================================
--- head/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c	Tue Jan 17 00:35:23 2017	(r312315)
@@ -165,6 +165,7 @@ r92cu_attach(struct rtwn_usb_softc *uc)
 	sc->sc_dump_tx_desc		= r92cu_dump_tx_desc;
 	sc->sc_tx_radiotap_flags	= r92c_tx_radiotap_flags;
 	sc->sc_rx_radiotap_flags	= r92c_rx_radiotap_flags;
+	sc->sc_get_rx_stats		= r92c_get_rx_stats;
 	sc->sc_get_rssi_cck		= r92c_get_rssi_cck;
 	sc->sc_get_rssi_ofdm		= r92c_get_rssi_ofdm;
 	sc->sc_classify_intr		= r92cu_classify_intr;

Modified: head/sys/dev/rtwn/rtl8812a/r12a.h
==============================================================================
--- head/sys/dev/rtwn/rtl8812a/r12a.h	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8812a/r12a.h	Tue Jan 17 00:35:23 2017	(r312315)
@@ -128,6 +128,8 @@ void	r12a_ratectl_tx_complete(struct rtw
 void	r12a_handle_c2h_report(struct rtwn_softc *, uint8_t *, int);
 int	r12a_check_frame_checksum(struct rtwn_softc *, struct mbuf *);
 uint8_t	r12a_rx_radiotap_flags(const void *);
+void	r12a_get_rx_stats(struct rtwn_softc *, struct ieee80211_rx_stats *,
+	    const void *, const void *);
 
 /* r12a_tx.c */
 void	r12a_fill_tx_desc(struct rtwn_softc *, struct ieee80211_node *,

Modified: head/sys/dev/rtwn/rtl8812a/r12a_rx.c
==============================================================================
--- head/sys/dev/rtwn/rtl8812a/r12a_rx.c	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8812a/r12a_rx.c	Tue Jan 17 00:35:23 2017	(r312315)
@@ -229,10 +229,97 @@ r12a_rx_radiotap_flags(const void *buf)
 
 	if (!(stat->rxdw4 & htole32(R12A_RXDW4_SPLCP)))
 		return (0);
-	rate = MS(le32toh(stat->rxdw3), R92C_RXDW3_RATE);
+	rate = MS(le32toh(stat->rxdw3), R12A_RXDW3_RATE);
 	if (RTWN_RATE_IS_CCK(rate))
 		flags = IEEE80211_RADIOTAP_F_SHORTPRE;
 	else
 		flags = IEEE80211_RADIOTAP_F_SHORTGI;
 	return (flags);
 }
+
+void
+r12a_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
+    const void *desc, const void *physt_ptr)
+{
+	const struct r92c_rx_stat *stat = desc;
+	const struct r12a_rx_phystat *physt = physt_ptr;
+	uint32_t rxdw0, rxdw1, rxdw3, rxdw4;
+	uint8_t rate;
+
+	rxdw0 = le32toh(stat->rxdw0);
+	rxdw1 = le32toh(stat->rxdw1);
+	rxdw3 = le32toh(stat->rxdw3);
+	rxdw4 = le32toh(stat->rxdw4);
+	rate = MS(rxdw3, R12A_RXDW3_RATE);
+
+	/* TODO: STBC, LDPC */
+	if (rxdw1 & R12A_RXDW1_AMPDU) {
+		if (rxdw0 & R92C_RXDW0_PHYST)
+			rxs->c_pktflags |= IEEE80211_RX_F_AMPDU;
+		else
+			rxs->c_pktflags |= IEEE80211_RX_F_AMPDU_MORE;
+	}
+
+	if ((rxdw4 & R12A_RXDW4_SPLCP) && rate >= RTWN_RIDX_MCS(0))
+		rxs->c_pktflags |= IEEE80211_RX_F_SHORTGI;
+
+	switch (MS(rxdw4, R12A_RXDW4_BW)) {
+	case R12A_RXDW4_BW20:
+		rxs->c_width = IEEE80211_RX_FW_20MHZ;
+		break;
+	case R12A_RXDW4_BW40:
+		rxs->c_width = IEEE80211_RX_FW_40MHZ;
+		break;
+	case R12A_RXDW4_BW80:
+		rxs->c_width = IEEE80211_RX_FW_80MHZ;
+		break;
+	default:
+		break;
+	}
+
+	if (RTWN_RATE_IS_CCK(rate))
+		rxs->c_phytype = IEEE80211_RX_FP_11B;
+	else {
+		int is5ghz;
+
+		/* XXX magic */
+		/* XXX check with RTL8812AU */
+		is5ghz = (physt->cfosho[2] != 0x01);
+
+		if (rate < RTWN_RIDX_MCS(0)) {
+			if (is5ghz)
+				rxs->c_phytype = IEEE80211_RX_FP_11A;
+			else
+				rxs->c_phytype = IEEE80211_RX_FP_11G;
+		} else {
+			if (is5ghz)
+				rxs->c_phytype = IEEE80211_RX_FP_11NA;
+			else
+				rxs->c_phytype = IEEE80211_RX_FP_11NG;
+		}
+	}
+
+	/* Map HW rate index to 802.11 rate. */
+	if (rate < RTWN_RIDX_MCS(0)) {
+		rxs->c_rate = ridx2rate[rate];
+		if (RTWN_RATE_IS_CCK(rate))
+			rxs->c_pktflags |= IEEE80211_RX_F_CCK;
+		else
+			rxs->c_pktflags |= IEEE80211_RX_F_OFDM;
+	} else {	/* MCS0~15. */
+		/* TODO: VHT rates */
+		rxs->c_rate = IEEE80211_RATE_MCS | (rate - 12);
+		rxs->c_pktflags |= IEEE80211_RX_F_HT;
+	}
+
+	/*
+	 * XXX always zero for RTL8821AU
+	 * (vendor driver does not check this field)
+	 */
+#if 0
+	rxs->r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
+	rxs->c_ieee = MS(le16toh(physt->phyw1), R12A_PHYW1_CHAN);
+	rxs->c_freq = ieee80211_ieee2mhz(rxs->c_ieee,
+	    (rxs->c_ieee < 36) ? IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ);
+#endif
+}

Modified: head/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h
==============================================================================
--- head/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h	Tue Jan 17 00:35:23 2017	(r312315)
@@ -34,18 +34,26 @@
 /* Rx MAC descriptor defines (chip-specific). */
 /* Rx dword 1 */
 #define R12A_RXDW1_AMSDU	0x00002000
+#define R12A_RXDW1_AMPDU	0x00008000
 #define R12A_RXDW1_CKSUM_ERR	0x00100000
 #define R12A_RXDW1_IPV6		0x00200000
 #define R12A_RXDW1_UDP		0x00400000
 #define R12A_RXDW1_CKSUM	0x00800000
 /* Rx dword 2 */
 #define R12A_RXDW2_RPT_C2H	0x10000000
+/* Rx dword 3 */
+#define R12A_RXDW3_RATE_M	0x0000007f
+#define R12A_RXDW3_RATE_S	0
 /* Rx dword 4 */
 #define R12A_RXDW4_SPLCP	0x00000001
 #define R12A_RXDW4_LDPC		0x00000002
 #define R12A_RXDW4_STBC		0x00000004
 #define R12A_RXDW4_BW_M		0x00000030
 #define R12A_RXDW4_BW_S		4
+#define R12A_RXDW4_BW20		0
+#define R12A_RXDW4_BW40		1
+#define R12A_RXDW4_BW80		2
+#define R12A_RXDW4_BW160	3
 
 /* Rx PHY descriptor. */
 struct r12a_rx_phystat {

Modified: head/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
==============================================================================
--- head/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c	Tue Jan 17 00:35:23 2017	(r312315)
@@ -190,6 +190,7 @@ r12au_attach(struct rtwn_usb_softc *uc)
 	sc->sc_dump_tx_desc		= r12au_dump_tx_desc;
 	sc->sc_tx_radiotap_flags	= r12a_tx_radiotap_flags;
 	sc->sc_rx_radiotap_flags	= r12a_rx_radiotap_flags;
+	sc->sc_get_rx_stats		= r12a_get_rx_stats;
 	sc->sc_get_rssi_cck		= r88e_get_rssi_cck;
 	sc->sc_get_rssi_ofdm		= r88e_get_rssi_ofdm;
 	sc->sc_classify_intr		= r12au_classify_intr;

Modified: head/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
==============================================================================
--- head/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c	Tue Jan 17 00:35:23 2017	(r312315)
@@ -182,6 +182,7 @@ r21au_attach(struct rtwn_usb_softc *uc)
 	sc->sc_dump_tx_desc		= r12au_dump_tx_desc;
 	sc->sc_tx_radiotap_flags	= r12a_tx_radiotap_flags;
 	sc->sc_rx_radiotap_flags	= r12a_rx_radiotap_flags;
+	sc->sc_get_rx_stats		= r12a_get_rx_stats;
 	sc->sc_get_rssi_cck		= r21a_get_rssi_cck;
 	sc->sc_get_rssi_ofdm		= r88e_get_rssi_ofdm;
 	sc->sc_classify_intr		= r12au_classify_intr;

Modified: head/sys/dev/rtwn/usb/rtwn_usb_rx.c
==============================================================================
--- head/sys/dev/rtwn/usb/rtwn_usb_rx.c	Mon Jan 16 20:57:01 2017	(r312314)
+++ head/sys/dev/rtwn/usb/rtwn_usb_rx.c	Tue Jan 17 00:35:23 2017	(r312315)
@@ -236,7 +236,7 @@ rtwn_report_intr(struct rtwn_usb_softc *
 }
 
 static struct ieee80211_node *
-rtwn_rx_frame(struct rtwn_softc *sc, struct mbuf *m, int8_t *rssi)
+rtwn_rx_frame(struct rtwn_softc *sc, struct mbuf *m)
 {
 	struct r92c_rx_stat stat;
 
@@ -244,7 +244,7 @@ rtwn_rx_frame(struct rtwn_softc *sc, str
 	m_copydata(m, 0, sizeof(struct r92c_rx_stat), (caddr_t)&stat);
 	m_adj(m, sizeof(struct r92c_rx_stat));
 
-	return (rtwn_rx_common(sc, m, &stat, rssi));
+	return (rtwn_rx_common(sc, m, &stat));
 }
 
 void
@@ -256,7 +256,6 @@ rtwn_bulk_rx_callback(struct usb_xfer *x
 	struct ieee80211_node *ni;
 	struct mbuf *m = NULL, *next;
 	struct rtwn_data *data;
-	int8_t nf, rssi;
 
 	RTWN_ASSERT_LOCKED(sc);
 
@@ -291,19 +290,15 @@ tr_setup:
 			next = m->m_next;
 			m->m_next = NULL;
 
-			ni = rtwn_rx_frame(sc, m, &rssi);
+			ni = rtwn_rx_frame(sc, m);
 
 			RTWN_UNLOCK(sc);
 
-			nf = RTWN_NOISE_FLOOR;
 			if (ni != NULL) {
-				if (ni->ni_flags & IEEE80211_NODE_HT)
-					m->m_flags |= M_AMPDU;
-				(void)ieee80211_input(ni, m, rssi - nf, nf);
+				(void)ieee80211_input_mimo(ni, m);
 				ieee80211_free_node(ni);
 			} else {
-				(void)ieee80211_input_all(ic, m,
-				    rssi - nf, nf);
+				(void)ieee80211_input_mimo_all(ic, m);
 			}
 			RTWN_LOCK(sc);
 			m = next;



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