From owner-svn-src-head@freebsd.org Sat Dec 10 18:57:34 2016 Return-Path: Delivered-To: svn-src-head@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 20E7DC71769; Sat, 10 Dec 2016 18:57:34 +0000 (UTC) (envelope-from adrian.chadd@gmail.com) Received: from mail-io0-x241.google.com (mail-io0-x241.google.com [IPv6:2607:f8b0:4001:c06::241]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id DF9CD1CE4; Sat, 10 Dec 2016 18:57:33 +0000 (UTC) (envelope-from adrian.chadd@gmail.com) Received: by mail-io0-x241.google.com with SMTP id f73so13553001ioe.2; Sat, 10 Dec 2016 10:57:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=3M7nVPkXZ5dXe2amEV0iFatXdN7WVzZO2lEyWTGzkKU=; b=AxhS7dNQ+sIynNi5X2XLhDvZ+t2FlGFV6sXZA+7NWfxfz1NwAQIG9Ahk7RpdSfCbZW z81fewHbvLIWYTx/FMRDdzNiUI4fyioSNKFfd4CCUhdpzKtqUnxcaq22xKncCbg2vn/C w5pQ8DoTokmzxTIhYlNlgBMKAXuQT5eRruqcb7AXvn5hGDfCj6wnc5G90CGUK0/Zqoa/ r43NUKV04qWE4CjW1hehzl7nrzu7a+fjA7MkS0qr3rgbJO45N9YJsyttYuK9f72Obk0K MRaFZgD2y6YqmXqSOBgIjYZkvonnhuW2UNjBif9pGEL+NMjMEym4tTvf7yyBzoX2Bm9z WF7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=3M7nVPkXZ5dXe2amEV0iFatXdN7WVzZO2lEyWTGzkKU=; b=fL3ED0Ie3VyrR3ZFlIoEEIWXw5HBoOKFe6rTbAzgzlpW1AcACp+rRZ5qcCqbhLzahf Phy7FByVkGuKPcF8Q7XugT/P4BZW4xdY3TYeyOsgziwAytQBvB3L4BbaB44cR94FWc6l uk5RQWQR0nyvbYuUzXD7H4ysdqFA0AJ1wNPJK4p8S4HkMe8M4w0yfEwWiyTCicm1r3bV 4rk3JIzNlcnc4YwId9wNl/KQx8s00dQNmcHMd67Z0dlB8+clClKotjWdLC6fXCcSYF9t WDv/DUmkz00qwDjj8hVV+OXw/QoUguGU/bEDWzuJRsRAAJ1NPD3aUoNAG/q4jiNYPvKN XMww== X-Gm-Message-State: AKaTC01taxJn1wExRCDAmXYk4/SltSKcb1iIHX0FZBv+qRfT/IZxFtf+RH+5IpaLgyVRuAQpNm0VygWtIcp5AQ== X-Received: by 10.36.58.85 with SMTP id m82mr3843414itm.29.1481396252803; Sat, 10 Dec 2016 10:57:32 -0800 (PST) MIME-Version: 1.0 Received: by 10.36.150.129 with HTTP; Sat, 10 Dec 2016 10:57:32 -0800 (PST) In-Reply-To: <201612101847.uBAIlEFb094635@repo.freebsd.org> References: <201612101847.uBAIlEFb094635@repo.freebsd.org> From: Adrian Chadd Date: Sat, 10 Dec 2016 10:57:32 -0800 Message-ID: Subject: Re: svn commit: r309825 - head/sys/dev/usb/wlan To: Andriy Voskoboinyk Cc: "src-committers@freebsd.org" , "svn-src-all@freebsd.org" , "svn-src-head@freebsd.org" Content-Type: text/plain; charset=UTF-8 X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 10 Dec 2016 18:57:34 -0000 Would you mind updating the manpage to state this monitor/promisc difference in the LIMITATIONS section, or something? Thanks! -a On 10 December 2016 at 10:47, Andriy Voskoboinyk wrote: > Author: avos > Date: Sat Dec 10 18:47:13 2016 > New Revision: 309825 > URL: https://svnweb.freebsd.org/changeset/base/309825 > > Log: > rsu: add promiscuous mode support. > > - Add partial promiscuous mode support (no management frames; > they cannot be received by the firmware and net80211 at the same time). > - Add monitor mode support (all frames). > > Tested with Asus, USB-N10. > > Modified: > head/sys/dev/usb/wlan/if_rsu.c > head/sys/dev/usb/wlan/if_rsureg.h > > Modified: head/sys/dev/usb/wlan/if_rsu.c > ============================================================================== > --- head/sys/dev/usb/wlan/if_rsu.c Sat Dec 10 18:29:39 2016 (r309824) > +++ head/sys/dev/usb/wlan/if_rsu.c Sat Dec 10 18:47:13 2016 (r309825) > @@ -23,7 +23,7 @@ __FBSDID("$FreeBSD$"); > * > * TODO: > * o tx a-mpdu > - * o monitor / hostap / ibss / mesh > + * o hostap / ibss / mesh > * o power-save operation > */ > > @@ -175,6 +175,7 @@ static void rsu_getradiocaps(struct ieee > static void rsu_set_channel(struct ieee80211com *); > static void rsu_scan_curchan(struct ieee80211_scan_state *, unsigned long); > static void rsu_scan_mindwell(struct ieee80211_scan_state *); > +static void rsu_update_promisc(struct ieee80211com *); > static uint8_t rsu_get_multi_pos(const uint8_t[]); > static void rsu_set_multi(struct rsu_softc *); > static void rsu_update_mcast(struct ieee80211com *); > @@ -202,6 +203,9 @@ static int rsu_read_rom(struct rsu_softc > static int rsu_fw_cmd(struct rsu_softc *, uint8_t, void *, int); > static void rsu_calib_task(void *, int); > static void rsu_tx_task(void *, int); > +static void rsu_set_led(struct rsu_softc *, int); > +static int rsu_monitor_newstate(struct ieee80211vap *, > + enum ieee80211_state, int); > static int rsu_newstate(struct ieee80211vap *, enum ieee80211_state, int); > static int rsu_key_alloc(struct ieee80211vap *, struct ieee80211_key *, > ieee80211_keyix *, ieee80211_keyix *); > @@ -244,6 +248,9 @@ static struct mbuf * > static void rsu_txeof(struct usb_xfer *, struct rsu_data *); > static int rsu_raw_xmit(struct ieee80211_node *, struct mbuf *, > const struct ieee80211_bpf_params *); > +static void rsu_rxfilter_init(struct rsu_softc *); > +static void rsu_rxfilter_set(struct rsu_softc *, uint32_t, uint32_t); > +static void rsu_rxfilter_refresh(struct rsu_softc *); > static void rsu_init(struct rsu_softc *); > static int rsu_tx_start(struct rsu_softc *, struct ieee80211_node *, > struct mbuf *, struct rsu_data *); > @@ -536,6 +543,7 @@ rsu_attach(device_t self) > /* Set device capabilities. */ > ic->ic_caps = > IEEE80211_C_STA | /* station mode */ > + IEEE80211_C_MONITOR | /* monitor mode supported */ > #if 0 > IEEE80211_C_BGSCAN | /* Background scan. */ > #endif > @@ -582,6 +590,7 @@ rsu_attach(device_t self) > ic->ic_scan_mindwell = rsu_scan_mindwell; > ic->ic_vap_create = rsu_vap_create; > ic->ic_vap_delete = rsu_vap_delete; > + ic->ic_update_promisc = rsu_update_promisc; > ic->ic_update_mcast = rsu_update_mcast; > ic->ic_parent = rsu_parent; > ic->ic_transmit = rsu_transmit; > @@ -688,7 +697,10 @@ rsu_vap_create(struct ieee80211com *ic, > > /* override state transition machine */ > uvp->newstate = vap->iv_newstate; > - vap->iv_newstate = rsu_newstate; > + if (opmode == IEEE80211_M_MONITOR) > + vap->iv_newstate = rsu_monitor_newstate; > + else > + vap->iv_newstate = rsu_newstate; > vap->iv_key_alloc = rsu_key_alloc; > vap->iv_key_set = rsu_key_set; > vap->iv_key_delete = rsu_key_delete; > @@ -759,9 +771,30 @@ rsu_getradiocaps(struct ieee80211com *ic > } > > static void > -rsu_set_channel(struct ieee80211com *ic __unused) > +rsu_set_channel(struct ieee80211com *ic) > { > - /* We are unable to switch channels, yet. */ > + struct rsu_softc *sc = ic->ic_softc; > + > + /* > + * Only need to set the channel in Monitor mode. AP scanning and auth > + * are already taken care of by their respective firmware commands. > + */ > + if (ic->ic_opmode == IEEE80211_M_MONITOR) { > + struct r92s_set_channel cmd; > + int error; > + > + cmd.channel = IEEE80211_CHAN2IEEE(ic->ic_curchan); > + > + RSU_LOCK(sc); > + error = rsu_fw_cmd(sc, R92S_CMD_SET_CHANNEL, &cmd, > + sizeof(cmd)); > + if (error != 0) { > + device_printf(sc->sc_dev, > + "%s: error %d setting channel\n", __func__, > + error); > + } > + RSU_UNLOCK(sc); > + } > } > > static void > @@ -782,6 +815,17 @@ rsu_scan_mindwell(struct ieee80211_scan_ > /* NB: don't try to abort scan; wait for firmware to finish */ > } > > +static void > +rsu_update_promisc(struct ieee80211com *ic) > +{ > + struct rsu_softc *sc = ic->ic_softc; > + > + RSU_LOCK(sc); > + if (sc->sc_running) > + rsu_rxfilter_refresh(sc); > + RSU_UNLOCK(sc); > +} > + > /* > * The same as rtwn_get_multi_pos() / rtwn_set_multi(). > */ > @@ -1343,6 +1387,47 @@ rsu_set_fw_power_state(struct rsu_softc > return (error); > } > > +static void > +rsu_set_led(struct rsu_softc *sc, int on) > +{ > + rsu_write_1(sc, R92S_LEDCFG, > + (rsu_read_1(sc, R92S_LEDCFG) & 0xf0) | (!on << 3)); > +} > + > +static int > +rsu_monitor_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, > + int arg) > +{ > + struct ieee80211com *ic = vap->iv_ic; > + struct rsu_softc *sc = ic->ic_softc; > + struct rsu_vap *uvp = RSU_VAP(vap); > + > + if (vap->iv_state != nstate) { > + IEEE80211_UNLOCK(ic); > + RSU_LOCK(sc); > + > + switch (nstate) { > + case IEEE80211_S_INIT: > + sc->sc_vap_is_running = 0; > + rsu_set_led(sc, 0); > + break; > + case IEEE80211_S_RUN: > + sc->sc_vap_is_running = 1; > + rsu_set_led(sc, 1); > + break; > + default: > + /* NOTREACHED */ > + break; > + } > + rsu_rxfilter_refresh(sc); > + > + RSU_UNLOCK(sc); > + IEEE80211_LOCK(ic); > + } > + > + return (uvp->newstate(vap, nstate, arg)); > +} > + > static int > rsu_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) > { > @@ -1376,6 +1461,12 @@ rsu_newstate(struct ieee80211vap *vap, e > RSU_LOCK(sc); > /* Disassociate from our current BSS. */ > rsu_disconnect(sc); > + usb_pause_mtx(&sc->sc_mtx, USB_MS_TO_TICKS(10)); > + > + /* Refresh Rx filter (may be modified by firmware). */ > + sc->sc_vap_is_running = 0; > + rsu_rxfilter_refresh(sc); > + > /* Reinstall static keys. */ > if (sc->sc_running) > rsu_reinit_static_keys(sc); > @@ -2030,6 +2121,11 @@ rsu_event_join_bss(struct rsu_softc *sc, > __func__, ether_sprintf(rsp->bss.macaddr), tmp); > /* XXX is this required? What's the top two bits for again? */ > ni->ni_associd = tmp | 0xc000; > + > + /* Refresh Rx filter (was changed by firmware). */ > + sc->sc_vap_is_running = 1; > + rsu_rxfilter_refresh(sc); > + > RSU_UNLOCK(sc); > ieee80211_new_state(vap, IEEE80211_S_RUN, > IEEE80211_FC0_SUBTYPE_ASSOC_RESP); > @@ -3329,6 +3425,65 @@ rsu_raw_xmit(struct ieee80211_node *ni, > } > > static void > +rsu_rxfilter_init(struct rsu_softc *sc) > +{ > + uint32_t reg; > + > + RSU_ASSERT_LOCKED(sc); > + > + /* Setup multicast filter. */ > + rsu_set_multi(sc); > + > + /* Adjust Rx filter. */ > + reg = rsu_read_4(sc, R92S_RCR); > + reg &= ~R92S_RCR_AICV; > + reg |= R92S_RCR_APP_PHYSTS; > + rsu_write_4(sc, R92S_RCR, reg); > + > + /* Update dynamic Rx filter parts. */ > + rsu_rxfilter_refresh(sc); > +} > + > +static void > +rsu_rxfilter_set(struct rsu_softc *sc, uint32_t clear, uint32_t set) > +{ > + /* NB: firmware can touch this register too. */ > + rsu_write_4(sc, R92S_RCR, > + (rsu_read_4(sc, R92S_RCR) & ~clear) | set); > +} > + > +static void > +rsu_rxfilter_refresh(struct rsu_softc *sc) > +{ > + struct ieee80211com *ic = &sc->sc_ic; > + uint32_t mask_all, mask_min; > + > + RSU_ASSERT_LOCKED(sc); > + > + /* NB: RCR_AMF / RXFLTMAP_MGT are used by firmware. */ > + mask_all = R92S_RCR_ACF | R92S_RCR_AAP; > + mask_min = R92S_RCR_APM; > + if (sc->sc_vap_is_running) > + mask_min |= R92S_RCR_CBSSID; > + else > + mask_all |= R92S_RCR_ADF; > + > + if (ic->ic_opmode == IEEE80211_M_MONITOR) { > + uint16_t rxfltmap; > + if (sc->sc_vap_is_running) > + rxfltmap = 0; > + else > + rxfltmap = R92S_RXFLTMAP_MGT_DEF; > + rsu_write_2(sc, R92S_RXFLTMAP_MGT, rxfltmap); > + } > + > + if (ic->ic_promisc == 0 && ic->ic_opmode != IEEE80211_M_MONITOR) > + rsu_rxfilter_set(sc, mask_all, mask_min); > + else > + rsu_rxfilter_set(sc, mask_min, mask_all); > +} > + > +static void > rsu_init(struct rsu_softc *sc) > { > struct ieee80211com *ic = &sc->sc_ic; > @@ -3394,12 +3549,8 @@ rsu_init(struct rsu_softc *sc) > goto fail; > } > > - /* Append PHY status. */ > - rsu_write_4(sc, R92S_RCR, > - rsu_read_4(sc, R92S_RCR) | 0x02000000); > - > - /* Setup multicast filter (must be done after firmware loading). */ > - rsu_set_multi(sc); > + /* Initialize Rx filter. */ > + rsu_rxfilter_init(sc); > > /* Set PS mode fully active */ > error = rsu_set_fw_power_state(sc, RSU_PWR_ACTIVE); > @@ -3433,6 +3584,7 @@ rsu_stop(struct rsu_softc *sc) > RSU_ASSERT_LOCKED(sc); > > sc->sc_running = 0; > + sc->sc_vap_is_running = 0; > sc->sc_calibrating = 0; > taskqueue_cancel_timeout(taskqueue_thread, &sc->calib_task, NULL); > taskqueue_cancel(taskqueue_thread, &sc->tx_task, NULL); > > Modified: head/sys/dev/usb/wlan/if_rsureg.h > ============================================================================== > --- head/sys/dev/usb/wlan/if_rsureg.h Sat Dec 10 18:29:39 2016 (r309824) > +++ head/sys/dev/usb/wlan/if_rsureg.h Sat Dec 10 18:47:13 2016 (r309825) > @@ -54,6 +54,12 @@ > #define R92S_TIMECTRL 0x0080 > #define R92S_TSFTR (R92S_TIMECTRL + 0x000) > > +#define R92S_FIFOCTRL 0x00a0 > +#define R92S_RXFLTMAP_MGT (R92S_FIFOCTRL + 0x076) > +#define R92S_RXFLTMAP_CTL (R92S_FIFOCTRL + 0x078) > +#define R92S_RXFLTMAP_DATA (R92S_FIFOCTRL + 0x07a) > +#define R92S_RXFLTMAP_MESH (R92S_FIFOCTRL + 0x07c) > + > #define R92S_SECURITY 0x0240 > #define R92S_CAMCMD (R92S_SECURITY + 0x000) > #define R92S_CAMWRITE (R92S_SECURITY + 0x004) > @@ -63,6 +69,7 @@ > #define R92S_GPIO_CTRL (R92S_GP + 0x00c) > #define R92S_GPIO_IO_SEL (R92S_GP + 0x00e) > #define R92S_MAC_PINMUX_CTRL (R92S_GP + 0x011) > +#define R92S_LEDCFG (R92S_GP + 0x012) > > #define R92S_IOCMD_CTRL 0x0370 > #define R92S_IOCMD_DATA 0x0374 > @@ -141,6 +148,29 @@ > #define R92S_TCR_IMEM_RDY 0x20 > #define R92S_TCR_FWRDY 0x80 > > +/* Bits for R92S_RCR. */ > +#define R92S_RCR_AAP 0x00000001 > +#define R92S_RCR_APM 0x00000002 > +#define R92S_RCR_AM 0x00000004 > +#define R92S_RCR_AB 0x00000008 > +#define R92S_RCR_ACRC32 0x00000020 > +#define R92S_RCR_AICV 0x00001000 > +#define R92S_RCR_APP_ICV 0x00010000 > +#define R92S_RCR_APP_MIC 0x00020000 > +#define R92S_RCR_ADF 0x00040000 > +#define R92S_RCR_ACF 0x00080000 > +#define R92S_RCR_AMF 0x00100000 > +#define R92S_RCR_ADD3 0x00200000 > +#define R92S_RCR_APWRMGT 0x00400000 > +#define R92S_RCR_CBSSID 0x00800000 > +#define R92S_RCR_APP_PHYSTS 0x02000000 > +#define R92S_RCR_ENMBID 0x08000000 > + > +/* Bits for R92S_RXFLTMAP*. */ > +#define R92S_RXFLTMAP_MGT_DEF 0x3f3f > +#define R92S_RXFLTMAP_FW(subtype) \ > + (1 << ((subtype) >> IEEE80211_FC0_SUBTYPE_SHIFT)) > + > /* Bits for R92S_GPIO_IO_SEL. */ > #define R92S_GPIO_WPS 0x10 > > @@ -546,6 +576,11 @@ struct r92s_set_pwr_mode { > uint8_t bcn_pass_time; > } __packed; > > +/* Structure for R92S_CMD_SET_CHANNEL. */ > +struct r92s_set_channel { > + uint32_t channel; > +} __packed; > + > /* Structure for event R92S_EVENT_JOIN_BSS. */ > struct r92s_event_join_bss { > uint32_t next; > @@ -817,6 +852,7 @@ struct rsu_softc { > int sc_currssi; > > u_int sc_running:1, > + sc_vap_is_running:1, > sc_calibrating:1, > sc_active_scan:1, > sc_extra_scan:1; >