svn commit: r308356 - in head/sys/dev/rtwn: . rtl8812a

Andriy Voskoboinyk avos at FreeBSD.org
Sat Nov 5 23:21:32 UTC 2016


Author: avos
Date: Sat Nov  5 23:21:30 2016
New Revision: 308356
URL: https://svnweb.freebsd.org/changeset/base/308356

Log:
  rtwn: fix Rx filter setup for some multi-vap configuratons.
  
  - Correctly refresh Rx filter when AP (IBSS) vap is created after STA vap.
  - Block any RCR updates during TSF correction (IBSS mode).
  - Set CBSSID* bits during vap creation, not when it was started / stopped.
  - Cache current state to prevent unnecessary register reads.
  
  Tested with RTL8188CE, STA + AP mode.

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/rtl8812a/r12a_caps.c

Modified: head/sys/dev/rtwn/if_rtwn.c
==============================================================================
--- head/sys/dev/rtwn/if_rtwn.c	Sat Nov  5 22:47:09 2016	(r308355)
+++ head/sys/dev/rtwn/if_rtwn.c	Sat Nov  5 23:21:30 2016	(r308356)
@@ -917,6 +917,9 @@ rtwn_tsf_sync_adhoc_task(void *arg, int 
 	/* Accept beacons with the same BSSID. */
 	rtwn_set_rx_bssid_all(sc, 0);
 
+	/* Deny RCR updates. */
+	sc->sc_flags |= RTWN_RCR_LOCKED;
+
 	/* Enable synchronization. */
 	rtwn_setbits_1(sc, R92C_BCN_CTRL(uvp->id),
 	    R92C_BCN_CTRL_DIS_TSF_UDT0, 0);
@@ -929,6 +932,7 @@ rtwn_tsf_sync_adhoc_task(void *arg, int 
 	    0, R92C_BCN_CTRL_DIS_TSF_UDT0);
 
 	/* Accept all beacons. */
+	sc->sc_flags &= ~RTWN_RCR_LOCKED;
 	rtwn_set_rx_bssid_all(sc, 1);
 
 	/* Schedule next TSF synchronization. */
@@ -1193,7 +1197,6 @@ rtwn_run(struct rtwn_softc *sc, struct i
 	struct ieee80211com *ic = vap->iv_ic;
 	struct rtwn_vap *uvp = RTWN_VAP(vap);
 	struct ieee80211_node *ni;
-	uint32_t reg;
 	uint8_t mode;
 	int error;
 
@@ -1246,18 +1249,6 @@ rtwn_run(struct rtwn_softc *sc, struct i
 		rtwn_write_1(sc, R92C_TXPAUSE, 0);
 	}
 
-	/* Allow Rx from our BSSID only. */
-	if (ic->ic_promisc == 0) {
-		reg = rtwn_read_4(sc, R92C_RCR);
-
-		if (sc->bcn_vaps == 0)
-			reg |= R92C_RCR_CBSSID_BCN;
-		if (sc->ap_vaps == 0)
-			reg |= R92C_RCR_CBSSID_DATA;
-
-		rtwn_write_4(sc, R92C_RCR, reg);
-	}
-
 #ifndef RTWN_WITHOUT_UCODE
 	/* Upload (QoS) Null Data frame to firmware. */
 	/* Note: do this for port 0 only. */

Modified: head/sys/dev/rtwn/if_rtwn_rx.c
==============================================================================
--- head/sys/dev/rtwn/if_rtwn_rx.c	Sat Nov  5 22:47:09 2016	(r308355)
+++ head/sys/dev/rtwn/if_rtwn_rx.c	Sat Nov  5 23:21:30 2016	(r308356)
@@ -362,7 +362,7 @@ rtwn_rxfilter_update_mgt(struct rtwn_sof
 {
 	uint16_t filter;
 
-	filter = 0x7f3f;
+	filter = 0x7f7f;
 	if (sc->bcn_vaps == 0) {	/* STA and/or MONITOR mode vaps */
 		filter &= ~(
 		    R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_ASSOC_REQ) |
@@ -393,7 +393,6 @@ rtwn_rxfilter_update(struct rtwn_softc *
 void
 rtwn_rxfilter_init(struct rtwn_softc *sc)
 {
-	uint32_t rcr;
 
 	RTWN_ASSERT_LOCKED(sc);
 
@@ -406,47 +405,60 @@ rtwn_rxfilter_init(struct rtwn_softc *sc
 	/* Reject all data frames. */
 	rtwn_write_2(sc, R92C_RXFLTMAP2, 0x0000);
 
-	rcr = sc->rcr;
-	rcr |= R92C_RCR_AM | R92C_RCR_AB | R92C_RCR_APM |
-	       R92C_RCR_HTC_LOC_CTRL | R92C_RCR_APP_PHYSTS |
-	       R92C_RCR_APP_ICV | R92C_RCR_APP_MIC;
-
-	/* Set Rx filter. */
-	rtwn_write_4(sc, R92C_RCR, rcr);
+	/* Append generic Rx filter bits. */
+	sc->rcr |= R92C_RCR_AM | R92C_RCR_AB | R92C_RCR_APM |
+	    R92C_RCR_HTC_LOC_CTRL | R92C_RCR_APP_PHYSTS |
+	    R92C_RCR_APP_ICV | R92C_RCR_APP_MIC;
 
 	/* Update dynamic Rx filter parts. */
 	rtwn_rxfilter_update(sc);
 }
 
 void
+rtwn_rxfilter_set(struct rtwn_softc *sc)
+{
+	if (!(sc->sc_flags & RTWN_RCR_LOCKED))
+		rtwn_write_4(sc, R92C_RCR, sc->rcr);
+}
+
+void
 rtwn_set_rx_bssid_all(struct rtwn_softc *sc, int enable)
 {
+
 	if (enable)
-		rtwn_setbits_4(sc, R92C_RCR, R92C_RCR_CBSSID_BCN, 0);
+		sc->rcr &= ~R92C_RCR_CBSSID_BCN;
 	else
-		rtwn_setbits_4(sc, R92C_RCR, 0, R92C_RCR_CBSSID_BCN);
+		sc->rcr |= R92C_RCR_CBSSID_BCN;
+	rtwn_rxfilter_set(sc);
 }
 
 void
 rtwn_set_promisc(struct rtwn_softc *sc)
 {
 	struct ieee80211com *ic = &sc->sc_ic;
-	uint32_t mask1, mask2;
+	uint32_t mask_all, mask_min;
 
 	RTWN_ASSERT_LOCKED(sc);
 
-	mask1 = R92C_RCR_ACF | R92C_RCR_ADF | R92C_RCR_AMF | R92C_RCR_AAP;
-	mask2 = R92C_RCR_APM;
+	mask_all = R92C_RCR_ACF | R92C_RCR_ADF | R92C_RCR_AMF | R92C_RCR_AAP;
+	mask_min = R92C_RCR_APM;
 
-	if (sc->vaps_running != 0) {
-		if (sc->bcn_vaps == 0)
-			mask2 |= R92C_RCR_CBSSID_BCN;
-		if (sc->ap_vaps == 0)
-			mask2 |= R92C_RCR_CBSSID_DATA;
+	if (sc->bcn_vaps == 0)
+		mask_min |= R92C_RCR_CBSSID_BCN;
+	if (sc->ap_vaps == 0)
+		mask_min |= R92C_RCR_CBSSID_DATA;
+
+	if (ic->ic_promisc == 0 && sc->mon_vaps == 0) {
+		if (sc->bcn_vaps != 0)
+			mask_all |= R92C_RCR_CBSSID_BCN;
+		if (sc->ap_vaps != 0)	/* for Null data frames */
+			mask_all |= R92C_RCR_CBSSID_DATA;
+
+		sc->rcr &= ~mask_all;
+		sc->rcr |= mask_min;
+	} else {
+		sc->rcr &= ~mask_min;
+		sc->rcr |= mask_all;
 	}
-
-	if (ic->ic_promisc == 0 && sc->mon_vaps == 0)
-		rtwn_setbits_4(sc, R92C_RCR, mask1, mask2);
-	else
-		rtwn_setbits_4(sc, R92C_RCR, mask2, mask1);
+	rtwn_rxfilter_set(sc);
 }

Modified: head/sys/dev/rtwn/if_rtwn_rx.h
==============================================================================
--- head/sys/dev/rtwn/if_rtwn_rx.h	Sat Nov  5 22:47:09 2016	(r308355)
+++ head/sys/dev/rtwn/if_rtwn_rx.h	Sat Nov  5 23:21:30 2016	(r308356)
@@ -32,6 +32,7 @@ void	rtwn_adhoc_recv_mgmt(struct ieee802
 void	rtwn_set_multi(struct rtwn_softc *);
 void	rtwn_rxfilter_update(struct rtwn_softc *);
 void	rtwn_rxfilter_init(struct rtwn_softc *);
+void	rtwn_rxfilter_set(struct rtwn_softc *);
 void	rtwn_set_rx_bssid_all(struct rtwn_softc *, int);
 void	rtwn_set_promisc(struct rtwn_softc *);
 

Modified: head/sys/dev/rtwn/if_rtwnvar.h
==============================================================================
--- head/sys/dev/rtwn/if_rtwnvar.h	Sat Nov  5 22:47:09 2016	(r308355)
+++ head/sys/dev/rtwn/if_rtwnvar.h	Sat Nov  5 23:21:30 2016	(r308356)
@@ -186,6 +186,7 @@ struct rtwn_softc {
 #define RTWN_RUNNING		0x10
 #define RTWN_FW_LOADED		0x20
 #define RTWN_TEMP_MEASURED	0x40
+#define RTWN_RCR_LOCKED		0x80
 
 #define RTWN_CHIP_HAS_BCNQ1(_sc)	\
 	((_sc)->bcn_status_reg[0] != (_sc)->bcn_status_reg[1])

Modified: head/sys/dev/rtwn/rtl8812a/r12a_caps.c
==============================================================================
--- head/sys/dev/rtwn/rtl8812a/r12a_caps.c	Sat Nov  5 22:47:09 2016	(r308355)
+++ head/sys/dev/rtwn/rtl8812a/r12a_caps.c	Sat Nov  5 23:21:30 2016	(r308356)
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
 #include <net80211/ieee80211_radiotap.h>
 
 #include <dev/rtwn/if_rtwnvar.h>
+#include <dev/rtwn/if_rtwn_rx.h>
 
 #include <dev/rtwn/rtl8812a/r12a.h>
 #include <dev/rtwn/rtl8812a/r12a_reg.h>
@@ -89,19 +90,13 @@ r12a_ioctl_net(struct ieee80211com *ic, 
 			changed = 1;
 		}
 		if (changed) {
-			if (rxmask == 0) {
+			if (rxmask == 0)
 				sc->rcr &= ~R12A_RCR_TCP_OFFLD_EN;
-				if (sc->sc_flags & RTWN_RUNNING) {
-					rtwn_setbits_4(sc, R92C_RCR,
-					    R12A_RCR_TCP_OFFLD_EN, 0);
-				}
-			} else {
+			else
 				sc->rcr |= R12A_RCR_TCP_OFFLD_EN;
-				if (sc->sc_flags & RTWN_RUNNING) {
-					rtwn_setbits_4(sc, R92C_RCR,
-					    0, R12A_RCR_TCP_OFFLD_EN);
-				}
-			}
+
+			if (sc->sc_flags & RTWN_RUNNING)
+				rtwn_rxfilter_set(sc);
 		}
 		RTWN_UNLOCK(sc);
 


More information about the svn-src-all mailing list