From owner-svn-src-all@freebsd.org Sun Nov 8 23:21:56 2015 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 3B5E2A2A419; Sun, 8 Nov 2015 23:21:56 +0000 (UTC) (envelope-from avos@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 10EBB14BD; Sun, 8 Nov 2015 23:21:55 +0000 (UTC) (envelope-from avos@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id tA8NLthB042007; Sun, 8 Nov 2015 23:21:55 GMT (envelope-from avos@FreeBSD.org) Received: (from avos@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id tA8NLsHq042005; Sun, 8 Nov 2015 23:21:54 GMT (envelope-from avos@FreeBSD.org) Message-Id: <201511082321.tA8NLsHq042005@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avos set sender to avos@FreeBSD.org using -f From: Andriy Voskoboinyk Date: Sun, 8 Nov 2015 23:21:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r290564 - head/sys/dev/usb/wlan 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.20 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: Sun, 08 Nov 2015 23:21:56 -0000 Author: avos Date: Sun Nov 8 23:21:54 2015 New Revision: 290564 URL: https://svnweb.freebsd.org/changeset/base/290564 Log: urtwn(4): improve RX filter. - Filter out unneeded frames in STA mode. - Implement ic_promisc() call. Tested with RTL8188EU, STA and MONITOR modes. Reviewed by: kevlo Approved by: adrian (mentor) Differential Revision: https://reviews.freebsd.org/D3999 Modified: head/sys/dev/usb/wlan/if_urtwn.c head/sys/dev/usb/wlan/if_urtwnreg.h Modified: head/sys/dev/usb/wlan/if_urtwn.c ============================================================================== --- head/sys/dev/usb/wlan/if_urtwn.c Sun Nov 8 23:06:40 2015 (r290563) +++ head/sys/dev/usb/wlan/if_urtwn.c Sun Nov 8 23:21:54 2015 (r290564) @@ -269,6 +269,8 @@ static void urtwn_set_gain(struct urtwn static void urtwn_scan_start(struct ieee80211com *); static void urtwn_scan_end(struct ieee80211com *); static void urtwn_set_channel(struct ieee80211com *); +static void urtwn_set_promisc(struct urtwn_softc *); +static void urtwn_update_promisc(struct ieee80211com *); static void urtwn_update_mcast(struct ieee80211com *); static void urtwn_set_chan(struct urtwn_softc *, struct ieee80211_channel *, @@ -457,6 +459,7 @@ urtwn_attach(device_t self) ic->ic_parent = urtwn_parent; ic->ic_vap_create = urtwn_vap_create; ic->ic_vap_delete = urtwn_vap_delete; + ic->ic_update_promisc = urtwn_update_promisc; ic->ic_update_mcast = urtwn_update_mcast; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, @@ -1574,22 +1577,6 @@ urtwn_newstate(struct ieee80211vap *vap, break; case IEEE80211_S_RUN: if (vap->iv_opmode == IEEE80211_M_MONITOR) { - /* Enable Rx of data frames. */ - urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff); - - /* Enable Rx of ctrl frames. */ - urtwn_write_2(sc, R92C_RXFLTMAP1, 0xffff); - - /* - * Accept data/control/management frames - * from any BSSID. - */ - urtwn_write_4(sc, R92C_RCR, - (urtwn_read_4(sc, R92C_RCR) & ~(R92C_RCR_APM | - R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN)) | - R92C_RCR_ADF | R92C_RCR_ACF | R92C_RCR_AMF | - R92C_RCR_AAP); - /* Turn link LED on. */ urtwn_set_led(sc, URTWN_LED_LINK, 1); break; @@ -1618,9 +1605,11 @@ urtwn_newstate(struct ieee80211vap *vap, urtwn_write_2(sc, R92C_BCN_INTERVAL, ni->ni_intval); /* Allow Rx from our BSSID only. */ - urtwn_write_4(sc, R92C_RCR, - urtwn_read_4(sc, R92C_RCR) | - R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN); + if (ic->ic_promisc == 0) { + urtwn_write_4(sc, R92C_RCR, + urtwn_read_4(sc, R92C_RCR) | + R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN); + } /* Enable TSF synchronization. */ urtwn_tsf_sync_enable(sc); @@ -2755,21 +2744,50 @@ urtwn_pa_bias_init(struct urtwn_softc *s static void urtwn_rxfilter_init(struct urtwn_softc *sc) { - /* Initialize Rx filter. */ - /* TODO: use better filter for monitor mode. */ - urtwn_write_4(sc, R92C_RCR, - R92C_RCR_AAP | R92C_RCR_APM | R92C_RCR_AM | R92C_RCR_AB | - R92C_RCR_APP_ICV | R92C_RCR_AMF | R92C_RCR_HTC_LOC_CTRL | - R92C_RCR_APP_MIC | R92C_RCR_APP_PHYSTS); + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + uint32_t rcr; + uint16_t filter; + + URTWN_ASSERT_LOCKED(sc); + /* Accept all multicast frames. */ urtwn_write_4(sc, R92C_MAR + 0, 0xffffffff); urtwn_write_4(sc, R92C_MAR + 4, 0xffffffff); - /* Accept all management frames. */ - urtwn_write_2(sc, R92C_RXFLTMAP0, 0xffff); + + /* Filter for management frames. */ + filter = 0x7f3f; + if (vap->iv_opmode == IEEE80211_M_STA) { + filter &= ~( + R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_ASSOC_REQ) | + R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_REASSOC_REQ) | + R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_PROBE_REQ)); + } + urtwn_write_2(sc, R92C_RXFLTMAP0, filter); + /* Reject all control frames. */ urtwn_write_2(sc, R92C_RXFLTMAP1, 0x0000); - /* Accept all data frames. */ - urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff); + + /* Reject all data frames. */ + urtwn_write_2(sc, R92C_RXFLTMAP2, 0x0000); + + 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; + + if (vap->iv_opmode == IEEE80211_M_MONITOR) { + /* Accept all frames. */ + rcr |= R92C_RCR_ACF | R92C_RCR_ADF | R92C_RCR_AMF | + R92C_RCR_AAP; + } + + /* Set Rx filter. */ + urtwn_write_4(sc, R92C_RCR, rcr); + + if (ic->ic_promisc != 0) { + /* Update Rx filter. */ + urtwn_set_promisc(sc); + } } static void @@ -3080,7 +3098,8 @@ urtwn_scan_end(struct ieee80211com *ic) URTWN_LOCK(sc); /* Restore limitations. */ - urtwn_set_rx_bssid_all(sc, 0); + if (ic->ic_promisc == 0) + urtwn_set_rx_bssid_all(sc, 0); /* Set gain under link. */ urtwn_set_gain(sc, 0x32); URTWN_UNLOCK(sc); @@ -3102,6 +3121,52 @@ urtwn_set_channel(struct ieee80211com *i } static void +urtwn_set_promisc(struct urtwn_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + uint32_t rcr, mask1, mask2; + + URTWN_ASSERT_LOCKED(sc); + + if (vap->iv_opmode == IEEE80211_M_MONITOR) + return; + + mask1 = R92C_RCR_ACF | R92C_RCR_ADF | R92C_RCR_AMF | R92C_RCR_AAP; + mask2 = R92C_RCR_APM; + + if (vap->iv_state == IEEE80211_S_RUN) { + switch (vap->iv_opmode) { + case IEEE80211_M_STA: + mask2 |= R92C_RCR_CBSSID_BCN | R92C_RCR_CBSSID_DATA; + break; + default: + device_printf(sc->sc_dev, "%s: undefined opmode %d\n", + __func__, vap->iv_opmode); + return; + } + } + + rcr = urtwn_read_4(sc, R92C_RCR); + if (ic->ic_promisc == 0) + rcr = (rcr & ~mask1) | mask2; + else + rcr = (rcr & ~mask2) | mask1; + urtwn_write_4(sc, R92C_RCR, rcr); +} + +static void +urtwn_update_promisc(struct ieee80211com *ic) +{ + struct urtwn_softc *sc = ic->ic_softc; + + URTWN_LOCK(sc); + if (sc->sc_flags & URTWN_RUNNING) + urtwn_set_promisc(sc); + URTWN_UNLOCK(sc); +} + +static void urtwn_update_mcast(struct ieee80211com *ic) { /* XXX do nothing? */ @@ -3302,6 +3367,7 @@ urtwn_init(struct urtwn_softc *sc) /* Set initial network type. */ urtwn_set_mode(sc, R92C_MSR_INFRA); + /* Initialize Rx filter. */ urtwn_rxfilter_init(sc); /* Set response rate. */ @@ -3375,6 +3441,9 @@ urtwn_init(struct urtwn_softc *sc) urtwn_bb_init(sc); urtwn_rf_init(sc); + /* Reinitialize Rx filter (D3845 is not committed yet). */ + urtwn_rxfilter_init(sc); + if (sc->chip & URTWN_CHIP_88E) { urtwn_write_2(sc, R92C_CR, urtwn_read_2(sc, R92C_CR) | R92C_CR_MACTXEN | Modified: head/sys/dev/usb/wlan/if_urtwnreg.h ============================================================================== --- head/sys/dev/usb/wlan/if_urtwnreg.h Sun Nov 8 23:06:40 2015 (r290563) +++ head/sys/dev/usb/wlan/if_urtwnreg.h Sun Nov 8 23:21:54 2015 (r290564) @@ -535,6 +535,10 @@ #define R92C_CAMCMD_CLR 0x40000000 #define R92C_CAMCMD_POLLING 0x80000000 +/* Bits for R92C_RXFLTMAP*. */ +#define R92C_RXFLTMAP_SUBTYPE(subtype) \ + (1 << ((subtype) >> IEEE80211_FC0_SUBTYPE_SHIFT)) + /* * Baseband registers.