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.
This commit is contained in:
parent
c4e33680f3
commit
c50d154a5f
@ -917,6 +917,9 @@ rtwn_tsf_sync_adhoc_task(void *arg, int pending)
|
||||
/* 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 pending)
|
||||
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 ieee80211vap *vap)
|
||||
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 ieee80211vap *vap)
|
||||
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. */
|
||||
|
@ -362,7 +362,7 @@ rtwn_rxfilter_update_mgt(struct rtwn_softc *sc)
|
||||
{
|
||||
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 *sc)
|
||||
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);
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ void rtwn_adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
|
||||
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 *);
|
||||
|
||||
|
@ -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])
|
||||
|
@ -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, u_long cmd, void *data)
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user