[Midnightbsd-cvs] src [10043] trunk/sys/dev/usb/wlan: sync with freebsd

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun May 27 18:35:12 EDT 2018


Revision: 10043
          http://svnweb.midnightbsd.org/src/?rev=10043
Author:   laffer1
Date:     2018-05-27 18:35:11 -0400 (Sun, 27 May 2018)
Log Message:
-----------
sync with freebsd

Modified Paths:
--------------
    trunk/sys/dev/usb/wlan/if_rum.c
    trunk/sys/dev/usb/wlan/if_rumfw.h
    trunk/sys/dev/usb/wlan/if_rumreg.h
    trunk/sys/dev/usb/wlan/if_rumvar.h
    trunk/sys/dev/usb/wlan/if_run.c
    trunk/sys/dev/usb/wlan/if_runreg.h
    trunk/sys/dev/usb/wlan/if_runvar.h
    trunk/sys/dev/usb/wlan/if_uath.c
    trunk/sys/dev/usb/wlan/if_uathreg.h
    trunk/sys/dev/usb/wlan/if_uathvar.h
    trunk/sys/dev/usb/wlan/if_upgt.c
    trunk/sys/dev/usb/wlan/if_upgtvar.h
    trunk/sys/dev/usb/wlan/if_ural.c
    trunk/sys/dev/usb/wlan/if_uralreg.h
    trunk/sys/dev/usb/wlan/if_uralvar.h
    trunk/sys/dev/usb/wlan/if_urtw.c
    trunk/sys/dev/usb/wlan/if_urtwreg.h
    trunk/sys/dev/usb/wlan/if_urtwvar.h
    trunk/sys/dev/usb/wlan/if_zyd.c
    trunk/sys/dev/usb/wlan/if_zydfw.h
    trunk/sys/dev/usb/wlan/if_zydreg.h

Added Paths:
-----------
    trunk/sys/dev/usb/wlan/if_rsu.c
    trunk/sys/dev/usb/wlan/if_rsureg.h
    trunk/sys/dev/usb/wlan/if_urtwnreg.h

Added: trunk/sys/dev/usb/wlan/if_rsu.c
===================================================================
--- trunk/sys/dev/usb/wlan/if_rsu.c	                        (rev 0)
+++ trunk/sys/dev/usb/wlan/if_rsu.c	2018-05-27 22:35:11 UTC (rev 10043)
@@ -0,0 +1,2487 @@
+/* $MidnightBSD$ */
+/*	$OpenBSD: if_rsu.c,v 1.17 2013/04/15 09:23:01 mglocker Exp $	*/
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini at free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/usb/wlan/if_rsu.c 321981 2017-08-03 07:56:39Z hselasky $");
+
+/*
+ * Driver for Realtek RTL8188SU/RTL8191SU/RTL8192SU.
+ *
+ * TODO:
+ *   o 11n support
+ *   o h/w crypto
+ *   o hostap / ibss / mesh
+ */
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/firmware.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_regdomain.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include "usbdevs.h"
+
+#define USB_DEBUG_VAR rsu_debug
+#include <dev/usb/usb_debug.h>
+
+#include <dev/usb/wlan/if_rsureg.h>
+
+#ifdef USB_DEBUG
+static int rsu_debug = 0;
+SYSCTL_NODE(_hw_usb, OID_AUTO, rsu, CTLFLAG_RW, 0, "USB rsu");
+SYSCTL_INT(_hw_usb_rsu, OID_AUTO, debug, CTLFLAG_RW, &rsu_debug, 0,
+    "Debug level");
+#endif
+
+static const STRUCT_USB_HOST_ID rsu_devs[] = {
+#define	RSU_HT_NOT_SUPPORTED 0
+#define	RSU_HT_SUPPORTED 1
+#define RSU_DEV_HT(v,p)  { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, \
+				   RSU_HT_SUPPORTED) }
+#define RSU_DEV(v,p)     { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, \
+				   RSU_HT_NOT_SUPPORTED) }
+	RSU_DEV(ASUS,			RTL8192SU),
+	RSU_DEV(AZUREWAVE,		RTL8192SU_4),
+	RSU_DEV_HT(ACCTON,		RTL8192SU),
+	RSU_DEV_HT(ASUS,		USBN10),
+	RSU_DEV_HT(AZUREWAVE,		RTL8192SU_1),
+	RSU_DEV_HT(AZUREWAVE,		RTL8192SU_2),
+	RSU_DEV_HT(AZUREWAVE,		RTL8192SU_3),
+	RSU_DEV_HT(AZUREWAVE,		RTL8192SU_5),
+	RSU_DEV_HT(BELKIN,		RTL8192SU_1),
+	RSU_DEV_HT(BELKIN,		RTL8192SU_2),
+	RSU_DEV_HT(BELKIN,		RTL8192SU_3),
+	RSU_DEV_HT(CONCEPTRONIC2,	RTL8192SU_1),
+	RSU_DEV_HT(CONCEPTRONIC2,	RTL8192SU_2),
+	RSU_DEV_HT(CONCEPTRONIC2,	RTL8192SU_3),
+	RSU_DEV_HT(COREGA,		RTL8192SU),
+	RSU_DEV_HT(DLINK2,		DWA131A1),
+	RSU_DEV_HT(DLINK2,		RTL8192SU_1),
+	RSU_DEV_HT(DLINK2,		RTL8192SU_2),
+	RSU_DEV_HT(EDIMAX,		RTL8192SU_1),
+	RSU_DEV_HT(EDIMAX,		RTL8192SU_2),
+	RSU_DEV_HT(EDIMAX,		EW7622UMN),
+	RSU_DEV_HT(GUILLEMOT,		HWGUN54),
+	RSU_DEV_HT(GUILLEMOT,		HWNUM300),
+	RSU_DEV_HT(HAWKING,		RTL8192SU_1),
+	RSU_DEV_HT(HAWKING,		RTL8192SU_2),
+	RSU_DEV_HT(PLANEX2,		GWUSNANO),
+	RSU_DEV_HT(REALTEK,		RTL8171),
+	RSU_DEV_HT(REALTEK,		RTL8172),
+	RSU_DEV_HT(REALTEK,		RTL8173),
+	RSU_DEV_HT(REALTEK,		RTL8174),
+	RSU_DEV_HT(REALTEK,		RTL8192SU),
+	RSU_DEV_HT(REALTEK,		RTL8712),
+	RSU_DEV_HT(REALTEK,		RTL8713),
+	RSU_DEV_HT(SENAO,		RTL8192SU_1),
+	RSU_DEV_HT(SENAO,		RTL8192SU_2),
+	RSU_DEV_HT(SITECOMEU,		WL349V1),
+	RSU_DEV_HT(SITECOMEU,		WL353),
+	RSU_DEV_HT(SWEEX2,		LW154),
+#undef RSU_DEV_HT
+#undef RSU_DEV
+};
+
+static device_probe_t   rsu_match;
+static device_attach_t  rsu_attach;
+static device_detach_t  rsu_detach;
+static usb_callback_t   rsu_bulk_tx_callback_be_bk;
+static usb_callback_t   rsu_bulk_tx_callback_vi_vo;
+static usb_callback_t   rsu_bulk_rx_callback;
+static usb_error_t	rsu_do_request(struct rsu_softc *,
+			    struct usb_device_request *, void *);
+static struct ieee80211vap *
+		rsu_vap_create(struct ieee80211com *, const char name[],
+		    int, enum ieee80211_opmode, int, const uint8_t bssid[],
+		    const uint8_t mac[]);
+static void	rsu_vap_delete(struct ieee80211vap *);
+static void	rsu_scan_start(struct ieee80211com *);
+static void	rsu_scan_end(struct ieee80211com *);
+static void	rsu_set_channel(struct ieee80211com *);
+static void	rsu_update_mcast(struct ifnet *);
+static int	rsu_alloc_rx_list(struct rsu_softc *);
+static void	rsu_free_rx_list(struct rsu_softc *);
+static int	rsu_alloc_tx_list(struct rsu_softc *);
+static void	rsu_free_tx_list(struct rsu_softc *);
+static void	rsu_free_list(struct rsu_softc *, struct rsu_data [], int);
+static struct rsu_data *_rsu_getbuf(struct rsu_softc *);
+static struct rsu_data *rsu_getbuf(struct rsu_softc *);
+static int	rsu_write_region_1(struct rsu_softc *, uint16_t, uint8_t *,
+		    int);
+static void	rsu_write_1(struct rsu_softc *, uint16_t, uint8_t);
+static void	rsu_write_2(struct rsu_softc *, uint16_t, uint16_t);
+static void	rsu_write_4(struct rsu_softc *, uint16_t, uint32_t);
+static int	rsu_read_region_1(struct rsu_softc *, uint16_t, uint8_t *,
+		    int);
+static uint8_t	rsu_read_1(struct rsu_softc *, uint16_t);
+static uint16_t	rsu_read_2(struct rsu_softc *, uint16_t);
+static uint32_t	rsu_read_4(struct rsu_softc *, uint16_t);
+static int	rsu_fw_iocmd(struct rsu_softc *, uint32_t);
+static uint8_t	rsu_efuse_read_1(struct rsu_softc *, uint16_t);
+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 int	rsu_newstate(struct ieee80211vap *, enum ieee80211_state, int);
+#ifdef notyet
+static void	rsu_set_key(struct rsu_softc *, const struct ieee80211_key *);
+static void	rsu_delete_key(struct rsu_softc *, const struct ieee80211_key *);
+#endif
+static int	rsu_site_survey(struct rsu_softc *, struct ieee80211vap *);
+static int	rsu_join_bss(struct rsu_softc *, struct ieee80211_node *);
+static int	rsu_disconnect(struct rsu_softc *);
+static void	rsu_event_survey(struct rsu_softc *, uint8_t *, int);
+static void	rsu_event_join_bss(struct rsu_softc *, uint8_t *, int);
+static void	rsu_rx_event(struct rsu_softc *, uint8_t, uint8_t *, int);
+static void	rsu_rx_multi_event(struct rsu_softc *, uint8_t *, int);
+static int8_t	rsu_get_rssi(struct rsu_softc *, int, void *);
+static struct mbuf *
+		rsu_rx_frame(struct rsu_softc *, uint8_t *, int, int *);
+static struct mbuf *
+		rsu_rx_multi_frame(struct rsu_softc *, uint8_t *, int, int *);
+static struct mbuf *
+		rsu_rxeof(struct usb_xfer *, struct rsu_data *, int *);
+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_init(void *);
+static void	rsu_init_locked(struct rsu_softc *);
+static int	rsu_tx_start(struct rsu_softc *, struct ieee80211_node *, 
+		    struct mbuf *, struct rsu_data *);
+static void	rsu_start(struct ifnet *);
+static void	rsu_start_locked(struct ifnet *);
+static int	rsu_ioctl(struct ifnet *, u_long, caddr_t);
+static void	rsu_stop(struct ifnet *, int);
+static void	rsu_stop_locked(struct ifnet *, int);
+static void	rsu_ms_delay(struct rsu_softc *);
+
+static device_method_t rsu_methods[] = {
+	DEVMETHOD(device_probe,		rsu_match),
+	DEVMETHOD(device_attach,	rsu_attach),
+	DEVMETHOD(device_detach,	rsu_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t rsu_driver = {
+	.name = "rsu",
+	.methods = rsu_methods,
+	.size = sizeof(struct rsu_softc)
+};
+
+static devclass_t rsu_devclass;
+
+DRIVER_MODULE(rsu, uhub, rsu_driver, rsu_devclass, NULL, 0);
+MODULE_DEPEND(rsu, wlan, 1, 1, 1);
+MODULE_DEPEND(rsu, usb, 1, 1, 1);
+MODULE_DEPEND(rsu, firmware, 1, 1, 1);
+MODULE_VERSION(rsu, 1);
+
+static uint8_t rsu_wme_ac_xfer_map[4] = {
+	[WME_AC_BE] = RSU_BULK_TX_BE_BK,
+	[WME_AC_BK] = RSU_BULK_TX_BE_BK,
+	[WME_AC_VI] = RSU_BULK_TX_VI_VO,
+	[WME_AC_VO] = RSU_BULK_TX_VI_VO,
+};
+
+static const struct usb_config rsu_config[RSU_N_TRANSFER] = {
+	[RSU_BULK_RX] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_IN,
+		.bufsize = RSU_RXBUFSZ,
+		.flags = {
+			.pipe_bof = 1,
+			.short_xfer_ok = 1
+		},
+		.callback = rsu_bulk_rx_callback
+	},
+	[RSU_BULK_TX_BE_BK] = {
+		.type = UE_BULK,
+		.endpoint = 0x06,
+		.direction = UE_DIR_OUT,
+		.bufsize = RSU_TXBUFSZ,
+		.flags = {
+			.ext_buffer = 1,
+			.pipe_bof = 1,
+			.force_short_xfer = 1
+		},
+		.callback = rsu_bulk_tx_callback_be_bk,
+		.timeout = RSU_TX_TIMEOUT
+	},
+	[RSU_BULK_TX_VI_VO] = {
+		.type = UE_BULK,
+		.endpoint = 0x04,
+		.direction = UE_DIR_OUT,
+		.bufsize = RSU_TXBUFSZ,
+		.flags = {
+			.ext_buffer = 1,
+			.pipe_bof = 1,
+			.force_short_xfer = 1
+		},
+		.callback = rsu_bulk_tx_callback_vi_vo,
+		.timeout = RSU_TX_TIMEOUT
+	},
+};
+
+static int
+rsu_match(device_t self)
+{
+	struct usb_attach_arg *uaa = device_get_ivars(self);
+
+	if (uaa->usb_mode != USB_MODE_HOST ||
+	    uaa->info.bIfaceIndex != 0 ||
+	    uaa->info.bConfigIndex != 0)
+		return (ENXIO);
+
+	return (usbd_lookup_id_by_uaa(rsu_devs, sizeof(rsu_devs), uaa));
+}
+
+static int
+rsu_attach(device_t self)
+{
+	struct usb_attach_arg *uaa = device_get_ivars(self);
+	struct rsu_softc *sc = device_get_softc(self);
+	struct ifnet *ifp;
+	struct ieee80211com *ic;
+	int error;
+	uint8_t iface_index, bands;
+
+	device_set_usb_desc(self);
+	sc->sc_udev = uaa->device;
+	sc->sc_dev = self;
+
+	mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
+	    MTX_DEF);
+	TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_task, 0, 
+	    rsu_calib_task, sc);
+
+	/* Allocate Tx/Rx buffers. */
+	error = rsu_alloc_rx_list(sc);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate Rx buffers\n");
+		goto fail_usb;
+	}
+
+	error = rsu_alloc_tx_list(sc);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate Tx buffers\n");
+		rsu_free_rx_list(sc);
+		goto fail_usb;
+	}
+
+	iface_index = 0;
+	error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
+	    rsu_config, RSU_N_TRANSFER, sc, &sc->sc_mtx);
+	if (error) {
+		device_printf(sc->sc_dev,
+		    "could not allocate USB transfers, err=%s\n", 
+		    usbd_errstr(error));
+		goto fail_usb;
+	}
+	RSU_LOCK(sc);
+	/* Read chip revision. */
+	sc->cut = MS(rsu_read_4(sc, R92S_PMC_FSM), R92S_PMC_FSM_CUT);
+	if (sc->cut != 3)
+		sc->cut = (sc->cut >> 1) + 1;
+	error = rsu_read_rom(sc);
+	RSU_UNLOCK(sc);
+	if (error != 0) {
+		device_printf(self, "could not read ROM\n");
+		goto fail_rom;
+	}
+	IEEE80211_ADDR_COPY(sc->sc_bssid, &sc->rom[0x12]);
+	device_printf(self, "MAC/BB RTL8712 cut %d\n", sc->cut);
+	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
+	if (ifp == NULL) {
+		device_printf(self, "cannot allocate interface\n");
+		goto fail_ifalloc;
+	}
+	ic = ifp->if_l2com;
+	ifp->if_softc = sc;
+	if_initname(ifp, "rsu", device_get_unit(self));
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_init = rsu_init;
+	ifp->if_ioctl = rsu_ioctl;
+	ifp->if_start = rsu_start;
+	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
+	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
+	IFQ_SET_READY(&ifp->if_snd);
+	ifp->if_capabilities |= IFCAP_RXCSUM;
+	ifp->if_capenable |= IFCAP_RXCSUM;
+	ifp->if_hwassist = CSUM_TCP;
+
+	ic->ic_ifp = ifp;
+	ic->ic_phytype = IEEE80211_T_OFDM;	/* Not only, but not used. */
+	ic->ic_opmode = IEEE80211_M_STA;	/* Default to BSS mode. */
+
+	/* Set device capabilities. */
+	ic->ic_caps =
+	    IEEE80211_C_STA |		/* station mode */
+	    IEEE80211_C_BGSCAN |	/* Background scan. */
+	    IEEE80211_C_SHPREAMBLE |	/* Short preamble supported. */
+	    IEEE80211_C_SHSLOT |	/* Short slot time supported. */
+	    IEEE80211_C_WPA;		/* WPA/RSN. */
+
+#if 0
+	/* Check if HT support is present. */
+	if (usb_lookup(rsu_devs_noht, uaa->vendor, uaa->product) == NULL) {
+		/* Set HT capabilities. */
+		ic->ic_htcaps =
+		    IEEE80211_HTCAP_CBW20_40 |
+		    IEEE80211_HTCAP_DSSSCCK40;
+		/* Set supported HT rates. */
+		for (i = 0; i < 2; i++)
+			ic->ic_sup_mcs[i] = 0xff;
+	}
+#endif
+
+	/* Set supported .11b and .11g rates. */
+	bands = 0;
+	setbit(&bands, IEEE80211_MODE_11B);
+	setbit(&bands, IEEE80211_MODE_11G);
+	ieee80211_init_channels(ic, NULL, &bands);
+
+	ieee80211_ifattach(ic, sc->sc_bssid);
+	ic->ic_raw_xmit = rsu_raw_xmit;
+	ic->ic_scan_start = rsu_scan_start;
+	ic->ic_scan_end = rsu_scan_end;
+	ic->ic_set_channel = rsu_set_channel;
+	ic->ic_vap_create = rsu_vap_create;
+	ic->ic_vap_delete = rsu_vap_delete;
+	ic->ic_update_mcast = rsu_update_mcast;
+
+	ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr,
+	    sizeof(sc->sc_txtap), RSU_TX_RADIOTAP_PRESENT, 
+	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+	    RSU_RX_RADIOTAP_PRESENT);
+
+	if (bootverbose)
+		ieee80211_announce(ic);
+
+	return (0);
+
+fail_ifalloc:
+fail_rom:
+	usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER);
+fail_usb:
+	mtx_destroy(&sc->sc_mtx);
+	return (ENXIO);
+}
+
+static int
+rsu_detach(device_t self)
+{
+	struct rsu_softc *sc = device_get_softc(self);
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+
+	rsu_stop(ifp, 1);
+	usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER);
+	ieee80211_ifdetach(ic);
+
+	taskqueue_drain_timeout(taskqueue_thread, &sc->calib_task);
+
+	/* Free Tx/Rx buffers. */
+	rsu_free_tx_list(sc);
+	rsu_free_rx_list(sc);
+
+	if_free(ifp);
+	mtx_destroy(&sc->sc_mtx);
+
+	return (0);
+}
+
+static usb_error_t
+rsu_do_request(struct rsu_softc *sc, struct usb_device_request *req,
+    void *data)
+{
+	usb_error_t err;
+	int ntries = 10;
+	
+	RSU_ASSERT_LOCKED(sc);
+
+	while (ntries--) {
+		err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
+		    req, data, 0, NULL, 250 /* ms */);
+		if (err == 0 || err == USB_ERR_NOT_CONFIGURED)
+			break;
+		DPRINTFN(1, "Control request failed, %s (retrying)\n",
+		    usbd_errstr(err));
+		usb_pause_mtx(&sc->sc_mtx, hz / 100);
+        }
+
+        return (err);
+}
+
+static struct ieee80211vap *
+rsu_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
+    enum ieee80211_opmode opmode, int flags,
+    const uint8_t bssid[IEEE80211_ADDR_LEN],
+    const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+	struct rsu_vap *uvp;
+	struct ieee80211vap *vap;
+
+	if (!TAILQ_EMPTY(&ic->ic_vaps))         /* only one at a time */
+		return (NULL);
+
+	uvp = (struct rsu_vap *) malloc(sizeof(struct rsu_vap),
+	    M_80211_VAP, M_NOWAIT | M_ZERO);
+	if (uvp == NULL)
+		return (NULL);
+	vap = &uvp->vap;
+
+	if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
+	    flags, bssid, mac) != 0) {
+		/* out of memory */
+		free(uvp, M_80211_VAP);
+		return (NULL);
+	}
+
+	/* override state transition machine */
+	uvp->newstate = vap->iv_newstate;
+	vap->iv_newstate = rsu_newstate;
+
+	/* complete setup */
+	ieee80211_vap_attach(vap, ieee80211_media_change,
+	    ieee80211_media_status);
+	ic->ic_opmode = opmode;
+
+	return (vap);
+}
+
+static void
+rsu_vap_delete(struct ieee80211vap *vap)
+{
+	struct rsu_vap *uvp = RSU_VAP(vap);
+
+	ieee80211_vap_detach(vap);
+	free(uvp, M_80211_VAP);
+}
+
+static void
+rsu_scan_start(struct ieee80211com *ic)
+{
+	int error;
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rsu_softc *sc = ifp->if_softc;
+
+	/* Scanning is done by the firmware. */
+	RSU_LOCK(sc);
+	error = rsu_site_survey(sc, TAILQ_FIRST(&ic->ic_vaps));
+	RSU_UNLOCK(sc);
+	if (error != 0)
+		device_printf(sc->sc_dev,
+		    "could not send site survey command\n");
+}
+
+static void
+rsu_scan_end(struct ieee80211com *ic)
+{
+	/* Nothing to do here. */
+}
+
+static void
+rsu_set_channel(struct ieee80211com *ic __unused)
+{
+	/* We are unable to switch channels, yet. */
+}
+
+static void
+rsu_update_mcast(struct ifnet *ifp)
+{
+        /* XXX do nothing?  */
+}
+
+static int
+rsu_alloc_list(struct rsu_softc *sc, struct rsu_data data[],
+    int ndata, int maxsz)
+{
+	int i, error;
+
+	for (i = 0; i < ndata; i++) {
+		struct rsu_data *dp = &data[i];
+		dp->sc = sc;
+		dp->m = NULL;
+		dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT);
+		if (dp->buf == NULL) {
+			device_printf(sc->sc_dev,
+			    "could not allocate buffer\n");
+			error = ENOMEM;
+			goto fail;
+		}
+		dp->ni = NULL;
+	}
+
+	return (0);
+fail:
+	rsu_free_list(sc, data, ndata);
+	return (error);
+}
+
+static int
+rsu_alloc_rx_list(struct rsu_softc *sc)
+{
+        int error, i;
+
+	error = rsu_alloc_list(sc, sc->sc_rx, RSU_RX_LIST_COUNT,
+	    RSU_RXBUFSZ);
+	if (error != 0)
+		return (error);
+
+	STAILQ_INIT(&sc->sc_rx_active);
+	STAILQ_INIT(&sc->sc_rx_inactive);
+
+	for (i = 0; i < RSU_RX_LIST_COUNT; i++)
+		STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next);
+
+	return (0);
+}
+
+static int
+rsu_alloc_tx_list(struct rsu_softc *sc)
+{
+	int error, i;
+
+	error = rsu_alloc_list(sc, sc->sc_tx, RSU_TX_LIST_COUNT,
+	    RSU_TXBUFSZ);
+	if (error != 0)
+		return (error);
+
+	STAILQ_INIT(&sc->sc_tx_inactive);
+
+	for (i = 0; i != RSU_N_TRANSFER; i++) {
+		STAILQ_INIT(&sc->sc_tx_active[i]);
+		STAILQ_INIT(&sc->sc_tx_pending[i]);
+	}
+
+	for (i = 0; i < RSU_TX_LIST_COUNT; i++) {
+		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i], next);
+	}
+
+	return (0);
+}
+
+static void
+rsu_free_tx_list(struct rsu_softc *sc)
+{
+	int i;
+
+	/* prevent further allocations from TX list(s) */
+	STAILQ_INIT(&sc->sc_tx_inactive);
+
+	for (i = 0; i != RSU_N_TRANSFER; i++) {
+		STAILQ_INIT(&sc->sc_tx_active[i]);
+		STAILQ_INIT(&sc->sc_tx_pending[i]);
+	}
+
+	rsu_free_list(sc, sc->sc_tx, RSU_TX_LIST_COUNT);
+}
+
+static void
+rsu_free_rx_list(struct rsu_softc *sc)
+{
+	/* prevent further allocations from RX list(s) */
+	STAILQ_INIT(&sc->sc_rx_inactive);
+	STAILQ_INIT(&sc->sc_rx_active);
+
+	rsu_free_list(sc, sc->sc_rx, RSU_RX_LIST_COUNT);
+}
+
+static void
+rsu_free_list(struct rsu_softc *sc, struct rsu_data data[], int ndata)
+{
+	int i;
+
+	for (i = 0; i < ndata; i++) {
+		struct rsu_data *dp = &data[i];
+
+		if (dp->buf != NULL) {
+			free(dp->buf, M_USBDEV);
+			dp->buf = NULL;
+		}
+		if (dp->ni != NULL) {
+			ieee80211_free_node(dp->ni);
+			dp->ni = NULL;
+		}
+	}
+}
+
+static struct rsu_data *
+_rsu_getbuf(struct rsu_softc *sc)
+{
+	struct rsu_data *bf;
+
+	bf = STAILQ_FIRST(&sc->sc_tx_inactive);
+	if (bf != NULL)
+		STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
+	else
+		bf = NULL;
+	if (bf == NULL)
+		DPRINTF("out of xmit buffers\n");
+        return (bf);
+}
+
+static struct rsu_data *
+rsu_getbuf(struct rsu_softc *sc)
+{
+	struct rsu_data *bf;
+
+	RSU_ASSERT_LOCKED(sc);
+
+	bf = _rsu_getbuf(sc);
+	if (bf == NULL) {
+		struct ifnet *ifp = sc->sc_ifp;
+		DPRINTF("stop queue\n");
+		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+	}
+	return (bf);
+}
+
+static int
+rsu_write_region_1(struct rsu_softc *sc, uint16_t addr, uint8_t *buf,
+    int len)
+{
+	usb_device_request_t req;
+
+	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+	req.bRequest = R92S_REQ_REGS;
+	USETW(req.wValue, addr);
+	USETW(req.wIndex, 0);
+	USETW(req.wLength, len);
+
+	return (rsu_do_request(sc, &req, buf));
+}
+
+static void
+rsu_write_1(struct rsu_softc *sc, uint16_t addr, uint8_t val)
+{
+	rsu_write_region_1(sc, addr, &val, 1);
+}
+
+static void
+rsu_write_2(struct rsu_softc *sc, uint16_t addr, uint16_t val)
+{
+	val = htole16(val);
+	rsu_write_region_1(sc, addr, (uint8_t *)&val, 2);
+}
+
+static void
+rsu_write_4(struct rsu_softc *sc, uint16_t addr, uint32_t val)
+{
+	val = htole32(val);
+	rsu_write_region_1(sc, addr, (uint8_t *)&val, 4);
+}
+
+static int
+rsu_read_region_1(struct rsu_softc *sc, uint16_t addr, uint8_t *buf,
+    int len)
+{
+	usb_device_request_t req;
+
+	req.bmRequestType = UT_READ_VENDOR_DEVICE;
+	req.bRequest = R92S_REQ_REGS;
+	USETW(req.wValue, addr);
+	USETW(req.wIndex, 0);
+	USETW(req.wLength, len);
+
+	return (rsu_do_request(sc, &req, buf));
+}
+
+static uint8_t
+rsu_read_1(struct rsu_softc *sc, uint16_t addr)
+{
+	uint8_t val;
+
+	if (rsu_read_region_1(sc, addr, &val, 1) != 0)
+		return (0xff);
+	return (val);
+}
+
+static uint16_t
+rsu_read_2(struct rsu_softc *sc, uint16_t addr)
+{
+	uint16_t val;
+
+	if (rsu_read_region_1(sc, addr, (uint8_t *)&val, 2) != 0)
+		return (0xffff);
+	return (le16toh(val));
+}
+
+static uint32_t
+rsu_read_4(struct rsu_softc *sc, uint16_t addr)
+{
+	uint32_t val;
+
+	if (rsu_read_region_1(sc, addr, (uint8_t *)&val, 4) != 0)
+		return (0xffffffff);
+	return (le32toh(val));
+}
+
+static int
+rsu_fw_iocmd(struct rsu_softc *sc, uint32_t iocmd)
+{
+	int ntries;
+
+	rsu_write_4(sc, R92S_IOCMD_CTRL, iocmd);
+	rsu_ms_delay(sc);
+	for (ntries = 0; ntries < 50; ntries++) {
+		if (rsu_read_4(sc, R92S_IOCMD_CTRL) == 0)
+			return (0);
+		rsu_ms_delay(sc);
+	}
+	return (ETIMEDOUT);
+}
+
+static uint8_t
+rsu_efuse_read_1(struct rsu_softc *sc, uint16_t addr)
+{
+	uint32_t reg;
+	int ntries;
+
+	reg = rsu_read_4(sc, R92S_EFUSE_CTRL);
+	reg = RW(reg, R92S_EFUSE_CTRL_ADDR, addr);
+	reg &= ~R92S_EFUSE_CTRL_VALID;
+	rsu_write_4(sc, R92S_EFUSE_CTRL, reg);
+	/* Wait for read operation to complete. */
+	for (ntries = 0; ntries < 100; ntries++) {
+		reg = rsu_read_4(sc, R92S_EFUSE_CTRL);
+		if (reg & R92S_EFUSE_CTRL_VALID)
+			return (MS(reg, R92S_EFUSE_CTRL_DATA));
+		rsu_ms_delay(sc);
+	}
+	device_printf(sc->sc_dev,
+	    "could not read efuse byte at address 0x%x\n", addr);
+	return (0xff);
+}
+
+static int
+rsu_read_rom(struct rsu_softc *sc)
+{
+	uint8_t *rom = sc->rom;
+	uint16_t addr = 0;
+	uint32_t reg;
+	uint8_t off, msk;
+	int i;
+
+	/* Make sure that ROM type is eFuse and that autoload succeeded. */
+	reg = rsu_read_1(sc, R92S_EE_9346CR);
+	if ((reg & (R92S_9356SEL | R92S_EEPROM_EN)) != R92S_EEPROM_EN)
+		return (EIO);
+
+	/* Turn on 2.5V to prevent eFuse leakage. */
+	reg = rsu_read_1(sc, R92S_EFUSE_TEST + 3);
+	rsu_write_1(sc, R92S_EFUSE_TEST + 3, reg | 0x80);
+	rsu_ms_delay(sc);
+	rsu_write_1(sc, R92S_EFUSE_TEST + 3, reg & ~0x80);
+
+	/* Read full ROM image. */
+	memset(&sc->rom, 0xff, sizeof(sc->rom));
+	while (addr < 512) {
+		reg = rsu_efuse_read_1(sc, addr);
+		if (reg == 0xff)
+			break;
+		addr++;
+		off = reg >> 4;
+		msk = reg & 0xf;
+		for (i = 0; i < 4; i++) {
+			if (msk & (1 << i))
+				continue;
+			rom[off * 8 + i * 2 + 0] =
+			    rsu_efuse_read_1(sc, addr);
+			addr++;
+			rom[off * 8 + i * 2 + 1] =
+			    rsu_efuse_read_1(sc, addr);
+			addr++;
+		}
+	}
+#ifdef USB_DEBUG
+	if (rsu_debug >= 5) {
+		/* Dump ROM content. */
+		printf("\n");
+		for (i = 0; i < sizeof(sc->rom); i++)
+			printf("%02x:", rom[i]);
+		printf("\n");
+	}
+#endif
+	return (0);
+}
+
+static int
+rsu_fw_cmd(struct rsu_softc *sc, uint8_t code, void *buf, int len)
+{
+	const uint8_t which = rsu_wme_ac_xfer_map[WME_AC_VO];
+	struct rsu_data *data;
+	struct r92s_tx_desc *txd;
+	struct r92s_fw_cmd_hdr *cmd;
+	int cmdsz;
+	int xferlen;
+
+	data = rsu_getbuf(sc);
+	if (data == NULL)
+		return (ENOMEM);
+
+	/* Round-up command length to a multiple of 8 bytes. */
+	cmdsz = (len + 7) & ~7;
+
+	xferlen = sizeof(*txd) + sizeof(*cmd) + cmdsz;
+	KASSERT(xferlen <= RSU_TXBUFSZ, ("%s: invalid length", __func__));
+	memset(data->buf, 0, xferlen);
+
+	/* Setup Tx descriptor. */
+	txd = (struct r92s_tx_desc *)data->buf;
+	txd->txdw0 = htole32(
+	    SM(R92S_TXDW0_OFFSET, sizeof(*txd)) |
+	    SM(R92S_TXDW0_PKTLEN, sizeof(*cmd) + cmdsz) |
+	    R92S_TXDW0_OWN | R92S_TXDW0_FSG | R92S_TXDW0_LSG);
+	txd->txdw1 = htole32(SM(R92S_TXDW1_QSEL, R92S_TXDW1_QSEL_H2C));
+
+	/* Setup command header. */
+	cmd = (struct r92s_fw_cmd_hdr *)&txd[1];
+	cmd->len = htole16(cmdsz);
+	cmd->code = code;
+	cmd->seq = sc->cmd_seq;
+	sc->cmd_seq = (sc->cmd_seq + 1) & 0x7f;
+
+	/* Copy command payload. */
+	memcpy(&cmd[1], buf, len);
+
+	DPRINTFN(2, "Tx cmd code=0x%x len=0x%x\n", code, cmdsz);
+	data->buflen = xferlen;
+	STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next);
+	usbd_transfer_start(sc->sc_xfer[which]);
+
+	return (0);
+}
+
+/* ARGSUSED */
+static void
+rsu_calib_task(void *arg, int pending __unused)
+{
+	struct rsu_softc *sc = arg;
+	uint32_t reg;
+
+	DPRINTFN(6, "running calibration task\n");
+
+	RSU_LOCK(sc);
+#ifdef notyet
+	/* Read WPS PBC status. */
+	rsu_write_1(sc, R92S_MAC_PINMUX_CTRL,
+	    R92S_GPIOMUX_EN | SM(R92S_GPIOSEL_GPIO, R92S_GPIOSEL_GPIO_JTAG));
+	rsu_write_1(sc, R92S_GPIO_IO_SEL,
+	    rsu_read_1(sc, R92S_GPIO_IO_SEL) & ~R92S_GPIO_WPS);
+	reg = rsu_read_1(sc, R92S_GPIO_CTRL);
+	if (reg != 0xff && (reg & R92S_GPIO_WPS))
+		DPRINTF(("WPS PBC is pushed\n"));
+#endif
+	/* Read current signal level. */
+	if (rsu_fw_iocmd(sc, 0xf4000001) == 0) {
+		reg = rsu_read_4(sc, R92S_IOCMD_DATA);
+		DPRINTFN(8, "RSSI=%d%%\n", reg >> 4);
+	}
+	if (sc->sc_calibrating)
+		taskqueue_enqueue_timeout(taskqueue_thread, &sc->calib_task, hz);
+	RSU_UNLOCK(sc);
+}
+
+static int
+rsu_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
+{
+	struct rsu_vap *uvp = RSU_VAP(vap);
+	struct ieee80211com *ic = vap->iv_ic;
+	struct rsu_softc *sc = ic->ic_ifp->if_softc;
+	struct ieee80211_node *ni;
+	struct ieee80211_rateset *rs;
+	enum ieee80211_state ostate;
+	int error, startcal = 0;
+
+	ostate = vap->iv_state;
+	DPRINTF("%s -> %s\n", ieee80211_state_name[ostate],
+	    ieee80211_state_name[nstate]);
+
+	IEEE80211_UNLOCK(ic);
+	if (ostate == IEEE80211_S_RUN) {
+		RSU_LOCK(sc);
+		/* Stop calibration. */
+		sc->sc_calibrating = 0;
+		RSU_UNLOCK(sc);
+		taskqueue_drain_timeout(taskqueue_thread, &sc->calib_task);
+		/* Disassociate from our current BSS. */
+		RSU_LOCK(sc);
+		rsu_disconnect(sc);
+	} else
+		RSU_LOCK(sc);
+	switch (nstate) {
+	case IEEE80211_S_INIT:
+		break;
+	case IEEE80211_S_AUTH:
+		ni = ieee80211_ref_node(vap->iv_bss);
+		error = rsu_join_bss(sc, ni);
+		ieee80211_free_node(ni);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "could not send join command\n");
+		}
+		break;
+	case IEEE80211_S_RUN:
+		ni = ieee80211_ref_node(vap->iv_bss);
+		rs = &ni->ni_rates;
+		/* Indicate highest supported rate. */
+		ni->ni_txrate = rs->rs_rates[rs->rs_nrates - 1];
+		ieee80211_free_node(ni);
+		startcal = 1;
+		break;
+	default:
+		break;
+	}
+	sc->sc_calibrating = 1;
+	/* Start periodic calibration. */
+	taskqueue_enqueue_timeout(taskqueue_thread, &sc->calib_task, hz);
+	RSU_UNLOCK(sc);
+	IEEE80211_LOCK(ic);
+	return (uvp->newstate(vap, nstate, arg));
+}
+
+#ifdef notyet
+static void
+rsu_set_key(struct rsu_softc *sc, const struct ieee80211_key *k)
+{
+	struct r92s_fw_cmd_set_key key;
+
+	memset(&key, 0, sizeof(key));
+	/* Map net80211 cipher to HW crypto algorithm. */
+	switch (k->wk_cipher->ic_cipher) {
+	case IEEE80211_CIPHER_WEP:
+		if (k->wk_keylen < 8)
+			key.algo = R92S_KEY_ALGO_WEP40;
+		else
+			key.algo = R92S_KEY_ALGO_WEP104;
+		break;
+	case IEEE80211_CIPHER_TKIP:
+		key.algo = R92S_KEY_ALGO_TKIP;
+		break;
+	case IEEE80211_CIPHER_AES_CCM:
+		key.algo = R92S_KEY_ALGO_AES;
+		break;
+	default:
+		return;
+	}
+	key.id = k->wk_keyix;
+	key.grpkey = (k->wk_flags & IEEE80211_KEY_GROUP) != 0;
+	memcpy(key.key, k->wk_key, MIN(k->wk_keylen, sizeof(key.key)));
+	(void)rsu_fw_cmd(sc, R92S_CMD_SET_KEY, &key, sizeof(key));
+}
+
+static void
+rsu_delete_key(struct rsu_softc *sc, const struct ieee80211_key *k)
+{
+	struct r92s_fw_cmd_set_key key;
+
+	memset(&key, 0, sizeof(key));
+	key.id = k->wk_keyix;
+	(void)rsu_fw_cmd(sc, R92S_CMD_SET_KEY, &key, sizeof(key));
+}
+#endif
+
+static int
+rsu_site_survey(struct rsu_softc *sc, struct ieee80211vap *vap)
+{
+	struct r92s_fw_cmd_sitesurvey cmd;
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+
+	memset(&cmd, 0, sizeof(cmd));
+	if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->scan_pass == 1)
+		cmd.active = htole32(1);
+	cmd.limit = htole32(48);
+	if (sc->scan_pass == 1 && vap->iv_des_nssid > 0) {
+		/* Do a directed scan for second pass. */
+		cmd.ssidlen = htole32(vap->iv_des_ssid[0].len);
+		memcpy(cmd.ssid, vap->iv_des_ssid[0].ssid,
+		    vap->iv_des_ssid[0].len);
+
+	}
+	DPRINTF("sending site survey command, pass=%d\n", sc->scan_pass);
+	return (rsu_fw_cmd(sc, R92S_CMD_SITE_SURVEY, &cmd, sizeof(cmd)));
+}
+
+static int
+rsu_join_bss(struct rsu_softc *sc, struct ieee80211_node *ni)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211vap *vap = ni->ni_vap;
+	struct ndis_wlan_bssid_ex *bss;
+	struct ndis_802_11_fixed_ies *fixed;
+	struct r92s_fw_cmd_auth auth;
+	uint8_t buf[sizeof(*bss) + 128] __aligned(4);
+	uint8_t *frm;
+	uint8_t opmode;
+	int error;
+
+	/* Let the FW decide the opmode based on the capinfo field. */
+	opmode = NDIS802_11AUTOUNKNOWN;
+	DPRINTF("setting operating mode to %d\n", opmode);
+	error = rsu_fw_cmd(sc, R92S_CMD_SET_OPMODE, &opmode, sizeof(opmode));
+	if (error != 0)
+		return (error);
+
+	memset(&auth, 0, sizeof(auth));
+	if (vap->iv_flags & IEEE80211_F_WPA) {
+		auth.mode = R92S_AUTHMODE_WPA;
+		auth.dot1x = (ni->ni_authmode == IEEE80211_AUTH_8021X);
+	} else
+		auth.mode = R92S_AUTHMODE_OPEN;
+	DPRINTF("setting auth mode to %d\n", auth.mode);
+	error = rsu_fw_cmd(sc, R92S_CMD_SET_AUTH, &auth, sizeof(auth));
+	if (error != 0)
+		return (error);
+
+	memset(buf, 0, sizeof(buf));
+	bss = (struct ndis_wlan_bssid_ex *)buf;
+	IEEE80211_ADDR_COPY(bss->macaddr, ni->ni_bssid);
+	bss->ssid.ssidlen = htole32(ni->ni_esslen);
+	memcpy(bss->ssid.ssid, ni->ni_essid, ni->ni_esslen);
+	if (vap->iv_flags & (IEEE80211_F_PRIVACY | IEEE80211_F_WPA))
+		bss->privacy = htole32(1);
+	bss->rssi = htole32(ni->ni_avgrssi);
+	if (ic->ic_curmode == IEEE80211_MODE_11B)
+		bss->networktype = htole32(NDIS802_11DS);
+	else
+		bss->networktype = htole32(NDIS802_11OFDM24);
+	bss->config.len = htole32(sizeof(bss->config));
+	bss->config.bintval = htole32(ni->ni_intval);
+	bss->config.dsconfig = htole32(ieee80211_chan2ieee(ic, ni->ni_chan));
+	bss->inframode = htole32(NDIS802_11INFRASTRUCTURE);
+	memcpy(bss->supprates, ni->ni_rates.rs_rates,
+	    ni->ni_rates.rs_nrates);
+	/* Write the fixed fields of the beacon frame. */
+	fixed = (struct ndis_802_11_fixed_ies *)&bss[1];
+	memcpy(&fixed->tstamp, ni->ni_tstamp.data, 8);
+	fixed->bintval = htole16(ni->ni_intval);
+	fixed->capabilities = htole16(ni->ni_capinfo);
+	/* Write IEs to be included in the association request. */
+	frm = (uint8_t *)&fixed[1];
+	frm = ieee80211_add_rsn(frm, vap);
+	frm = ieee80211_add_wpa(frm, vap);
+	frm = ieee80211_add_qos(frm, ni);
+	if (ni->ni_flags & IEEE80211_NODE_HT)
+		frm = ieee80211_add_htcap(frm, ni);
+	bss->ieslen = htole32(frm - (uint8_t *)fixed);
+	bss->len = htole32(((frm - buf) + 3) & ~3);
+	DPRINTF("sending join bss command to %s chan %d\n",
+	    ether_sprintf(bss->macaddr), le32toh(bss->config.dsconfig));
+	return (rsu_fw_cmd(sc, R92S_CMD_JOIN_BSS, buf, sizeof(buf)));
+}
+
+static int
+rsu_disconnect(struct rsu_softc *sc)
+{
+	uint32_t zero = 0;	/* :-) */
+
+	/* Disassociate from our current BSS. */
+	DPRINTF("sending disconnect command\n");
+	return (rsu_fw_cmd(sc, R92S_CMD_DISCONNECT, &zero, sizeof(zero)));
+}
+
+CTASSERT(MCLBYTES > sizeof(struct ieee80211_frame));
+
+static void
+rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211_frame *wh;
+	struct ieee80211_channel *c;
+	struct ndis_wlan_bssid_ex *bss;
+	struct mbuf *m;
+	uint32_t ieslen;
+	uint32_t pktlen;
+
+	if (__predict_false(len < sizeof(*bss)))
+		return;
+	bss = (struct ndis_wlan_bssid_ex *)buf;
+	ieslen = le32toh(bss->ieslen);
+	/* range check length of information element */
+	if (__predict_false(ieslen > (uint32_t)(len - sizeof(*bss))))
+		return;
+
+	DPRINTFN(2, "found BSS %s: len=%d chan=%d inframode=%d "
+	    "networktype=%d privacy=%d\n",
+	    ether_sprintf(bss->macaddr), ieslen,
+	    le32toh(bss->config.dsconfig), le32toh(bss->inframode),
+	    le32toh(bss->networktype), le32toh(bss->privacy));
+
+	/* Build a fake beacon frame to let net80211 do all the parsing. */
+	if (__predict_false(ieslen > (size_t)(MCLBYTES - sizeof(*wh))))
+		return;
+	pktlen = sizeof(*wh) + ieslen;
+	m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR);
+	if (__predict_false(m == NULL))
+		return;
+	wh = mtod(m, struct ieee80211_frame *);
+	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
+	    IEEE80211_FC0_SUBTYPE_BEACON;
+	wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
+	USETW(wh->i_dur, 0);
+	IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
+	IEEE80211_ADDR_COPY(wh->i_addr2, bss->macaddr);
+	IEEE80211_ADDR_COPY(wh->i_addr3, bss->macaddr);
+	*(uint16_t *)wh->i_seq = 0;
+	memcpy(&wh[1], (uint8_t *)&bss[1], ieslen);
+
+	/* Finalize mbuf. */
+	m->m_pkthdr.len = m->m_len = pktlen;
+	m->m_pkthdr.rcvif = ifp;
+	/* Fix the channel. */
+	c = ieee80211_find_channel_byieee(ic, 
+	    le32toh(bss->config.dsconfig), 
+	    IEEE80211_CHAN_G);
+	if (c) {
+		ic->ic_curchan = c;
+		ieee80211_radiotap_chan_change(ic);
+	}
+	/* XXX avoid a LOR */
+	RSU_UNLOCK(sc);
+	ieee80211_input_all(ic, m, le32toh(bss->rssi), 0);
+	RSU_LOCK(sc);
+}
+
+static void
+rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+	struct ieee80211_node *ni = vap->iv_bss;
+	struct r92s_event_join_bss *rsp;
+	uint32_t tmp;
+	int res;
+
+	if (__predict_false(len < sizeof(*rsp)))
+		return;
+	rsp = (struct r92s_event_join_bss *)buf;
+	res = (int)le32toh(rsp->join_res);
+
+	DPRINTF("Rx join BSS event len=%d res=%d\n", len, res);
+	if (res <= 0) {
+		RSU_UNLOCK(sc);
+		ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
+		RSU_LOCK(sc);
+		return;
+	}
+	tmp = le32toh(rsp->associd);
+	if (tmp >= vap->iv_max_aid) {
+		DPRINTF("Assoc ID overflow\n");
+		tmp = 1;
+	}
+	DPRINTF("associated with %s associd=%d\n",
+	    ether_sprintf(rsp->bss.macaddr), tmp);
+	ni->ni_associd = tmp | 0xc000;
+	RSU_UNLOCK(sc);
+	ieee80211_new_state(vap, IEEE80211_S_RUN,
+	    IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
+	RSU_LOCK(sc);
+}
+
+static void
+rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+
+	DPRINTFN(4, "Rx event code=%d len=%d\n", code, len);
+	switch (code) {
+	case R92S_EVT_SURVEY:
+		if (vap->iv_state == IEEE80211_S_SCAN)
+			rsu_event_survey(sc, buf, len);
+		break;
+	case R92S_EVT_SURVEY_DONE:
+		DPRINTF("site survey pass %d done, found %d BSS\n",
+		    sc->scan_pass, le32toh(*(uint32_t *)buf));
+		if (vap->iv_state != IEEE80211_S_SCAN)
+			break;	/* Ignore if not scanning. */
+		if (sc->scan_pass == 0 && vap->iv_des_nssid != 0) {
+			/* Schedule a directed scan for hidden APs. */
+			sc->scan_pass = 1;
+			RSU_UNLOCK(sc);
+			ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
+			RSU_LOCK(sc);
+			break;
+		}
+		sc->scan_pass = 0;
+		break;
+	case R92S_EVT_JOIN_BSS:
+		if (vap->iv_state == IEEE80211_S_AUTH)
+			rsu_event_join_bss(sc, buf, len);
+		break;
+#if 0
+XXX This event is occurring regularly, possibly due to some power saving event
+XXX and disrupts the WLAN traffic. Disable for now.
+	case R92S_EVT_DEL_STA:
+		DPRINTF("disassociated from %s\n", ether_sprintf(buf));
+		if (vap->iv_state == IEEE80211_S_RUN &&
+		    IEEE80211_ADDR_EQ(vap->iv_bss->ni_bssid, buf)) {
+			RSU_UNLOCK(sc);
+			ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
+			RSU_LOCK(sc);
+		}
+		break;
+#endif
+	case R92S_EVT_WPS_PBC:
+		DPRINTF("WPS PBC pushed.\n");
+		break;
+	case R92S_EVT_FWDBG:
+		if (ifp->if_flags & IFF_DEBUG) {
+			buf[60] = '\0';
+			printf("FWDBG: %s\n", (char *)buf);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+rsu_rx_multi_event(struct rsu_softc *sc, uint8_t *buf, int len)
+{
+	struct r92s_fw_cmd_hdr *cmd;
+	int cmdsz;
+
+	DPRINTFN(6, "Rx events len=%d\n", len);
+
+	/* Skip Rx status. */
+	buf += sizeof(struct r92s_rx_stat);
+	len -= sizeof(struct r92s_rx_stat);
+
+	/* Process all events. */
+	for (;;) {
+		/* Check that command header fits. */
+		if (__predict_false(len < sizeof(*cmd)))
+			break;
+		cmd = (struct r92s_fw_cmd_hdr *)buf;
+		/* Check that command payload fits. */
+		cmdsz = le16toh(cmd->len);
+		if (__predict_false(len < sizeof(*cmd) + cmdsz))
+			break;
+
+		/* Process firmware event. */
+		rsu_rx_event(sc, cmd->code, (uint8_t *)&cmd[1], cmdsz);
+
+		if (!(cmd->seq & R92S_FW_CMD_MORE))
+			break;
+		buf += sizeof(*cmd) + cmdsz;
+		len -= sizeof(*cmd) + cmdsz;
+	}
+}
+
+static int8_t
+rsu_get_rssi(struct rsu_softc *sc, int rate, void *physt)
+{
+	static const int8_t cckoff[] = { 14, -2, -20, -40 };
+	struct r92s_rx_phystat *phy;
+	struct r92s_rx_cck *cck;
+	uint8_t rpt;
+	int8_t rssi;
+
+	if (rate <= 3) {
+		cck = (struct r92s_rx_cck *)physt;
+		rpt = (cck->agc_rpt >> 6) & 0x3;
+		rssi = cck->agc_rpt & 0x3e;
+		rssi = cckoff[rpt] - rssi;
+	} else {	/* OFDM/HT. */
+		phy = (struct r92s_rx_phystat *)physt;
+		rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 106;
+	}
+	return (rssi);
+}
+
+static struct mbuf *
+rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211_frame *wh;
+	struct r92s_rx_stat *stat;
+	uint32_t rxdw0, rxdw3;
+	struct mbuf *m;
+	uint8_t rate;
+	int infosz;
+
+	stat = (struct r92s_rx_stat *)buf;
+	rxdw0 = le32toh(stat->rxdw0);
+	rxdw3 = le32toh(stat->rxdw3);
+
+	if (__predict_false(rxdw0 & R92S_RXDW0_CRCERR)) {
+		ifp->if_ierrors++;
+		return NULL;
+	}
+	if (__predict_false(pktlen < sizeof(*wh) || pktlen > MCLBYTES)) {
+		ifp->if_ierrors++;
+		return NULL;
+	}
+
+	rate = MS(rxdw3, R92S_RXDW3_RATE);
+	infosz = MS(rxdw0, R92S_RXDW0_INFOSZ) * 8;
+
+	/* Get RSSI from PHY status descriptor if present. */
+	if (infosz != 0)
+		*rssi = rsu_get_rssi(sc, rate, &stat[1]);
+	else
+		*rssi = 0;
+
+	DPRINTFN(5, "Rx frame len=%d rate=%d infosz=%d rssi=%d\n",
+	    pktlen, rate, infosz, *rssi);
+
+	MGETHDR(m, M_NOWAIT, MT_DATA);
+	if (__predict_false(m == NULL)) {
+		ifp->if_ierrors++;
+		return NULL;
+	}
+	if (pktlen > MHLEN) {
+		MCLGET(m, M_NOWAIT);
+		if (__predict_false(!(m->m_flags & M_EXT))) {
+			ifp->if_ierrors++;
+			m_freem(m);
+			return NULL;
+		}
+	}
+	/* Finalize mbuf. */
+	m->m_pkthdr.rcvif = ifp;
+	/* Hardware does Rx TCP checksum offload. */
+	if (rxdw3 & R92S_RXDW3_TCPCHKVALID) {
+		if (__predict_true(rxdw3 & R92S_RXDW3_TCPCHKRPT))
+			m->m_pkthdr.csum_flags |= CSUM_DATA_VALID;
+	}
+	wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz);
+	memcpy(mtod(m, uint8_t *), wh, pktlen);
+	m->m_pkthdr.len = m->m_len = pktlen;
+
+	if (ieee80211_radiotap_active(ic)) {
+		struct rsu_rx_radiotap_header *tap = &sc->sc_rxtap;
+
+		/* Map HW rate index to 802.11 rate. */
+		tap->wr_flags = 2;
+		if (!(rxdw3 & R92S_RXDW3_HTC)) {
+			switch (rate) {
+			/* CCK. */
+			case  0: tap->wr_rate =   2; break;
+			case  1: tap->wr_rate =   4; break;
+			case  2: tap->wr_rate =  11; break;
+			case  3: tap->wr_rate =  22; break;
+			/* OFDM. */
+			case  4: tap->wr_rate =  12; break;
+			case  5: tap->wr_rate =  18; break;
+			case  6: tap->wr_rate =  24; break;
+			case  7: tap->wr_rate =  36; break;
+			case  8: tap->wr_rate =  48; break;
+			case  9: tap->wr_rate =  72; break;
+			case 10: tap->wr_rate =  96; break;
+			case 11: tap->wr_rate = 108; break;
+			}
+		} else if (rate >= 12) {	/* MCS0~15. */
+			/* Bit 7 set means HT MCS instead of rate. */
+			tap->wr_rate = 0x80 | (rate - 12);
+		}
+		tap->wr_dbm_antsignal = *rssi;
+		tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
+		tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
+	}
+
+	return (m);
+}
+
+static struct mbuf *
+rsu_rx_multi_frame(struct rsu_softc *sc, uint8_t *buf, int len, int *rssi)
+{
+	struct r92s_rx_stat *stat;
+	uint32_t rxdw0;
+	int totlen, pktlen, infosz, npkts;
+	struct mbuf *m, *m0 = NULL, *prevm = NULL;
+
+	/* Get the number of encapsulated frames. */
+	stat = (struct r92s_rx_stat *)buf;
+	npkts = MS(le32toh(stat->rxdw2), R92S_RXDW2_PKTCNT);
+	DPRINTFN(6, "Rx %d frames in one chunk\n", npkts);
+
+	/* Process all of them. */
+	while (npkts-- > 0) {
+		if (__predict_false(len < sizeof(*stat)))
+			break;
+		stat = (struct r92s_rx_stat *)buf;
+		rxdw0 = le32toh(stat->rxdw0);
+
+		pktlen = MS(rxdw0, R92S_RXDW0_PKTLEN);
+		if (__predict_false(pktlen == 0))
+			break;
+
+		infosz = MS(rxdw0, R92S_RXDW0_INFOSZ) * 8;
+
+		/* Make sure everything fits in xfer. */
+		totlen = sizeof(*stat) + infosz + pktlen;
+		if (__predict_false(totlen > len))
+			break;
+
+		/* Process 802.11 frame. */
+		m = rsu_rx_frame(sc, buf, pktlen, rssi);
+		if (m0 == NULL)
+			m0 = m;
+		if (prevm == NULL)
+			prevm = m;
+		else {
+			prevm->m_next = m;
+			prevm = m;
+		}
+		/* Next chunk is 128-byte aligned. */
+		totlen = (totlen + 127) & ~127;
+		buf += totlen;
+		len -= totlen;
+	}
+
+	return (m0);
+}
+
+static struct mbuf *
+rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi)
+{
+	struct rsu_softc *sc = data->sc;
+	struct r92s_rx_stat *stat;
+	int len;
+
+	usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
+
+	if (__predict_false(len < sizeof(*stat))) {
+		DPRINTF("xfer too short %d\n", len);
+		sc->sc_ifp->if_ierrors++;
+		return (NULL);
+	}
+	/* Determine if it is a firmware C2H event or an 802.11 frame. */
+	stat = (struct r92s_rx_stat *)data->buf;
+	if ((le32toh(stat->rxdw1) & 0x1ff) == 0x1ff) {
+		rsu_rx_multi_event(sc, data->buf, len);
+		/* No packets to process. */
+		return (NULL);
+	} else
+		return (rsu_rx_multi_frame(sc, data->buf, len, rssi));
+}
+
+static void
+rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct rsu_softc *sc = usbd_xfer_softc(xfer);
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211_frame *wh;
+	struct ieee80211_node *ni;
+	struct mbuf *m = NULL, *next;
+	struct rsu_data *data;
+	int rssi = 1;
+
+	RSU_ASSERT_LOCKED(sc);
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		data = STAILQ_FIRST(&sc->sc_rx_active);
+		if (data == NULL)
+			goto tr_setup;
+		STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
+		m = rsu_rxeof(xfer, data, &rssi);
+		STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
+		/* FALLTHROUGH */
+	case USB_ST_SETUP:
+tr_setup:
+		data = STAILQ_FIRST(&sc->sc_rx_inactive);
+		if (data == NULL) {
+			KASSERT(m == NULL, ("mbuf isn't NULL"));
+			return;
+		}
+		STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
+		STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
+		usbd_xfer_set_frame_data(xfer, 0, data->buf,
+		    usbd_xfer_max_len(xfer));
+		usbd_transfer_submit(xfer);
+		/*
+		 * To avoid LOR we should unlock our private mutex here to call
+		 * ieee80211_input() because here is at the end of a USB
+		 * callback and safe to unlock.
+		 */
+		RSU_UNLOCK(sc);
+		while (m != NULL) {
+			next = m->m_next;
+			m->m_next = NULL;
+			wh = mtod(m, struct ieee80211_frame *);
+			ni = ieee80211_find_rxnode(ic,
+			    (struct ieee80211_frame_min *)wh);
+			if (ni != NULL) {
+				(void)ieee80211_input(ni, m, rssi, 0);
+				ieee80211_free_node(ni);
+			} else
+				(void)ieee80211_input_all(ic, m, rssi, 0);
+			m = next;
+		}
+		RSU_LOCK(sc);
+		break;
+	default:
+		/* needs it to the inactive queue due to a error. */
+		data = STAILQ_FIRST(&sc->sc_rx_active);
+		if (data != NULL) {
+			STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
+			STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
+		}
+		if (error != USB_ERR_CANCELLED) {
+			usbd_xfer_set_stall(xfer);
+			ifp->if_ierrors++;
+			goto tr_setup;
+		}
+		break;
+	}
+
+}
+
+
+static void
+rsu_txeof(struct usb_xfer *xfer, struct rsu_data *data)
+{
+	struct rsu_softc *sc = usbd_xfer_softc(xfer);
+	struct ifnet *ifp = sc->sc_ifp;
+	struct mbuf *m;
+
+	RSU_ASSERT_LOCKED(sc);
+
+	/*
+	 * Do any tx complete callback.  Note this must be done before releasing
+	 * the node reference.
+	 */
+	if (data->m) {
+		m = data->m;
+		if (m->m_flags & M_TXCB) {
+			/* XXX status? */
+			ieee80211_process_callback(data->ni, m, 0);
+		}
+		m_freem(m);
+		data->m = NULL;
+	}
+	if (data->ni) {
+		ieee80211_free_node(data->ni);
+		data->ni = NULL;
+	}
+	ifp->if_opackets++;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+}
+
+static void
+rsu_bulk_tx_callback_sub(struct usb_xfer *xfer, usb_error_t error,
+    uint8_t which)
+{
+	struct rsu_softc *sc = usbd_xfer_softc(xfer);
+	struct ifnet *ifp = sc->sc_ifp;
+	struct rsu_data *data;
+
+	RSU_ASSERT_LOCKED(sc);
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		data = STAILQ_FIRST(&sc->sc_tx_active[which]);
+		if (data == NULL)
+			goto tr_setup;
+		DPRINTF("transfer done %p\n", data);
+		STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next);
+		rsu_txeof(xfer, data);
+		STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
+		/* FALLTHROUGH */
+	case USB_ST_SETUP:
+tr_setup:
+		data = STAILQ_FIRST(&sc->sc_tx_pending[which]);
+		if (data == NULL) {
+			DPRINTF("empty pending queue sc %p\n", sc);
+			return;
+		}
+		STAILQ_REMOVE_HEAD(&sc->sc_tx_pending[which], next);
+		STAILQ_INSERT_TAIL(&sc->sc_tx_active[which], data, next);
+		usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
+		DPRINTF("submitting transfer %p\n", data);
+		usbd_transfer_submit(xfer);
+		break;
+	default:
+		data = STAILQ_FIRST(&sc->sc_tx_active[which]);
+		if (data != NULL) {
+			STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next);
+			rsu_txeof(xfer, data);
+			STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
+		}
+		ifp->if_oerrors++;
+
+		if (error != USB_ERR_CANCELLED) {
+			usbd_xfer_set_stall(xfer);
+			goto tr_setup;
+		}
+		break;
+	}
+}
+
+static void
+rsu_bulk_tx_callback_be_bk(struct usb_xfer *xfer, usb_error_t error)
+{
+	rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_BE_BK);
+}
+
+static void
+rsu_bulk_tx_callback_vi_vo(struct usb_xfer *xfer, usb_error_t error)
+{
+	rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_VI_VO);
+}
+
+static int
+rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, 
+    struct mbuf *m0, struct rsu_data *data)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+        struct ieee80211vap *vap = ni->ni_vap;
+	struct ieee80211_frame *wh;
+	struct ieee80211_key *k = NULL;
+	struct r92s_tx_desc *txd;
+	uint8_t type;
+	uint8_t tid = 0;
+	uint8_t which;
+	int hasqos;
+	int xferlen;
+
+	RSU_ASSERT_LOCKED(sc);
+
+	wh = mtod(m0, struct ieee80211_frame *);
+	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+
+	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
+		k = ieee80211_crypto_encap(ni, m0);
+		if (k == NULL) {
+			device_printf(sc->sc_dev,
+			    "ieee80211_crypto_encap returns NULL.\n");
+			/* XXX we don't expect the fragmented frames */
+			m_freem(m0);
+			return (ENOBUFS);
+		}
+		wh = mtod(m0, struct ieee80211_frame *);
+	}
+	switch (type) {
+	case IEEE80211_FC0_TYPE_CTL:
+	case IEEE80211_FC0_TYPE_MGT:
+		which = rsu_wme_ac_xfer_map[WME_AC_VO];
+		break;
+	default:
+		which = rsu_wme_ac_xfer_map[M_WME_GETAC(m0)];
+		break;
+	}
+	hasqos = 0;
+
+	/* Fill Tx descriptor. */
+	txd = (struct r92s_tx_desc *)data->buf;
+	memset(txd, 0, sizeof(*txd));
+
+	txd->txdw0 |= htole32(
+	    SM(R92S_TXDW0_PKTLEN, m0->m_pkthdr.len) |
+	    SM(R92S_TXDW0_OFFSET, sizeof(*txd)) |
+	    R92S_TXDW0_OWN | R92S_TXDW0_FSG | R92S_TXDW0_LSG);
+
+	txd->txdw1 |= htole32(
+	    SM(R92S_TXDW1_MACID, R92S_MACID_BSS) |
+	    SM(R92S_TXDW1_QSEL, R92S_TXDW1_QSEL_BE));
+	if (!hasqos)
+		txd->txdw1 |= htole32(R92S_TXDW1_NONQOS);
+#ifdef notyet
+	if (k != NULL) {
+		switch (k->wk_cipher->ic_cipher) {
+		case IEEE80211_CIPHER_WEP:
+			cipher = R92S_TXDW1_CIPHER_WEP;
+			break;
+		case IEEE80211_CIPHER_TKIP:
+			cipher = R92S_TXDW1_CIPHER_TKIP;
+			break;
+		case IEEE80211_CIPHER_AES_CCM:
+			cipher = R92S_TXDW1_CIPHER_AES;
+			break;
+		default:
+			cipher = R92S_TXDW1_CIPHER_NONE;
+		}
+		txd->txdw1 |= htole32(
+		    SM(R92S_TXDW1_CIPHER, cipher) |
+		    SM(R92S_TXDW1_KEYIDX, k->k_id));
+	}
+#endif
+	txd->txdw2 |= htole32(R92S_TXDW2_BK);
+	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
+		txd->txdw2 |= htole32(R92S_TXDW2_BMCAST);
+	/*
+	 * Firmware will use and increment the sequence number for the
+	 * specified TID.
+	 */
+	txd->txdw3 |= htole32(SM(R92S_TXDW3_SEQ, tid));
+
+	if (ieee80211_radiotap_active_vap(vap)) {
+		struct rsu_tx_radiotap_header *tap = &sc->sc_txtap;
+
+		tap->wt_flags = 0;
+		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
+		ieee80211_radiotap_tx(vap, m0);
+	}
+	xferlen = sizeof(*txd) + m0->m_pkthdr.len;
+	m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&txd[1]);
+
+	data->buflen = xferlen;
+	data->ni = ni;
+	data->m = m0;
+	STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next);
+
+	/* start transfer, if any */
+	usbd_transfer_start(sc->sc_xfer[which]);
+	return (0);
+}
+
+static void
+rsu_start(struct ifnet *ifp)
+{
+	struct rsu_softc *sc = ifp->if_softc;
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+		return;
+
+	RSU_LOCK(sc);
+	rsu_start_locked(ifp);
+	RSU_UNLOCK(sc);
+}
+
+static void
+rsu_start_locked(struct ifnet *ifp)
+{
+	struct rsu_softc *sc = ifp->if_softc;
+	struct ieee80211_node *ni;
+	struct rsu_data *bf;
+	struct mbuf *m;
+
+	RSU_ASSERT_LOCKED(sc);
+
+	for (;;) {
+		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+		if (m == NULL)
+			break;
+		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+		m->m_pkthdr.rcvif = NULL;
+
+		bf = rsu_getbuf(sc);
+		if (bf == NULL) {
+			ifp->if_iqdrops++;
+			m_freem(m);
+			ieee80211_free_node(ni);
+		} else if (rsu_tx_start(sc, ni, m, bf) != 0) {
+			ifp->if_oerrors++;
+			STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
+			ieee80211_free_node(ni);
+		}
+	}
+}
+
+static int
+rsu_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ifreq *ifr = (struct ifreq *) data;
+	int error = 0, startall = 0;
+
+	switch (cmd) {
+	case SIOCSIFFLAGS:
+		if (ifp->if_flags & IFF_UP) {
+			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+				rsu_init(ifp->if_softc);
+				startall = 1;
+			}
+		} else {
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+				rsu_stop(ifp, 1);
+		}
+		if (startall)
+			ieee80211_start_all(ic);
+		break;
+	case SIOCGIFMEDIA:
+		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
+		break;
+	case SIOCGIFADDR:
+		error = ether_ioctl(ifp, cmd, data);
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+
+	return (error);
+}
+
+/*
+ * Power on sequence for A-cut adapters.
+ */
+static void
+rsu_power_on_acut(struct rsu_softc *sc)
+{
+	uint32_t reg;
+
+	rsu_write_1(sc, R92S_SPS0_CTRL + 1, 0x53);
+	rsu_write_1(sc, R92S_SPS0_CTRL + 0, 0x57);
+
+	/* Enable AFE macro block's bandgap and Mbias. */
+	rsu_write_1(sc, R92S_AFE_MISC,
+	    rsu_read_1(sc, R92S_AFE_MISC) |
+	    R92S_AFE_MISC_BGEN | R92S_AFE_MISC_MBEN);
+	/* Enable LDOA15 block. */
+	rsu_write_1(sc, R92S_LDOA15_CTRL,
+	    rsu_read_1(sc, R92S_LDOA15_CTRL) | R92S_LDA15_EN);
+
+	rsu_write_1(sc, R92S_SPS1_CTRL,
+	    rsu_read_1(sc, R92S_SPS1_CTRL) | R92S_SPS1_LDEN);
+	usb_pause_mtx(&sc->sc_mtx, 2 * hz);
+	/* Enable switch regulator block. */
+	rsu_write_1(sc, R92S_SPS1_CTRL,
+	    rsu_read_1(sc, R92S_SPS1_CTRL) | R92S_SPS1_SWEN);
+
+	rsu_write_4(sc, R92S_SPS1_CTRL, 0x00a7b267);
+
+	rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1,
+	    rsu_read_1(sc, R92S_SYS_ISO_CTRL + 1) | 0x08);
+
+	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
+	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x20);
+
+	rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1,
+	    rsu_read_1(sc, R92S_SYS_ISO_CTRL + 1) & ~0x90);
+
+	/* Enable AFE clock. */
+	rsu_write_1(sc, R92S_AFE_XTAL_CTRL + 1,
+	    rsu_read_1(sc, R92S_AFE_XTAL_CTRL + 1) & ~0x04);
+	/* Enable AFE PLL macro block. */
+	rsu_write_1(sc, R92S_AFE_PLL_CTRL,
+	    rsu_read_1(sc, R92S_AFE_PLL_CTRL) | 0x11);
+	/* Attach AFE PLL to MACTOP/BB. */
+	rsu_write_1(sc, R92S_SYS_ISO_CTRL,
+	    rsu_read_1(sc, R92S_SYS_ISO_CTRL) & ~0x11);
+
+	/* Switch to 40MHz clock instead of 80MHz. */
+	rsu_write_2(sc, R92S_SYS_CLKR,
+	    rsu_read_2(sc, R92S_SYS_CLKR) & ~R92S_SYS_CLKSEL);
+
+	/* Enable MAC clock. */
+	rsu_write_2(sc, R92S_SYS_CLKR,
+	    rsu_read_2(sc, R92S_SYS_CLKR) |
+	    R92S_MAC_CLK_EN | R92S_SYS_CLK_EN);
+
+	rsu_write_1(sc, R92S_PMC_FSM, 0x02);
+
+	/* Enable digital core and IOREG R/W. */
+	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
+	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x08);
+
+	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
+	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x80);
+
+	/* Switch the control path to firmware. */
+	reg = rsu_read_2(sc, R92S_SYS_CLKR);
+	reg = (reg & ~R92S_SWHW_SEL) | R92S_FWHW_SEL;
+	rsu_write_2(sc, R92S_SYS_CLKR, reg);
+
+	rsu_write_2(sc, R92S_CR, 0x37fc);
+
+	/* Fix USB RX FIFO issue. */
+	rsu_write_1(sc, 0xfe5c,
+	    rsu_read_1(sc, 0xfe5c) | 0x80);
+	rsu_write_1(sc, 0x00ab,
+	    rsu_read_1(sc, 0x00ab) | 0xc0);
+
+	rsu_write_1(sc, R92S_SYS_CLKR,
+	    rsu_read_1(sc, R92S_SYS_CLKR) & ~R92S_SYS_CPU_CLKSEL);
+}
+
+/*
+ * Power on sequence for B-cut and C-cut adapters.
+ */
+static void
+rsu_power_on_bcut(struct rsu_softc *sc)
+{
+	uint32_t reg;
+	int ntries;
+
+	/* Prevent eFuse leakage. */
+	rsu_write_1(sc, 0x37, 0xb0);
+	usb_pause_mtx(&sc->sc_mtx, hz / 100);
+	rsu_write_1(sc, 0x37, 0x30);
+
+	/* Switch the control path to hardware. */
+	reg = rsu_read_2(sc, R92S_SYS_CLKR);
+	if (reg & R92S_FWHW_SEL) {
+		rsu_write_2(sc, R92S_SYS_CLKR,
+		    reg & ~(R92S_SWHW_SEL | R92S_FWHW_SEL));
+	}
+	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
+	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) & ~0x8c);
+	rsu_ms_delay(sc);
+
+	rsu_write_1(sc, R92S_SPS0_CTRL + 1, 0x53);
+	rsu_write_1(sc, R92S_SPS0_CTRL + 0, 0x57);
+
+	reg = rsu_read_1(sc, R92S_AFE_MISC);
+	rsu_write_1(sc, R92S_AFE_MISC, reg | R92S_AFE_MISC_BGEN);
+	rsu_write_1(sc, R92S_AFE_MISC, reg | R92S_AFE_MISC_BGEN |
+	    R92S_AFE_MISC_MBEN | R92S_AFE_MISC_I32_EN);
+
+	/* Enable PLL. */
+	rsu_write_1(sc, R92S_LDOA15_CTRL,
+	    rsu_read_1(sc, R92S_LDOA15_CTRL) | R92S_LDA15_EN);
+
+	rsu_write_1(sc, R92S_LDOV12D_CTRL,
+	    rsu_read_1(sc, R92S_LDOV12D_CTRL) | R92S_LDV12_EN);
+
+	rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1,
+	    rsu_read_1(sc, R92S_SYS_ISO_CTRL + 1) | 0x08);
+
+	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
+	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x20);
+
+	/* Support 64KB IMEM. */
+	rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1,
+	    rsu_read_1(sc, R92S_SYS_ISO_CTRL + 1) & ~0x97);
+
+	/* Enable AFE clock. */
+	rsu_write_1(sc, R92S_AFE_XTAL_CTRL + 1,
+	    rsu_read_1(sc, R92S_AFE_XTAL_CTRL + 1) & ~0x04);
+	/* Enable AFE PLL macro block. */
+	reg = rsu_read_1(sc, R92S_AFE_PLL_CTRL);
+	rsu_write_1(sc, R92S_AFE_PLL_CTRL, reg | 0x11);
+	rsu_ms_delay(sc);
+	rsu_write_1(sc, R92S_AFE_PLL_CTRL, reg | 0x51);
+	rsu_ms_delay(sc);
+	rsu_write_1(sc, R92S_AFE_PLL_CTRL, reg | 0x11);
+	rsu_ms_delay(sc);
+
+	/* Attach AFE PLL to MACTOP/BB. */
+	rsu_write_1(sc, R92S_SYS_ISO_CTRL,
+	    rsu_read_1(sc, R92S_SYS_ISO_CTRL) & ~0x11);
+
+	/* Switch to 40MHz clock. */
+	rsu_write_1(sc, R92S_SYS_CLKR, 0x00);
+	/* Disable CPU clock and 80MHz SSC. */
+	rsu_write_1(sc, R92S_SYS_CLKR,
+	    rsu_read_1(sc, R92S_SYS_CLKR) | 0xa0);
+	/* Enable MAC clock. */
+	rsu_write_2(sc, R92S_SYS_CLKR,
+	    rsu_read_2(sc, R92S_SYS_CLKR) |
+	    R92S_MAC_CLK_EN | R92S_SYS_CLK_EN);
+
+	rsu_write_1(sc, R92S_PMC_FSM, 0x02);
+
+	/* Enable digital core and IOREG R/W. */
+	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
+	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x08);
+
+	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
+	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x80);
+
+	/* Switch the control path to firmware. */
+	reg = rsu_read_2(sc, R92S_SYS_CLKR);
+	reg = (reg & ~R92S_SWHW_SEL) | R92S_FWHW_SEL;
+	rsu_write_2(sc, R92S_SYS_CLKR, reg);
+
+	rsu_write_2(sc, R92S_CR, 0x37fc);
+
+	/* Fix USB RX FIFO issue. */
+	rsu_write_1(sc, 0xfe5c,
+	    rsu_read_1(sc, 0xfe5c) | 0x80);
+
+	rsu_write_1(sc, R92S_SYS_CLKR,
+	    rsu_read_1(sc, R92S_SYS_CLKR) & ~R92S_SYS_CPU_CLKSEL);
+
+	rsu_write_1(sc, 0xfe1c, 0x80);
+
+	/* Make sure TxDMA is ready to download firmware. */
+	for (ntries = 0; ntries < 20; ntries++) {
+		reg = rsu_read_1(sc, R92S_TCR);
+		if ((reg & (R92S_TCR_IMEM_CHK_RPT | R92S_TCR_EMEM_CHK_RPT)) ==
+		    (R92S_TCR_IMEM_CHK_RPT | R92S_TCR_EMEM_CHK_RPT))
+			break;
+		rsu_ms_delay(sc);
+	}
+	if (ntries == 20) {
+		DPRINTF("TxDMA is not ready\n");
+		/* Reset TxDMA. */
+		reg = rsu_read_1(sc, R92S_CR);
+		rsu_write_1(sc, R92S_CR, reg & ~R92S_CR_TXDMA_EN);
+		rsu_ms_delay(sc);
+		rsu_write_1(sc, R92S_CR, reg | R92S_CR_TXDMA_EN);
+	}
+}
+
+static void
+rsu_power_off(struct rsu_softc *sc)
+{
+	/* Turn RF off. */
+	rsu_write_1(sc, R92S_RF_CTRL, 0x00);
+	usb_pause_mtx(&sc->sc_mtx, hz / 200);
+
+	/* Turn MAC off. */
+	/* Switch control path. */
+	rsu_write_1(sc, R92S_SYS_CLKR + 1, 0x38);
+	/* Reset MACTOP. */
+	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 0x70);
+	rsu_write_1(sc, R92S_PMC_FSM, 0x06);
+	rsu_write_1(sc, R92S_SYS_ISO_CTRL + 0, 0xf9);
+	rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1, 0xe8);
+
+	/* Disable AFE PLL. */
+	rsu_write_1(sc, R92S_AFE_PLL_CTRL, 0x00);
+	/* Disable A15V. */
+	rsu_write_1(sc, R92S_LDOA15_CTRL, 0x54);
+	/* Disable eFuse 1.2V. */
+	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 0x50);
+	rsu_write_1(sc, R92S_LDOV12D_CTRL, 0x24);
+	/* Enable AFE macro block's bandgap and Mbias. */
+	rsu_write_1(sc, R92S_AFE_MISC, 0x30);
+	/* Disable 1.6V LDO. */
+	rsu_write_1(sc, R92S_SPS0_CTRL + 0, 0x56);
+	rsu_write_1(sc, R92S_SPS0_CTRL + 1, 0x43);
+}
+
+static int
+rsu_fw_loadsection(struct rsu_softc *sc, const uint8_t *buf, int len)
+{
+	const uint8_t which = rsu_wme_ac_xfer_map[WME_AC_VO];
+	struct rsu_data *data;
+	struct r92s_tx_desc *txd;
+	int mlen;
+
+	while (len > 0) {
+		data = rsu_getbuf(sc);
+		if (data == NULL)
+			return (ENOMEM);
+		txd = (struct r92s_tx_desc *)data->buf;
+		memset(txd, 0, sizeof(*txd));
+		if (len <= RSU_TXBUFSZ - sizeof(*txd)) {
+			/* Last chunk. */
+			txd->txdw0 |= htole32(R92S_TXDW0_LINIP);
+			mlen = len;
+		} else
+			mlen = RSU_TXBUFSZ - sizeof(*txd);
+		txd->txdw0 |= htole32(SM(R92S_TXDW0_PKTLEN, mlen));
+		memcpy(&txd[1], buf, mlen);
+		data->buflen = sizeof(*txd) + mlen;
+		DPRINTF("starting transfer %p\n", data);
+		STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next);
+		buf += mlen;
+		len -= mlen;
+	}
+	usbd_transfer_start(sc->sc_xfer[which]);
+	return (0);
+}
+
+CTASSERT(sizeof(size_t) >= sizeof(uint32_t));
+
+static int
+rsu_load_firmware(struct rsu_softc *sc)
+{
+	const struct r92s_fw_hdr *hdr;
+	struct r92s_fw_priv *dmem;
+	const uint8_t *imem, *emem;
+	uint32_t imemsz, ememsz;
+	const struct firmware *fw;
+	size_t size;
+	uint32_t reg;
+	int ntries, error;
+
+	if (rsu_read_1(sc, R92S_TCR) & R92S_TCR_FWRDY) {
+		DPRINTF("Firmware already loaded\n");
+		return (0);
+	}
+
+	RSU_UNLOCK(sc);
+	/* Read firmware image from the filesystem. */
+	if ((fw = firmware_get("rsu-rtl8712fw")) == NULL) {
+		device_printf(sc->sc_dev, 
+		    "%s: failed load firmware of file rsu-rtl8712fw\n",
+		    __func__);
+		RSU_LOCK(sc);
+		return (ENXIO);
+	}
+	RSU_LOCK(sc);
+	size = fw->datasize;
+	if (size < sizeof(*hdr)) {
+		device_printf(sc->sc_dev, "firmware too short\n");
+		error = EINVAL;
+		goto fail;
+	}
+	hdr = (const struct r92s_fw_hdr *)fw->data;
+	if (hdr->signature != htole16(0x8712) &&
+	    hdr->signature != htole16(0x8192)) {
+		device_printf(sc->sc_dev,
+		    "invalid firmware signature 0x%x\n",
+		    le16toh(hdr->signature));
+		error = EINVAL;
+		goto fail;
+	}
+	DPRINTF("FW V%d %02x-%02x %02x:%02x\n", le16toh(hdr->version),
+	    hdr->month, hdr->day, hdr->hour, hdr->minute);
+
+	/* Make sure that driver and firmware are in sync. */
+	if (hdr->privsz != htole32(sizeof(*dmem))) {
+		device_printf(sc->sc_dev, "unsupported firmware image\n");
+		error = EINVAL;
+		goto fail;
+	}
+	/* Get FW sections sizes. */
+	imemsz = le32toh(hdr->imemsz);
+	ememsz = le32toh(hdr->sramsz);
+	/* Check that all FW sections fit in image. */
+	if (imemsz > (size_t)(size - sizeof(*hdr)) ||
+	    ememsz > (size_t)(size - sizeof(*hdr) - imemsz)) {
+		device_printf(sc->sc_dev, "firmware too short\n");
+		error = EINVAL;
+		goto fail;
+	}
+	imem = (const uint8_t *)&hdr[1];
+	emem = imem + imemsz;
+
+	/* Load IMEM section. */
+	error = rsu_fw_loadsection(sc, imem, imemsz);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "could not load firmware section %s\n", "IMEM");
+		goto fail;
+	}
+	/* Wait for load to complete. */
+	for (ntries = 0; ntries != 50; ntries++) {
+		usb_pause_mtx(&sc->sc_mtx, hz / 100);
+		reg = rsu_read_1(sc, R92S_TCR);
+		if (reg & R92S_TCR_IMEM_CODE_DONE)
+			break;
+	}
+	if (ntries == 50) {
+		device_printf(sc->sc_dev, "timeout waiting for IMEM transfer\n");
+		error = ETIMEDOUT;
+		goto fail;
+	}
+	/* Load EMEM section. */
+	error = rsu_fw_loadsection(sc, emem, ememsz);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "could not load firmware section %s\n", "EMEM");
+		goto fail;
+	}
+	/* Wait for load to complete. */
+	for (ntries = 0; ntries != 50; ntries++) {
+		usb_pause_mtx(&sc->sc_mtx, hz / 100);
+		reg = rsu_read_2(sc, R92S_TCR);
+		if (reg & R92S_TCR_EMEM_CODE_DONE)
+			break;
+	}
+	if (ntries == 50) {
+		device_printf(sc->sc_dev, "timeout waiting for EMEM transfer\n");
+		error = ETIMEDOUT;
+		goto fail;
+	}
+	/* Enable CPU. */
+	rsu_write_1(sc, R92S_SYS_CLKR,
+	    rsu_read_1(sc, R92S_SYS_CLKR) | R92S_SYS_CPU_CLKSEL);
+	if (!(rsu_read_1(sc, R92S_SYS_CLKR) & R92S_SYS_CPU_CLKSEL)) {
+		device_printf(sc->sc_dev, "could not enable system clock\n");
+		error = EIO;
+		goto fail;
+	}
+	rsu_write_2(sc, R92S_SYS_FUNC_EN,
+	    rsu_read_2(sc, R92S_SYS_FUNC_EN) | R92S_FEN_CPUEN);
+	if (!(rsu_read_2(sc, R92S_SYS_FUNC_EN) & R92S_FEN_CPUEN)) {
+		device_printf(sc->sc_dev, 
+		    "could not enable microcontroller\n");
+		error = EIO;
+		goto fail;
+	}
+	/* Wait for CPU to initialize. */
+	for (ntries = 0; ntries < 100; ntries++) {
+		if (rsu_read_1(sc, R92S_TCR) & R92S_TCR_IMEM_RDY)
+			break;
+		rsu_ms_delay(sc);
+	}
+	if (ntries == 100) {
+		device_printf(sc->sc_dev,
+		    "timeout waiting for microcontroller\n");
+		error = ETIMEDOUT;
+		goto fail;
+	}
+
+	/* Update DMEM section before loading. */
+	dmem = __DECONST(struct r92s_fw_priv *, &hdr->priv);
+	memset(dmem, 0, sizeof(*dmem));
+	dmem->hci_sel = R92S_HCI_SEL_USB | R92S_HCI_SEL_8172;
+	dmem->nendpoints = 0;
+	dmem->rf_config = 0x12;	/* 1T2R */
+	dmem->vcs_type = R92S_VCS_TYPE_AUTO;
+	dmem->vcs_mode = R92S_VCS_MODE_RTS_CTS;
+#ifdef notyet
+	dmem->bw40_en = (ic->ic_htcaps & IEEE80211_HTCAP_CBW20_40) != 0;
+#endif
+	dmem->turbo_mode = 1;
+	/* Load DMEM section. */
+	error = rsu_fw_loadsection(sc, (uint8_t *)dmem, sizeof(*dmem));
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "could not load firmware section %s\n", "DMEM");
+		goto fail;
+	}
+	/* Wait for load to complete. */
+	for (ntries = 0; ntries < 100; ntries++) {
+		if (rsu_read_1(sc, R92S_TCR) & R92S_TCR_DMEM_CODE_DONE)
+			break;
+		rsu_ms_delay(sc);
+	}
+	if (ntries == 100) {
+		device_printf(sc->sc_dev, "timeout waiting for %s transfer\n",
+		    "DMEM");
+		error = ETIMEDOUT;
+		goto fail;
+	}
+	/* Wait for firmware readiness. */
+	for (ntries = 0; ntries < 60; ntries++) {
+		if (!(rsu_read_1(sc, R92S_TCR) & R92S_TCR_FWRDY))
+			break;
+		rsu_ms_delay(sc);
+	}
+	if (ntries == 60) {
+		device_printf(sc->sc_dev, 
+		    "timeout waiting for firmware readiness\n");
+		error = ETIMEDOUT;
+		goto fail;
+	}
+ fail:
+	firmware_put(fw, FIRMWARE_UNLOAD);
+	return (error);
+}
+
+
+static int	
+rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 
+    const struct ieee80211_bpf_params *params)
+{
+	struct ieee80211com *ic = ni->ni_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rsu_softc *sc = ifp->if_softc;
+	struct rsu_data *bf;
+
+	/* prevent management frames from being sent if we're not ready */
+	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+		m_freem(m);
+		ieee80211_free_node(ni);
+		return (ENETDOWN);
+	}
+	RSU_LOCK(sc);
+	bf = rsu_getbuf(sc);
+	if (bf == NULL) {
+		ieee80211_free_node(ni);
+		m_freem(m);
+		RSU_UNLOCK(sc);
+		return (ENOBUFS);
+	}
+	ifp->if_opackets++;
+	if (rsu_tx_start(sc, ni, m, bf) != 0) {
+		ieee80211_free_node(ni);
+		ifp->if_oerrors++;
+		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
+		RSU_UNLOCK(sc);
+		return (EIO);
+	}
+	RSU_UNLOCK(sc);
+
+	return (0);
+}
+
+static void
+rsu_init(void *arg)
+{
+	struct rsu_softc *sc = arg;
+
+	RSU_LOCK(sc);
+	rsu_init_locked(arg);
+	RSU_UNLOCK(sc);
+}
+
+static void
+rsu_init_locked(struct rsu_softc *sc)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	struct r92s_set_pwr_mode cmd;
+	int error;
+	int i;
+
+	/* Init host async commands ring. */
+	sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0;
+
+	/* Power on adapter. */
+	if (sc->cut == 1)
+		rsu_power_on_acut(sc);
+	else
+		rsu_power_on_bcut(sc);
+
+	/* Load firmware. */
+	error = rsu_load_firmware(sc);
+	if (error != 0)
+		goto fail;
+
+	/* Enable Rx TCP checksum offload. */
+	rsu_write_4(sc, R92S_RCR,
+	    rsu_read_4(sc, R92S_RCR) | 0x04000000);
+	/* Append PHY status. */
+	rsu_write_4(sc, R92S_RCR,
+	    rsu_read_4(sc, R92S_RCR) | 0x02000000);
+
+	rsu_write_4(sc, R92S_CR,
+	    rsu_read_4(sc, R92S_CR) & ~0xff000000);
+
+	/* Use 128 bytes pages. */
+	rsu_write_1(sc, 0x00b5,
+	    rsu_read_1(sc, 0x00b5) | 0x01);
+	/* Enable USB Rx aggregation. */
+	rsu_write_1(sc, 0x00bd,
+	    rsu_read_1(sc, 0x00bd) | 0x80);
+	/* Set USB Rx aggregation threshold. */
+	rsu_write_1(sc, 0x00d9, 0x01);
+	/* Set USB Rx aggregation timeout (1.7ms/4). */
+	rsu_write_1(sc, 0xfe5b, 0x04);
+	/* Fix USB Rx FIFO issue. */
+	rsu_write_1(sc, 0xfe5c,
+	    rsu_read_1(sc, 0xfe5c) | 0x80);
+
+	/* Set MAC address. */
+	rsu_write_region_1(sc, R92S_MACID, IF_LLADDR(ifp), 
+	    IEEE80211_ADDR_LEN);
+
+	/* It really takes 1.5 seconds for the firmware to boot: */
+	usb_pause_mtx(&sc->sc_mtx, (3 * hz) / 2);
+
+	DPRINTF("setting MAC address to %s\n", ether_sprintf(IF_LLADDR(ifp)));
+	error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, IF_LLADDR(ifp),
+	    IEEE80211_ADDR_LEN);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not set MAC address\n");
+		goto fail;
+	}
+
+	rsu_write_1(sc, R92S_USB_HRPWM,
+	    R92S_USB_HRPWM_PS_ST_ACTIVE | R92S_USB_HRPWM_PS_ALL_ON);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.mode = R92S_PS_MODE_ACTIVE;
+	DPRINTF("setting ps mode to %d\n", cmd.mode);
+	error = rsu_fw_cmd(sc, R92S_CMD_SET_PWR_MODE, &cmd, sizeof(cmd));
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not set PS mode\n");
+		goto fail;
+	}
+
+#if 0
+	if (ic->ic_htcaps & IEEE80211_HTCAP_CBW20_40) {
+		/* Enable 40MHz mode. */
+		error = rsu_fw_iocmd(sc,
+		    SM(R92S_IOCMD_CLASS, 0xf4) |
+		    SM(R92S_IOCMD_INDEX, 0x00) |
+		    SM(R92S_IOCMD_VALUE, 0x0007));
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "could not enable 40MHz mode\n");
+			goto fail;
+		}
+	}
+
+	/* Set default channel. */
+	ic->ic_bss->ni_chan = ic->ic_ibss_chan;
+#endif
+	sc->scan_pass = 0;
+	usbd_transfer_start(sc->sc_xfer[RSU_BULK_RX]);
+
+	/* We're ready to go. */
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+	return;
+fail:
+	/* Need to stop all failed transfers, if any */
+	for (i = 0; i != RSU_N_TRANSFER; i++)
+		usbd_transfer_stop(sc->sc_xfer[i]);
+}
+
+static void
+rsu_stop(struct ifnet *ifp, int disable)
+{
+	struct rsu_softc *sc = ifp->if_softc;
+
+	RSU_LOCK(sc);
+	rsu_stop_locked(ifp, disable);
+	RSU_UNLOCK(sc);
+}
+
+static void
+rsu_stop_locked(struct ifnet *ifp, int disable __unused)
+{
+	struct rsu_softc *sc = ifp->if_softc;
+	int i;
+
+	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+	sc->sc_calibrating = 0;
+	taskqueue_cancel_timeout(taskqueue_thread, &sc->calib_task, NULL);
+
+	/* Power off adapter. */
+	rsu_power_off(sc);
+
+	for (i = 0; i < RSU_N_TRANSFER; i++)
+		usbd_transfer_stop(sc->sc_xfer[i]);
+}
+
+static void
+rsu_ms_delay(struct rsu_softc *sc)
+{
+	usb_pause_mtx(&sc->sc_mtx, hz / 1000);
+}


Property changes on: trunk/sys/dev/usb/wlan/if_rsu.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/dev/usb/wlan/if_rsureg.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_rsureg.h	                        (rev 0)
+++ trunk/sys/dev/usb/wlan/if_rsureg.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -0,0 +1,771 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini at free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $OpenBSD: if_rsureg.h,v 1.3 2013/04/15 09:23:01 mglocker Exp $
+ * $FreeBSD: stable/10/sys/dev/usb/wlan/if_rsureg.h 267349 2014-06-11 05:50:04Z hselasky $
+ */
+
+/* USB Requests. */
+#define R92S_REQ_REGS	0x05
+
+/*
+ * MAC registers.
+ */
+#define R92S_SYSCFG		0x0000
+#define R92S_SYS_ISO_CTRL	(R92S_SYSCFG + 0x000)
+#define R92S_SYS_FUNC_EN	(R92S_SYSCFG + 0x002)
+#define R92S_PMC_FSM		(R92S_SYSCFG + 0x004)
+#define R92S_SYS_CLKR		(R92S_SYSCFG + 0x008)
+#define R92S_EE_9346CR		(R92S_SYSCFG + 0x00a)
+#define R92S_AFE_MISC		(R92S_SYSCFG + 0x010)
+#define R92S_SPS0_CTRL		(R92S_SYSCFG + 0x011)
+#define R92S_SPS1_CTRL		(R92S_SYSCFG + 0x018)
+#define R92S_RF_CTRL		(R92S_SYSCFG + 0x01f)
+#define R92S_LDOA15_CTRL	(R92S_SYSCFG + 0x020)
+#define R92S_LDOV12D_CTRL	(R92S_SYSCFG + 0x021)
+#define R92S_AFE_XTAL_CTRL	(R92S_SYSCFG + 0x026)
+#define R92S_AFE_PLL_CTRL	(R92S_SYSCFG + 0x028)
+#define R92S_EFUSE_CTRL		(R92S_SYSCFG + 0x030)
+#define R92S_EFUSE_TEST		(R92S_SYSCFG + 0x034)
+#define R92S_EFUSE_CLK_CTRL	(R92S_SYSCFG + 0x2f8)
+
+#define R92S_CMDCTRL		0x0040
+#define R92S_CR			(R92S_CMDCTRL + 0x000)
+#define R92S_TCR		(R92S_CMDCTRL + 0x004)
+#define R92S_RCR		(R92S_CMDCTRL + 0x008)
+
+#define R92S_MACIDSETTING	0x0050
+#define R92S_MACID		(R92S_MACIDSETTING + 0x000)
+
+#define R92S_GP			0x01e0
+#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_IOCMD_CTRL		0x0370
+#define R92S_IOCMD_DATA		0x0374
+
+#define R92S_USB_HRPWM		0xfe58
+
+/* Bits for R92S_SYS_FUNC_EN. */
+#define R92S_FEN_CPUEN	0x0400
+
+/* Bits for R92S_PMC_FSM. */
+#define R92S_PMC_FSM_CUT_M	0x000f8000
+#define R92S_PMC_FSM_CUT_S	15
+
+/* Bits for R92S_SYS_CLKR. */
+#define R92S_SYS_CLKSEL		0x0001
+#define R92S_SYS_PS_CLKSEL	0x0002
+#define R92S_SYS_CPU_CLKSEL	0x0004
+#define R92S_MAC_CLK_EN		0x0800
+#define R92S_SYS_CLK_EN		0x1000
+#define R92S_SWHW_SEL		0x4000
+#define R92S_FWHW_SEL		0x8000
+
+/* Bits for R92S_EE_9346CR. */
+#define R92S_9356SEL		0x10
+#define R92S_EEPROM_EN		0x20
+
+/* Bits for R92S_AFE_MISC. */
+#define R92S_AFE_MISC_BGEN	0x01
+#define R92S_AFE_MISC_MBEN	0x02
+#define R92S_AFE_MISC_I32_EN	0x08
+
+/* Bits for R92S_SPS1_CTRL. */
+#define R92S_SPS1_LDEN	0x01
+#define R92S_SPS1_SWEN	0x02
+
+/* Bits for R92S_LDOA15_CTRL. */
+#define R92S_LDA15_EN	0x01
+
+/* Bits for R92S_LDOV12D_CTRL. */
+#define R92S_LDV12_EN	0x01
+
+/* Bits for R92C_EFUSE_CTRL. */
+#define R92S_EFUSE_CTRL_DATA_M	0x000000ff
+#define R92S_EFUSE_CTRL_DATA_S	0
+#define R92S_EFUSE_CTRL_ADDR_M	0x0003ff00
+#define R92S_EFUSE_CTRL_ADDR_S	8
+#define R92S_EFUSE_CTRL_VALID	0x80000000
+
+/* Bits for R92S_CR. */
+#define R92S_CR_TXDMA_EN	0x10
+
+/* Bits for R92S_TCR. */
+#define R92S_TCR_IMEM_CODE_DONE	0x01
+#define R92S_TCR_IMEM_CHK_RPT	0x02
+#define R92S_TCR_EMEM_CODE_DONE	0x04
+#define R92S_TCR_EMEM_CHK_RPT	0x08
+#define R92S_TCR_DMEM_CODE_DONE	0x10
+#define R92S_TCR_IMEM_RDY	0x20
+#define R92S_TCR_FWRDY		0x80
+
+/* Bits for R92S_GPIO_IO_SEL. */
+#define R92S_GPIO_WPS	0x10
+
+/* Bits for R92S_MAC_PINMUX_CTRL. */
+#define R92S_GPIOSEL_GPIO_M		0x03
+#define R92S_GPIOSEL_GPIO_S		0
+#define R92S_GPIOSEL_GPIO_JTAG		0
+#define R92S_GPIOSEL_GPIO_PHYDBG	1
+#define R92S_GPIOSEL_GPIO_BT		2
+#define R92S_GPIOSEL_GPIO_WLANDBG	3
+#define R92S_GPIOMUX_EN			0x08
+
+/* Bits for R92S_IOCMD_CTRL. */
+#define R92S_IOCMD_CLASS_M		0xff000000
+#define R92S_IOCMD_CLASS_S		24
+#define R92S_IOCMD_CLASS_BB_RF		0xf0
+#define R92S_IOCMD_VALUE_M		0x00ffff00
+#define R92S_IOCMD_VALUE_S		8
+#define R92S_IOCMD_INDEX_M		0x000000ff
+#define R92S_IOCMD_INDEX_S		0
+#define R92S_IOCMD_INDEX_BB_READ	0
+#define R92S_IOCMD_INDEX_BB_WRITE	1
+#define R92S_IOCMD_INDEX_RF_READ	2
+#define R92S_IOCMD_INDEX_RF_WRITE	3
+
+/* Bits for R92S_USB_HRPWM. */
+#define R92S_USB_HRPWM_PS_ALL_ON	0x04
+#define R92S_USB_HRPWM_PS_ST_ACTIVE	0x08
+
+/*
+ * Macros to access subfields in registers.
+ */
+/* Mask and Shift (getter). */
+#define MS(val, field)							\
+	(((val) & field##_M) >> field##_S)
+
+/* Shift and Mask (setter). */
+#define SM(field, val)							\
+	(((val) << field##_S) & field##_M)
+
+/* Rewrite. */
+#define RW(var, field, val)						\
+	(((var) & ~field##_M) | SM(field, val))
+
+/*
+ * Firmware image header.
+ */
+struct r92s_fw_priv {
+	/* QWORD0 */
+	uint16_t	signature;
+	uint8_t		hci_sel;
+#define R92S_HCI_SEL_PCIE	0x01
+#define R92S_HCI_SEL_USB	0x02
+#define R92S_HCI_SEL_SDIO	0x04
+#define R92S_HCI_SEL_8172	0x10
+#define R92S_HCI_SEL_AP		0x80
+
+	uint8_t		chip_version;
+	uint16_t	custid;
+	uint8_t		rf_config;
+	uint8_t		nendpoints;
+	/* QWORD1 */
+	uint32_t	regulatory;
+	uint8_t		rfintfs;
+	uint8_t		def_nettype;
+	uint8_t		turbo_mode;
+	uint8_t		lowpower_mode;
+	/* QWORD2 */
+	uint8_t		lbk_mode;
+	uint8_t		mp_mode;
+	uint8_t		vcs_type;
+#define R92S_VCS_TYPE_DISABLE	0
+#define R92S_VCS_TYPE_ENABLE	1
+#define R92S_VCS_TYPE_AUTO	2
+
+	uint8_t		vcs_mode;
+#define R92S_VCS_MODE_NONE	0
+#define R92S_VCS_MODE_RTS_CTS	1
+#define R92S_VCS_MODE_CTS2SELF	2
+
+	uint32_t	reserved1;
+	/* QWORD3 */
+	uint8_t		qos_en;
+	uint8_t		bw40_en;
+	uint8_t		amsdu2ampdu_en;
+	uint8_t		ampdu_en;
+	uint8_t		rc_offload;
+	uint8_t		agg_offload;
+	uint16_t	reserved2;
+	/* QWORD4 */
+	uint8_t		beacon_offload;
+	uint8_t		mlme_offload;
+	uint8_t		hwpc_offload;
+	uint8_t		tcpcsum_offload;
+	uint8_t		tcp_offload;
+	uint8_t		ps_offload;
+	uint8_t		wwlan_offload;
+	uint8_t		reserved3;
+	/* QWORD5 */
+	uint16_t	tcp_tx_len;
+	uint16_t	tcp_rx_len;
+	uint32_t	reserved4;
+} __packed;
+
+struct r92s_fw_hdr {
+	uint16_t	signature;
+	uint16_t	version;
+	uint32_t	dmemsz;
+	uint32_t	imemsz;
+	uint32_t	sramsz;
+	uint32_t	privsz;
+	uint16_t	efuse_addr;
+	uint16_t	h2c_resp_addr;
+	uint32_t	svnrev;
+	uint8_t		month;
+	uint8_t		day;
+	uint8_t		hour;
+	uint8_t		minute;
+	struct		r92s_fw_priv priv;
+} __packed;
+
+/* Structure for FW commands and FW events notifications. */
+struct r92s_fw_cmd_hdr {
+	uint16_t	len;
+	uint8_t		code;
+	uint8_t		seq;
+#define R92S_FW_CMD_MORE	0x80
+
+	uint32_t	reserved;
+} __packed;
+
+/* FW commands codes. */
+#define R92S_CMD_READ_MACREG		0
+#define R92S_CMD_WRITE_MACREG		1
+#define R92S_CMD_READ_BBREG		2
+#define R92S_CMD_WRITE_BBREG		3
+#define R92S_CMD_READ_RFREG		4
+#define R92S_CMD_WRITE_RFREG		5
+#define R92S_CMD_READ_EEPROM		6
+#define R92S_CMD_WRITE_EEPROM		7
+#define R92S_CMD_READ_EFUSE		8
+#define R92S_CMD_WRITE_EFUSE		9
+#define R92S_CMD_READ_CAM		10
+#define R92S_CMD_WRITE_CAM		11
+#define R92S_CMD_SET_BCNITV		12
+#define R92S_CMD_SET_MBIDCFG		13
+#define R92S_CMD_JOIN_BSS		14
+#define R92S_CMD_DISCONNECT		15
+#define R92S_CMD_CREATE_BSS		16
+#define R92S_CMD_SET_OPMODE		17
+#define R92S_CMD_SITE_SURVEY		18
+#define R92S_CMD_SET_AUTH		19
+#define R92S_CMD_SET_KEY		20
+#define R92S_CMD_SET_STA_KEY		21
+#define R92S_CMD_SET_ASSOC_STA		22
+#define R92S_CMD_DEL_ASSOC_STA		23
+#define R92S_CMD_SET_STAPWRSTATE	24
+#define R92S_CMD_SET_BASIC_RATE		25
+#define R92S_CMD_GET_BASIC_RATE		26
+#define R92S_CMD_SET_DATA_RATE		27
+#define R92S_CMD_GET_DATA_RATE		28
+#define R92S_CMD_SET_PHY_INFO		29
+#define R92S_CMD_GET_PHY_INFO		30
+#define R92S_CMD_SET_PHY		31
+#define R92S_CMD_GET_PHY		32
+#define R92S_CMD_READ_RSSI		33
+#define R92S_CMD_READ_GAIN		34
+#define R92S_CMD_SET_ATIM		35
+#define R92S_CMD_SET_PWR_MODE		36
+#define R92S_CMD_JOIN_BSS_RPT		37
+#define R92S_CMD_SET_RA_TABLE		38
+#define R92S_CMD_GET_RA_TABLE		39
+#define R92S_CMD_GET_CCX_REPORT		40
+#define R92S_CMD_GET_DTM_REPORT		41
+#define R92S_CMD_GET_TXRATE_STATS	42
+#define R92S_CMD_SET_USB_SUSPEND	43
+#define R92S_CMD_SET_H2C_LBK		44
+#define R92S_CMD_ADDBA_REQ		45
+#define R92S_CMD_SET_CHANNEL		46
+#define R92S_CMD_SET_TXPOWER		47
+#define R92S_CMD_SWITCH_ANTENNA		48
+#define R92S_CMD_SET_CRYSTAL_CAL	49
+#define R92S_CMD_SET_SINGLE_CARRIER_TX	50
+#define R92S_CMD_SET_SINGLE_TONE_TX	51
+#define R92S_CMD_SET_CARRIER_SUPPR_TX	52
+#define R92S_CMD_SET_CONTINUOUS_TX	53
+#define R92S_CMD_SWITCH_BANDWIDTH	54
+#define R92S_CMD_TX_BEACON		55
+#define R92S_CMD_SET_POWER_TRACKING	56
+#define R92S_CMD_AMSDU_TO_AMPDU		57
+#define R92S_CMD_SET_MAC_ADDRESS	58
+#define R92S_CMD_GET_H2C_LBK		59
+#define R92S_CMD_SET_PBREQ_IE		60
+#define R92S_CMD_SET_ASSOCREQ_IE	61
+#define R92S_CMD_SET_PBRESP_IE		62
+#define R92S_CMD_SET_ASSOCRESP_IE	63
+#define R92S_CMD_GET_CURDATARATE	64
+#define R92S_CMD_GET_TXRETRY_CNT	65
+#define R92S_CMD_GET_RXRETRY_CNT	66
+#define R92S_CMD_GET_BCNOK_CNT		67
+#define R92S_CMD_GET_BCNERR_CNT		68
+#define R92S_CMD_GET_CURTXPWR_LEVEL	69
+#define R92S_CMD_SET_DIG		70
+#define R92S_CMD_SET_RA			71
+#define R92S_CMD_SET_PT			72
+#define R92S_CMD_READ_TSSI		73
+
+/* FW events notifications codes. */
+#define R92S_EVT_READ_MACREG		0
+#define R92S_EVT_READ_BBREG		1
+#define R92S_EVT_READ_RFREG		2
+#define R92S_EVT_READ_EEPROM		3
+#define R92S_EVT_READ_EFUSE		4
+#define R92S_EVT_READ_CAM		5
+#define R92S_EVT_GET_BASICRATE		6
+#define R92S_EVT_GET_DATARATE		7
+#define R92S_EVT_SURVEY			8
+#define R92S_EVT_SURVEY_DONE		9
+#define R92S_EVT_JOIN_BSS		10
+#define R92S_EVT_ADD_STA		11
+#define R92S_EVT_DEL_STA		12
+#define R92S_EVT_ATIM_DONE		13
+#define R92S_EVT_TX_REPORT		14
+#define R92S_EVT_CCX_REPORT		15
+#define R92S_EVT_DTM_REPORT		16
+#define R92S_EVT_TXRATE_STATS		17
+#define R92S_EVT_C2H_LBK		18
+#define R92S_EVT_FWDBG			19
+#define R92S_EVT_C2H_FEEDBACK		20
+#define R92S_EVT_ADDBA			21
+#define R92S_EVT_C2H_BCN		22
+#define R92S_EVT_PWR_STATE		23
+#define R92S_EVT_WPS_PBC		24
+#define R92S_EVT_ADDBA_REQ_REPORT	25
+
+/* Structure for R92S_CMD_SITE_SURVEY. */
+struct r92s_fw_cmd_sitesurvey {
+	uint32_t	active;
+	uint32_t	limit;
+	uint32_t	ssidlen;
+	uint8_t		ssid[32 + 1];
+} __packed;
+
+/* Structure for R92S_CMD_SET_AUTH. */
+struct r92s_fw_cmd_auth {
+	uint8_t	mode;
+#define R92S_AUTHMODE_OPEN	0
+#define R92S_AUTHMODE_SHARED	1
+#define R92S_AUTHMODE_WPA	2
+
+	uint8_t	dot1x;
+} __packed;
+
+/* Structure for R92S_CMD_SET_KEY. */
+struct r92s_fw_cmd_set_key {
+	uint8_t	algo;
+#define R92S_KEY_ALGO_NONE	0
+#define R92S_KEY_ALGO_WEP40	1
+#define R92S_KEY_ALGO_TKIP	2
+#define R92S_KEY_ALGO_TKIP_MMIC	3
+#define R92S_KEY_ALGO_AES	4
+#define R92S_KEY_ALGO_WEP104	5
+
+	uint8_t	id;
+	uint8_t	grpkey;
+	uint8_t	key[16];
+} __packed;
+
+/* Structures for R92S_EVENT_SURVEY/R92S_CMD_JOIN_BSS. */
+/* NDIS_802_11_SSID. */
+struct ndis_802_11_ssid {
+	uint32_t	ssidlen;
+	uint8_t		ssid[32];
+} __packed;
+
+/* NDIS_802_11_CONFIGURATION_FH. */
+struct ndis_802_11_configuration_fh {
+	uint32_t	len;
+	uint32_t	hoppattern;
+	uint32_t	hopset;
+	uint32_t	dwelltime;
+} __packed;
+
+/* NDIS_802_11_CONFIGURATION. */
+struct ndis_802_11_configuration {
+	uint32_t	len;
+	uint32_t	bintval;
+	uint32_t	atim;
+	uint32_t	dsconfig;
+	struct		ndis_802_11_configuration_fh fhconfig;
+} __packed;
+
+/* NDIS_WLAN_BSSID_EX. */
+struct ndis_wlan_bssid_ex {
+	uint32_t	len;
+	uint8_t		macaddr[IEEE80211_ADDR_LEN];
+	uint8_t		reserved[2];
+	struct		ndis_802_11_ssid ssid;
+	uint32_t	privacy;
+	int32_t		rssi;
+	uint32_t	networktype;
+#define NDIS802_11FH		0
+#define NDIS802_11DS		1
+#define NDIS802_11OFDM5		2
+#define NDIS802_11OFDM24	3
+#define NDIS802_11AUTOMODE	4
+
+	struct		ndis_802_11_configuration config;
+	uint32_t	inframode;
+#define NDIS802_11IBSS			0
+#define NDIS802_11INFRASTRUCTURE	1
+#define NDIS802_11AUTOUNKNOWN		2
+#define NDIS802_11MONITOR		3
+#define NDIS802_11APMODE		4
+
+	uint8_t		supprates[16];
+	uint32_t	ieslen;
+	/* Followed by ``ieslen'' bytes. */
+} __packed;
+
+/* NDIS_802_11_FIXED_IEs. */
+struct ndis_802_11_fixed_ies {
+	uint8_t		tstamp[8];
+	uint16_t	bintval;
+	uint16_t	capabilities;
+} __packed;
+
+/* Structure for R92S_CMD_SET_PWR_MODE. */
+struct r92s_set_pwr_mode {
+	uint8_t		mode;
+#define R92S_PS_MODE_ACTIVE	0
+#define R92S_PS_MODE_MIN	1
+#define R92S_PS_MODE_MAX	2
+#define R92S_PS_MODE_DTIM	3
+#define R92S_PS_MODE_VOIP	4
+#define R92S_PS_MODE_UAPSD_WMM	5
+#define R92S_PS_MODE_UAPSD	6
+#define R92S_PS_MODE_IBSS	7
+#define R92S_PS_MODE_WWLAN	8
+#define R92S_PS_MODE_RADIOOFF	9
+#define R92S_PS_MODE_DISABLE	10
+
+	uint8_t		low_traffic_en;
+	uint8_t		lpnav_en;
+	uint8_t		rf_low_snr_en;
+	uint8_t		dps_en;
+	uint8_t		bcn_rx_en;
+	uint8_t		bcn_pass_cnt;
+	uint8_t		bcn_to;
+	uint16_t	bcn_itv;
+	uint8_t		app_itv;
+	uint8_t		awake_bcn_itv;
+	uint8_t		smart_ps;
+	uint8_t		bcn_pass_time;
+} __packed;
+
+/* Structure for event R92S_EVENT_JOIN_BSS. */
+struct r92s_event_join_bss {
+	uint32_t	next;
+	uint32_t	prev;
+	uint32_t	networktype;
+	uint32_t	fixed;
+	uint32_t	lastscanned;
+	uint32_t	associd;
+	uint32_t	join_res;
+	struct		ndis_wlan_bssid_ex bss;
+} __packed;
+
+#define R92S_MACID_BSS	5
+
+/* Rx MAC descriptor. */
+struct r92s_rx_stat {
+	uint32_t	rxdw0;
+#define R92S_RXDW0_PKTLEN_M	0x00003fff
+#define R92S_RXDW0_PKTLEN_S	0
+#define R92S_RXDW0_CRCERR	0x00004000
+#define R92S_RXDW0_INFOSZ_M	0x000f0000
+#define R92S_RXDW0_INFOSZ_S	16
+#define R92S_RXDW0_QOS		0x00800000
+#define R92S_RXDW0_SHIFT_M	0x03000000
+#define R92S_RXDW0_SHIFT_S	24
+#define R92S_RXDW0_DECRYPTED	0x08000000
+
+	uint32_t	rxdw1;
+#define R92S_RXDW1_MOREFRAG	0x08000000
+
+	uint32_t	rxdw2;
+#define R92S_RXDW2_FRAG_M	0x0000f000
+#define R92S_RXDW2_FRAG_S	12
+#define R92S_RXDW2_PKTCNT_M	0x00ff0000
+#define R92S_RXDW2_PKTCNT_S	16
+
+	uint32_t	rxdw3;
+#define R92S_RXDW3_RATE_M	0x0000003f
+#define R92S_RXDW3_RATE_S	0
+#define R92S_RXDW3_TCPCHKRPT	0x00000800
+#define R92S_RXDW3_IPCHKRPT	0x00001000
+#define R92S_RXDW3_TCPCHKVALID	0x00002000
+#define R92S_RXDW3_HTC		0x00004000
+
+	uint32_t	rxdw4;
+	uint32_t	rxdw5;
+} __packed __aligned(4);
+
+/* Rx PHY descriptor. */
+struct r92s_rx_phystat {
+	uint32_t	phydw0;
+	uint32_t	phydw1;
+	uint32_t	phydw2;
+	uint32_t	phydw3;
+	uint32_t	phydw4;
+	uint32_t	phydw5;
+	uint32_t	phydw6;
+	uint32_t	phydw7;
+} __packed __aligned(4);
+
+/* Rx PHY CCK descriptor. */
+struct r92s_rx_cck {
+	uint8_t		adc_pwdb[4];
+	uint8_t		sq_rpt;
+	uint8_t		agc_rpt;
+} __packed;
+
+/* Tx MAC descriptor. */
+struct r92s_tx_desc {
+	uint32_t	txdw0;
+#define R92S_TXDW0_PKTLEN_M	0x0000ffff
+#define R92S_TXDW0_PKTLEN_S	0
+#define R92S_TXDW0_OFFSET_M	0x00ff0000
+#define R92S_TXDW0_OFFSET_S	16
+#define R92S_TXDW0_TYPE_M	0x03000000
+#define R92S_TXDW0_TYPE_S	24
+#define R92S_TXDW0_LSG		0x04000000
+#define R92S_TXDW0_FSG		0x08000000
+#define R92S_TXDW0_LINIP	0x10000000
+#define R92S_TXDW0_OWN		0x80000000
+
+	uint32_t	txdw1;
+#define R92S_TXDW1_MACID_M	0x0000001f
+#define R92S_TXDW1_MACID_S	0
+#define R92S_TXDW1_MOREDATA	0x00000020
+#define R92S_TXDW1_MOREFRAG	0x00000040
+#define R92S_TXDW1_QSEL_M	0x00001f00
+#define R92S_TXDW1_QSEL_S	8
+#define R92S_TXDW1_QSEL_BE	0x03
+#define R92S_TXDW1_QSEL_H2C	0x1f
+#define R92S_TXDW1_NONQOS	0x00010000
+#define R92S_TXDW1_KEYIDX_M	0x00060000
+#define R92S_TXDW1_KEYIDX_S	17
+#define R92S_TXDW1_CIPHER_M	0x00c00000
+#define R92S_TXDW1_CIPHER_S	22
+#define R92S_TXDW1_CIPHER_WEP	1
+#define R92S_TXDW1_CIPHER_TKIP	2
+#define R92S_TXDW1_CIPHER_AES	3
+#define R92S_TXDW1_HWPC		0x80000000
+
+	uint32_t	txdw2;
+#define R92S_TXDW2_BMCAST	0x00000080
+#define R92S_TXDW2_AGGEN	0x20000000
+#define R92S_TXDW2_BK		0x40000000
+
+	uint32_t	txdw3;
+#define R92S_TXDW3_SEQ_M	0x0fff0000
+#define R92S_TXDW3_SEQ_S	16
+#define R92S_TXDW3_FRAG_M	0xf0000000
+#define R92S_TXDW3_FRAG_S	28
+
+	uint32_t	txdw4;
+#define R92S_TXDW4_TXBW		0x00040000
+
+	uint32_t	txdw5;
+#define R92S_TXDW5_DISFB	0x00008000
+
+	uint16_t	ipchksum;
+	uint16_t	tcpchksum;
+
+	uint16_t	txbufsize;
+	uint16_t	reserved1;
+} __packed __aligned(4);
+
+
+/*
+ * Driver definitions.
+ */
+#define RSU_RX_LIST_COUNT	1
+#define RSU_TX_LIST_COUNT	32
+
+#define RSU_HOST_CMD_RING_COUNT	32
+
+#define RSU_RXBUFSZ	(8 * 1024)
+#define RSU_TXBUFSZ	\
+	((sizeof(struct r92s_tx_desc) + IEEE80211_MAX_LEN + 3) & ~3)
+
+#define RSU_TX_TIMEOUT	5000	/* ms */
+#define RSU_CMD_TIMEOUT	2000	/* ms */
+
+/* Queue ids (used by soft only). */
+#define RSU_QID_BCN	0
+#define RSU_QID_MGT	1
+#define RSU_QID_BMC	2
+#define RSU_QID_VO	3
+#define RSU_QID_VI	4
+#define RSU_QID_BE	5
+#define RSU_QID_BK	6
+#define RSU_QID_RXOFF	7
+#define RSU_QID_H2C	8
+#define RSU_QID_C2H	9
+
+/* Map AC to queue id. */
+static const uint8_t rsu_ac2qid[WME_NUM_AC] = {
+	RSU_QID_BE,
+	RSU_QID_BK,
+	RSU_QID_VI,
+	RSU_QID_VO
+};
+
+/* Pipe index to endpoint address mapping. */
+static const uint8_t r92s_epaddr[] =
+    { 0x83, 0x04, 0x06, 0x0d,
+      0x05, 0x07,
+      0x89, 0x0a, 0x0b, 0x0c };
+
+/* Queue id to pipe index mapping for 4 endpoints configurations. */
+static const uint8_t rsu_qid2idx_4ep[] =
+    { 3, 3, 3, 1, 1, 2, 2, 0, 3, 0 };
+
+/* Queue id to pipe index mapping for 6 endpoints configurations. */
+static const uint8_t rsu_qid2idx_6ep[] =
+    { 3, 3, 3, 1, 4, 2, 5, 0, 3, 0 };
+
+/* Queue id to pipe index mapping for 11 endpoints configurations. */
+static const uint8_t rsu_qid2idx_11ep[] =
+    { 7, 9, 8, 1, 4, 2, 5, 0, 3, 6 };
+
+struct rsu_rx_radiotap_header {
+	struct ieee80211_radiotap_header wr_ihdr;
+	uint8_t		wr_flags;
+	uint8_t		wr_rate;
+	uint16_t	wr_chan_freq;
+	uint16_t	wr_chan_flags;
+	uint8_t		wr_dbm_antsignal;
+} __packed __aligned(8);
+
+#define RSU_RX_RADIOTAP_PRESENT			\
+	(1 << IEEE80211_RADIOTAP_FLAGS |	\
+	 1 << IEEE80211_RADIOTAP_RATE |		\
+	 1 << IEEE80211_RADIOTAP_CHANNEL |	\
+	 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)
+
+struct rsu_tx_radiotap_header {
+	struct ieee80211_radiotap_header wt_ihdr;
+	uint8_t		wt_flags;
+	uint16_t	wt_chan_freq;
+	uint16_t	wt_chan_flags;
+} __packed __aligned(8);
+
+#define RSU_TX_RADIOTAP_PRESENT			\
+	(1 << IEEE80211_RADIOTAP_FLAGS |	\
+	 1 << IEEE80211_RADIOTAP_CHANNEL)
+
+struct rsu_softc;
+
+struct rsu_host_cmd {
+	void	(*cb)(struct rsu_softc *, void *);
+	uint8_t	data[256];
+};
+
+struct rsu_cmd_newstate {
+	enum ieee80211_state	state;
+	int			arg;
+};
+
+struct rsu_cmd_key {
+	struct ieee80211_key	key;
+};
+
+struct rsu_host_cmd_ring {
+	struct rsu_host_cmd	cmd[RSU_HOST_CMD_RING_COUNT];
+	int			cur;
+	int			next;
+	int			queued;
+};
+
+enum {
+	RSU_BULK_RX,
+	RSU_BULK_TX_BE_BK,	/* = WME_AC_BE/BK */
+	RSU_BULK_TX_VI_VO,	/* = WME_AC_VI/VO */
+	RSU_N_TRANSFER,
+};
+
+struct rsu_data {
+	struct rsu_softc	*sc;
+	uint8_t			*buf;
+	uint16_t		buflen;
+	struct mbuf		*m;
+	struct ieee80211_node	*ni;
+	STAILQ_ENTRY(rsu_data)  next;
+};
+
+struct rsu_vap {
+	struct ieee80211vap		vap;
+	struct ieee80211_beacon_offsets bo;
+
+	int				(*newstate)(struct ieee80211vap *,
+					    enum ieee80211_state, int);
+};
+#define RSU_VAP(vap) 			((struct rsu_vap *)(vap))
+
+#define	RSU_LOCK(sc)			mtx_lock(&(sc)->sc_mtx)
+#define	RSU_UNLOCK(sc)			mtx_unlock(&(sc)->sc_mtx)
+#define	RSU_ASSERT_LOCKED(sc)		mtx_assert(&(sc)->sc_mtx, MA_OWNED)
+
+struct rsu_softc {
+	struct ifnet			*sc_ifp;
+	device_t			sc_dev;
+	struct usb_device		*sc_udev;
+	int				(*sc_newstate)(struct ieee80211com *,
+					    enum ieee80211_state, int);
+	struct usbd_interface		*sc_iface;
+	struct timeout_task		calib_task;
+	const uint8_t			*qid2idx;
+	struct mtx			sc_mtx;
+
+	u_int				cut;
+	int				scan_pass;
+	struct rsu_host_cmd_ring	cmdq;
+	struct rsu_data			sc_rx[RSU_RX_LIST_COUNT];
+	struct rsu_data			sc_tx[RSU_TX_LIST_COUNT];
+	struct rsu_data			*fwcmd_data;
+	uint8_t				cmd_seq;
+	uint8_t				rom[128];
+	uint8_t				sc_bssid[IEEE80211_ADDR_LEN];
+	struct usb_xfer			*sc_xfer[RSU_N_TRANSFER];
+	uint8_t				sc_calibrating;
+
+	STAILQ_HEAD(, rsu_data)		sc_rx_active;
+	STAILQ_HEAD(, rsu_data)		sc_rx_inactive;
+	STAILQ_HEAD(, rsu_data)		sc_tx_active[RSU_N_TRANSFER];
+	STAILQ_HEAD(, rsu_data)		sc_tx_inactive;
+	STAILQ_HEAD(, rsu_data)		sc_tx_pending[RSU_N_TRANSFER];
+
+	union {
+		struct rsu_rx_radiotap_header th;
+		uint8_t	pad[64];
+	}				sc_rxtapu;
+#define sc_rxtap	sc_rxtapu.th
+	int				sc_rxtap_len;
+
+	union {
+		struct rsu_tx_radiotap_header th;
+		uint8_t	pad[64];
+	}				sc_txtapu;
+#define sc_txtap	sc_txtapu.th
+	int				sc_txtap_len;
+};


Property changes on: trunk/sys/dev/usb/wlan/if_rsureg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/dev/usb/wlan/if_rum.c
===================================================================
--- trunk/sys/dev/usb/wlan/if_rum.c	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_rum.c	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,4 +1,5 @@
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_rum.c 269267 2014-07-29 22:00:54Z hselasky $	*/
+/* $MidnightBSD$ */
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_rum.c 269266 2014-07-29 21:59:24Z hselasky $	*/
 
 /*-
  * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini at free.fr>
@@ -19,7 +20,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/9/sys/dev/usb/wlan/if_rum.c 269267 2014-07-29 22:00:54Z hselasky $");
+__FBSDID("$FreeBSD: stable/10/sys/dev/usb/wlan/if_rum.c 269266 2014-07-29 21:59:24Z hselasky $");
 
 /*-
  * Ralink Technology RT2501USB/RT2601USB chipset driver
@@ -1122,7 +1123,7 @@
 	sc->tx_nfree--;
 
 	wh = mtod(m0, struct ieee80211_frame *);
-	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
 		k = ieee80211_crypto_encap(ni, m0);
 		if (k == NULL) {
 			m_freem(m0);
@@ -1240,7 +1241,7 @@
 	else
 		rate = ni->ni_txrate;
 
-	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
 		k = ieee80211_crypto_encap(ni, m0);
 		if (k == NULL) {
 			m_freem(m0);

Modified: trunk/sys/dev/usb/wlan/if_rumfw.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_rumfw.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_rumfw.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,4 +1,5 @@
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_rumfw.h 196219 2009-08-14 20:03:53Z jhb $	*/
+/* $MidnightBSD$ */
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_rumfw.h 196219 2009-08-14 20:03:53Z jhb $	*/
 
 /*-
  * Copyright (c) 2005-2006, Ralink Technology, Corp.

Modified: trunk/sys/dev/usb/wlan/if_rumreg.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_rumreg.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_rumreg.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,4 +1,5 @@
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_rumreg.h 196970 2009-09-08 13:19:05Z phk $	*/
+/* $MidnightBSD$ */
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_rumreg.h 261455 2014-02-04 03:36:42Z eadler $	*/
 
 /*-
  * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini at free.fr>
@@ -139,7 +140,7 @@
 #define RT2573_BBP_BUSY	(1 << 16)
 /* possible flags for register PHY_CSR4 */
 #define RT2573_RF_20BIT	(20 << 24)
-#define RT2573_RF_BUSY	(1 << 31)
+#define RT2573_RF_BUSY	(1U << 31)
 
 /* LED values */
 #define RT2573_LED_RADIO	(1 << 8)

Modified: trunk/sys/dev/usb/wlan/if_rumvar.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_rumvar.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_rumvar.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,4 +1,5 @@
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_rumvar.h 259460 2013-12-16 09:34:01Z hselasky $	*/
+/* $MidnightBSD$ */
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_rumvar.h 253757 2013-07-29 05:54:13Z hselasky $	*/
 
 /*-
  * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini at free.fr>

Modified: trunk/sys/dev/usb/wlan/if_run.c
===================================================================
--- trunk/sys/dev/usb/wlan/if_run.c	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_run.c	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008,2010 Damien Bergamini <damien.bergamini at free.fr>
  * ported to FreeBSD by Akinori Furukoshi <moonlightakkiy at yahoo.ca>
@@ -18,7 +19,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/9/sys/dev/usb/wlan/if_run.c 294903 2016-01-27 07:34:23Z delphij $");
+__FBSDID("$FreeBSD: stable/10/sys/dev/usb/wlan/if_run.c 292183 2015-12-14 09:24:40Z hselasky $");
 
 /*-
  * Ralink Technology RT2700U/RT2800U/RT3000U/RT3900E chipset driver.
@@ -180,6 +181,7 @@
     RUN_DEV(DLINK,		DWA127),
     RUN_DEV(DLINK,		DWA140B3),
     RUN_DEV(DLINK,		DWA160B2),
+    RUN_DEV(DLINK,		DWA140D1),
     RUN_DEV(DLINK,		DWA162),
     RUN_DEV(DLINK2,		DWA130),
     RUN_DEV(DLINK2,		RT2870_1),
@@ -2806,8 +2808,8 @@
 
 	wh = mtod(m, struct ieee80211_frame *);
 
-	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
-		wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
+	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
+		wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
 		m->m_flags |= M_WEP;
 	}
 
@@ -3255,13 +3257,13 @@
 	txwi = (struct rt2860_txwi *)(txd + 1);
 	txwi->len = htole16(m->m_pkthdr.len - pad);
 	if (rt2860_rates[ridx].phy == IEEE80211_T_DS) {
-		txwi->phy = htole16(RT2860_PHY_CCK);
+		mcs |= RT2860_PHY_CCK;
 		if (ridx != RT2860_RIDX_CCK1 &&
 		    (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
 			mcs |= RT2860_PHY_SHPRE;
 	} else
-		txwi->phy = htole16(RT2860_PHY_OFDM);
-	txwi->phy |= htole16(mcs);
+		mcs |= RT2860_PHY_OFDM;
+	txwi->phy = htole16(mcs);
 
 	/* check if RTS/CTS or CTS-to-self protection is required */
 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
@@ -3338,7 +3340,7 @@
 
 	/* pickup a rate index */
 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
-	    type != IEEE80211_FC0_TYPE_DATA) {
+	    type != IEEE80211_FC0_TYPE_DATA || m->m_flags & M_EAPOL) {
 		ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
 		    RT2860_RIDX_OFDM6 : RT2860_RIDX_CCK1;
 		ctl_ridx = rt2860_rates[ridx].ctl_ridx;
@@ -5004,7 +5006,7 @@
 	tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL;
 	/* setup protection frame rate (MCS code) */
 	tmp |= (ic->ic_curmode == IEEE80211_MODE_11A) ?
-	    rt2860_rates[RT2860_RIDX_OFDM6].mcs :
+	    rt2860_rates[RT2860_RIDX_OFDM6].mcs | RT2860_PHY_OFDM :
 	    rt2860_rates[RT2860_RIDX_CCK11].mcs;
 
 	/* CCK frames don't require protection */

Modified: trunk/sys/dev/usb/wlan/if_runreg.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_runreg.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_runreg.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$OpenBSD: rt2860reg.h,v 1.19 2009/05/18 19:25:07 damien Exp $	*/
 
 /*-
@@ -16,7 +17,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $FreeBSD: stable/9/sys/dev/usb/wlan/if_runreg.h 294903 2016-01-27 07:34:23Z delphij $
+ * $FreeBSD: stable/10/sys/dev/usb/wlan/if_runreg.h 261868 2014-02-14 03:45:49Z kevlo $
  */
 
 #ifndef _IF_RUNREG_H_
@@ -962,6 +963,31 @@
 #define	RT2860_RIDX_MAX		12
 
 /*
+ * Control and status registers access macros.
+ */
+#define RAL_READ(sc, reg)						\
+	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
+
+#define RAL_WRITE(sc, reg, val)						\
+	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
+
+#define RAL_BARRIER_WRITE(sc)						\
+	bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, 0x1800,		\
+	    BUS_SPACE_BARRIER_WRITE)
+
+#define RAL_BARRIER_READ_WRITE(sc)					\
+	bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, 0x1800,		\
+	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
+
+#define RAL_WRITE_REGION_1(sc, offset, datap, count)			\
+	bus_space_write_region_1((sc)->sc_st, (sc)->sc_sh, (offset),	\
+	    (datap), (count))
+
+#define RAL_SET_REGION_4(sc, offset, val, count)			\
+	bus_space_set_region_4((sc)->sc_st, (sc)->sc_sh, (offset),	\
+	    (val), (count))
+
+/*
  * EEPROM access macro.
  */
 #define RT2860_EEPROM_CTL(sc, val) do {					\

Modified: trunk/sys/dev/usb/wlan/if_runvar.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_runvar.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_runvar.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$OpenBSD: if_runvar.h,v 1.3 2009/03/26 20:17:27 damien Exp $	*/
 
 /*-
@@ -17,7 +18,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $FreeBSD: stable/9/sys/dev/usb/wlan/if_runvar.h 262605 2014-02-28 16:11:43Z kevlo $
+ * $FreeBSD: stable/10/sys/dev/usb/wlan/if_runvar.h 262604 2014-02-28 16:08:31Z kevlo $
  */
 
 #ifndef _IF_RUNVAR_H_

Modified: trunk/sys/dev/usb/wlan/if_uath.c
===================================================================
--- trunk/sys/dev/usb/wlan/if_uath.c	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_uath.c	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2006 Sam Leffler, Errno Consulting
  * Copyright (c) 2008-2009 Weongyo Jeong <weongyo at freebsd.org>
@@ -49,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/9/sys/dev/usb/wlan/if_uath.c 259457 2013-12-16 09:07:09Z hselasky $");
+__FBSDID("$FreeBSD: stable/10/sys/dev/usb/wlan/if_uath.c 262007 2014-02-17 01:36:53Z kevlo $");
 
 /*-
  * Driver for Atheros AR5523 USB parts.
@@ -1625,7 +1626,7 @@
 	}
 
 	wh = mtod(m0, struct ieee80211_frame *);
-	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
 		k = ieee80211_crypto_encap(ni, m0);
 		if (k == NULL) {
 			m_freem(m0);
@@ -2459,11 +2460,8 @@
 
 	UATH_ASSERT_LOCKED(sc);
 
-	switch (USB_GET_STATE(xfer)) {
-	case USB_ST_TRANSFERRED:
-		cmd = STAILQ_FIRST(&sc->sc_cmd_active);
-		if (cmd == NULL)
-			goto setup;
+	cmd = STAILQ_FIRST(&sc->sc_cmd_active);
+	if (cmd != NULL && USB_GET_STATE(xfer) != USB_ST_SETUP) {
 		STAILQ_REMOVE_HEAD(&sc->sc_cmd_active, next);
 		UATH_STAT_DEC(sc, st_cmd_active);
 		STAILQ_INSERT_TAIL((cmd->flags & UATH_CMD_FLAG_READ) ?
@@ -2472,7 +2470,10 @@
 			UATH_STAT_INC(sc, st_cmd_waiting);
 		else
 			UATH_STAT_INC(sc, st_cmd_inactive);
-		/* FALLTHROUGH */
+	}
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
 	case USB_ST_SETUP:
 setup:
 		cmd = STAILQ_FIRST(&sc->sc_cmd_pending);

Modified: trunk/sys/dev/usb/wlan/if_uathreg.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_uathreg.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_uathreg.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*	$OpenBSD: if_uathreg.h,v 1.2 2006/09/18 16:34:23 damien Exp $	*/
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_uathreg.h 190688 2009-04-04 11:23:00Z weongyo $	*/
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_uathreg.h 190688 2009-04-04 11:23:00Z weongyo $	*/
 
 /*-
  * Copyright (c) 2006

Modified: trunk/sys/dev/usb/wlan/if_uathvar.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_uathvar.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_uathvar.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*	$OpenBSD: if_uathvar.h,v 1.3 2006/09/20 19:47:17 damien Exp $	*/
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_uathvar.h 259460 2013-12-16 09:34:01Z hselasky $	*/
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_uathvar.h 253757 2013-07-29 05:54:13Z hselasky $	*/
 
 /*-
  * Copyright (c) 2006

Modified: trunk/sys/dev/usb/wlan/if_upgt.c
===================================================================
--- trunk/sys/dev/usb/wlan/if_upgt.c	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_upgt.c	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*	$OpenBSD: if_upgt.c,v 1.35 2008/04/16 18:32:15 damien Exp $ */
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_upgt.c 292184 2015-12-14 09:42:39Z hselasky $ */
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_upgt.c 292183 2015-12-14 09:24:40Z hselasky $ */
 
 /*
  * Copyright (c) 2007 Marcus Glocker <mglocker at openbsd.org>
@@ -2222,7 +2223,7 @@
 	 * Software crypto.
 	 */
 	wh = mtod(m, struct ieee80211_frame *);
-	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
 		k = ieee80211_crypto_encap(ni, m);
 		if (k == NULL) {
 			device_printf(sc->sc_dev,

Modified: trunk/sys/dev/usb/wlan/if_upgtvar.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_upgtvar.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_upgtvar.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*	$OpenBSD: if_upgtvar.h,v 1.14 2008/02/02 13:48:44 mglocker Exp $ */
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_upgtvar.h 259460 2013-12-16 09:34:01Z hselasky $ */
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_upgtvar.h 253757 2013-07-29 05:54:13Z hselasky $ */
 
 /*
  * Copyright (c) 2007 Marcus Glocker <mglocker at openbsd.org>

Modified: trunk/sys/dev/usb/wlan/if_ural.c
===================================================================
--- trunk/sys/dev/usb/wlan/if_ural.c	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_ural.c	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,4 +1,5 @@
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_ural.c 269267 2014-07-29 22:00:54Z hselasky $	*/
+/* $MidnightBSD$ */
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_ural.c 269266 2014-07-29 21:59:24Z hselasky $	*/
 
 /*-
  * Copyright (c) 2005, 2006
@@ -21,7 +22,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/9/sys/dev/usb/wlan/if_ural.c 269267 2014-07-29 22:00:54Z hselasky $");
+__FBSDID("$FreeBSD: stable/10/sys/dev/usb/wlan/if_ural.c 269266 2014-07-29 21:59:24Z hselasky $");
 
 /*-
  * Ralink Technology RT2500USB chipset driver
@@ -1121,7 +1122,7 @@
 	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
 
 	wh = mtod(m0, struct ieee80211_frame *);
-	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
 		k = ieee80211_crypto_encap(ni, m0);
 		if (k == NULL) {
 			m_freem(m0);
@@ -1290,7 +1291,7 @@
 	else
 		rate = ni->ni_txrate;
 
-	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
 		k = ieee80211_crypto_encap(ni, m0);
 		if (k == NULL) {
 			m_freem(m0);

Modified: trunk/sys/dev/usb/wlan/if_uralreg.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_uralreg.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_uralreg.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,4 +1,5 @@
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_uralreg.h 196219 2009-08-14 20:03:53Z jhb $	*/
+/* $MidnightBSD$ */
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_uralreg.h 261455 2014-02-04 03:36:42Z eadler $	*/
 
 /*-
  * Copyright (c) 2005, 2006
@@ -197,7 +198,7 @@
 } __packed;
 
 #define RAL_RF_LOBUSY	(1 << 15)
-#define RAL_RF_BUSY	(1 << 31)
+#define RAL_RF_BUSY	(1U << 31)
 #define RAL_RF_20BIT	(20 << 24)
 
 #define RAL_RF1	0

Modified: trunk/sys/dev/usb/wlan/if_uralvar.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_uralvar.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_uralvar.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,4 +1,5 @@
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_uralvar.h 259460 2013-12-16 09:34:01Z hselasky $	*/
+/* $MidnightBSD$ */
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_uralvar.h 253757 2013-07-29 05:54:13Z hselasky $	*/
 
 /*-
  * Copyright (c) 2005

Modified: trunk/sys/dev/usb/wlan/if_urtw.c
===================================================================
--- trunk/sys/dev/usb/wlan/if_urtw.c	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_urtw.c	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008 Weongyo Jeong <weongyo at FreeBSD.org>
  *
@@ -15,7 +16,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/9/sys/dev/usb/wlan/if_urtw.c 260575 2014-01-12 21:21:19Z hselasky $");
+__FBSDID("$FreeBSD: stable/10/sys/dev/usb/wlan/if_urtw.c 262007 2014-02-17 01:36:53Z kevlo $");
 #include <sys/param.h>
 #include <sys/sockio.h>
 #include <sys/sysctl.h>
@@ -1696,7 +1697,7 @@
 	/*
 	 * Software crypto.
 	 */
-	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
 		k = ieee80211_crypto_encap(ni, m0);
 		if (k == NULL) {
 			device_printf(sc->sc_dev,

Added: trunk/sys/dev/usb/wlan/if_urtwnreg.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_urtwnreg.h	                        (rev 0)
+++ trunk/sys/dev/usb/wlan/if_urtwnreg.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -0,0 +1,2188 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini at free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
+ * $FreeBSD: stable/10/sys/dev/usb/wlan/if_urtwnreg.h 266578 2014-05-23 06:47:47Z hselasky $
+ */
+
+#define URTWN_CONFIG_INDEX	0
+#define URTWN_IFACE_INDEX	0
+
+#define	URTWN_NOISE_FLOOR	-95
+
+#define R92C_MAX_CHAINS	2
+
+/* Maximum number of output pipes is 3. */
+#define R92C_MAX_EPOUT	3
+
+#define R92C_MAX_TX_PWR	0x3f
+
+#define R92C_PUBQ_NPAGES	231
+#define R92C_TXPKTBUF_COUNT	256
+#define R92C_TX_PAGE_COUNT	248
+#define R92C_TX_PAGE_BOUNDARY	(R92C_TX_PAGE_COUNT + 1)
+#define R88E_TXPKTBUF_COUNT	177
+#define R88E_TX_PAGE_COUNT	169
+#define R88E_TX_PAGE_BOUNDARY	(R88E_TX_PAGE_COUNT + 1)
+
+#define R92C_H2C_NBOX	4
+
+/* USB Requests. */
+#define R92C_REQ_REGS	0x05
+
+/*
+ * MAC registers.
+ */
+/* System Configuration. */
+#define R92C_SYS_ISO_CTRL		0x000
+#define R92C_SYS_FUNC_EN		0x002
+#define R92C_APS_FSMCO			0x004
+#define R92C_SYS_CLKR			0x008
+#define R92C_AFE_MISC			0x010
+#define R92C_SPS0_CTRL			0x011
+#define R92C_SPS_OCP_CFG		0x018
+#define R92C_RSV_CTRL			0x01c
+#define R92C_RF_CTRL			0x01f
+#define R92C_LDOA15_CTRL		0x020
+#define R92C_LDOV12D_CTRL		0x021
+#define R92C_LDOHCI12_CTRL		0x022
+#define R92C_LPLDO_CTRL			0x023
+#define R92C_AFE_XTAL_CTRL		0x024
+#define R92C_AFE_PLL_CTRL		0x028
+#define R92C_EFUSE_CTRL			0x030
+#define R92C_EFUSE_TEST			0x034
+#define R92C_PWR_DATA			0x038
+#define R92C_CAL_TIMER			0x03c
+#define R92C_ACLK_MON			0x03e
+#define R92C_GPIO_MUXCFG		0x040
+#define R92C_GPIO_IO_SEL		0x042
+#define R92C_MAC_PINMUX_CFG		0x043
+#define R92C_GPIO_PIN_CTRL		0x044
+#define R92C_GPIO_INTM			0x048
+#define R92C_LEDCFG0			0x04c
+#define R92C_LEDCFG1			0x04d
+#define R92C_LEDCFG2			0x04e
+#define R92C_LEDCFG3			0x04f
+#define R92C_FSIMR			0x050
+#define R92C_FSISR			0x054
+#define R92C_HSIMR			0x058
+#define R92C_HSISR			0x05c
+#define R92C_MCUFWDL			0x080
+#define R92C_HMEBOX_EXT(idx)		(0x088 + (idx) * 2)
+#define R88E_HIMR			0x0b0
+#define R88E_HISR			0x0b4
+#define R88E_HIMRE			0x0b8
+#define R88E_HISRE			0x0bc
+#define R92C_EFUSE_ACCESS               0x0cf
+#define R92C_BIST_SCAN			0x0d0
+#define R92C_BIST_RPT			0x0d4
+#define R92C_BIST_ROM_RPT		0x0d8
+#define R92C_USB_SIE_INTF		0x0e0
+#define R92C_PCIE_MIO_INTF		0x0e4
+#define R92C_PCIE_MIO_INTD		0x0e8
+#define R92C_HPON_FSM			0x0ec
+#define R92C_SYS_CFG			0x0f0
+/* MAC General Configuration. */
+#define R92C_CR				0x100
+#define R92C_PBP			0x104
+#define R92C_TRXDMA_CTRL		0x10c
+#define R92C_TRXFF_BNDY			0x114
+#define R92C_TRXFF_STATUS		0x118
+#define R92C_RXFF_PTR			0x11c
+#define R92C_HIMR			0x120
+#define R92C_HISR			0x124
+#define R92C_HIMRE			0x128
+#define R92C_HISRE			0x12c
+#define R92C_CPWM			0x12f
+#define R92C_FWIMR			0x130
+#define R92C_FWISR			0x134
+#define R92C_PKTBUF_DBG_CTRL		0x140
+#define R92C_PKTBUF_DBG_DATA_L		0x144
+#define R92C_PKTBUF_DBG_DATA_H		0x148
+#define R92C_TC0_CTRL(i)		(0x150 + (i) * 4)
+#define R92C_TCUNIT_BASE		0x164
+#define R92C_MBIST_START		0x174
+#define R92C_MBIST_DONE			0x178
+#define R92C_MBIST_FAIL			0x17c
+#define R92C_C2HEVT_MSG_NORMAL		0x1a0
+#define R92C_C2HEVT_MSG_TEST		0x1b8
+#define R92C_C2HEVT_CLEAR		0x1bf
+#define R92C_MCUTST_1			0x1c0
+#define R92C_FMETHR			0x1c8
+#define R92C_HMETFR			0x1cc
+#define R92C_HMEBOX(idx)		(0x1d0 + (idx) * 4)
+#define R92C_LLT_INIT			0x1e0
+#define R92C_BB_ACCESS_CTRL		0x1e8
+#define R92C_BB_ACCESS_DATA		0x1ec
+#define R88E_HMEBOX_EXT(idx)            (0x1f0 + (idx) * 4)
+/* Tx DMA Configuration. */
+#define R92C_RQPN			0x200
+#define R92C_FIFOPAGE			0x204
+#define R92C_TDECTRL			0x208
+#define R92C_TXDMA_OFFSET_CHK		0x20c
+#define R92C_TXDMA_STATUS		0x210
+#define R92C_RQPN_NPQ			0x214
+/* Rx DMA Configuration. */
+#define R92C_RXDMA_AGG_PG_TH		0x280
+#define R92C_RXPKT_NUM			0x284
+#define R92C_RXDMA_STATUS		0x288
+/* Protocol Configuration. */
+#define R92C_FWHW_TXQ_CTRL		0x420
+#define R92C_HWSEQ_CTRL			0x423
+#define R92C_TXPKTBUF_BCNQ_BDNY		0x424
+#define R92C_TXPKTBUF_MGQ_BDNY		0x425
+#define R92C_SPEC_SIFS			0x428
+#define R92C_RL				0x42a
+#define R92C_DARFRC			0x430
+#define R92C_RARFRC			0x438
+#define R92C_RRSR			0x440
+#define R92C_ARFR(i)			(0x444 + (i) * 4)
+#define R92C_AGGLEN_LMT			0x458
+#define R92C_AMPDU_MIN_SPACE		0x45c
+#define R92C_TXPKTBUF_WMAC_LBK_BF_HD	0x45d
+#define R92C_FAST_EDCA_CTRL		0x460
+#define R92C_RD_RESP_PKT_TH		0x463
+#define R92C_INIRTS_RATE_SEL		0x480
+#define R92C_INIDATA_RATE_SEL(macid)	(0x484 + (macid))
+#define R92C_MAX_AGGR_NUM		0x4ca
+/* EDCA Configuration. */
+#define R92C_EDCA_VO_PARAM		0x500
+#define R92C_EDCA_VI_PARAM		0x504
+#define R92C_EDCA_BE_PARAM		0x508
+#define R92C_EDCA_BK_PARAM		0x50c
+#define R92C_BCNTCFG			0x510
+#define R92C_PIFS			0x512
+#define R92C_RDG_PIFS			0x513
+#define R92C_SIFS_CCK			0x514
+#define R92C_SIFS_OFDM			0x516
+#define R92C_AGGR_BREAK_TIME		0x51a
+#define R92C_SLOT			0x51b
+#define R92C_TX_PTCL_CTRL		0x520
+#define R92C_TXPAUSE			0x522
+#define R92C_DIS_TXREQ_CLR		0x523
+#define R92C_RD_CTRL			0x524
+#define R92C_TBTT_PROHIBIT		0x540
+#define R92C_RD_NAV_NXT			0x544
+#define R92C_NAV_PROT_LEN		0x546
+#define R92C_BCN_CTRL			0x550
+#define R92C_USTIME_TSF			0x551
+#define R92C_MBID_NUM			0x552
+#define R92C_DUAL_TSF_RST		0x553
+#define R92C_BCN_INTERVAL		0x554
+#define R92C_DRVERLYINT			0x558
+#define R92C_BCNDMATIM			0x559
+#define R92C_ATIMWND			0x55a
+#define R92C_BCN_MAX_ERR		0x55d
+#define R92C_RXTSF_OFFSET_CCK		0x55e
+#define R92C_RXTSF_OFFSET_OFDM		0x55f
+#define R92C_TSFTR			0x560
+#define R92C_INIT_TSFTR			0x564
+#define R92C_PSTIMER			0x580
+#define R92C_TIMER0			0x584
+#define R92C_TIMER1			0x588
+#define R92C_ACMHWCTRL			0x5c0
+#define R92C_ACMRSTCTRL			0x5c1
+#define R92C_ACMAVG			0x5c2
+#define R92C_VO_ADMTIME			0x5c4
+#define R92C_VI_ADMTIME			0x5c6
+#define R92C_BE_ADMTIME			0x5c8
+#define R92C_EDCA_RANDOM_GEN		0x5cc
+#define R92C_SCH_TXCMD			0x5d0
+/* WMAC Configuration. */
+#define R92C_APSD_CTRL			0x600
+#define R92C_BWOPMODE			0x603
+#define R92C_RCR			0x608
+#define R92C_RX_DRVINFO_SZ		0x60f
+#define R92C_MACID			0x610
+#define R92C_BSSID			0x618
+#define R92C_MAR			0x620
+#define R92C_MAC_SPEC_SIFS		0x63a
+#define R92C_R2T_SIFS			0x63c
+#define R92C_T2T_SIFS			0x63e
+#define R92C_ACKTO			0x640
+#define R92C_CAMCMD			0x670
+#define R92C_CAMWRITE			0x674
+#define R92C_CAMREAD			0x678
+#define R92C_CAMDBG			0x67c
+#define R92C_SECCFG			0x680
+#define R92C_RXFLTMAP0			0x6a0
+#define R92C_RXFLTMAP1			0x6a2
+#define R92C_RXFLTMAP2			0x6a4
+
+/* Bits for R92C_SYS_ISO_CTRL. */
+#define R92C_SYS_ISO_CTRL_MD2PP		0x0001
+#define R92C_SYS_ISO_CTRL_UA2USB	0x0002
+#define R92C_SYS_ISO_CTRL_UD2CORE	0x0004
+#define R92C_SYS_ISO_CTRL_PA2PCIE	0x0008
+#define R92C_SYS_ISO_CTRL_PD2CORE	0x0010
+#define R92C_SYS_ISO_CTRL_IP2MAC	0x0020
+#define R92C_SYS_ISO_CTRL_DIOP		0x0040
+#define R92C_SYS_ISO_CTRL_DIOE		0x0080
+#define R92C_SYS_ISO_CTRL_EB2CORE	0x0100
+#define R92C_SYS_ISO_CTRL_DIOR		0x0200
+#define R92C_SYS_ISO_CTRL_PWC_EV25V	0x4000
+#define R92C_SYS_ISO_CTRL_PWC_EV12V	0x8000
+
+/* Bits for R92C_SYS_FUNC_EN. */
+#define R92C_SYS_FUNC_EN_BBRSTB		0x0001
+#define R92C_SYS_FUNC_EN_BB_GLB_RST	0x0002
+#define R92C_SYS_FUNC_EN_USBA		0x0004
+#define R92C_SYS_FUNC_EN_UPLL		0x0008
+#define R92C_SYS_FUNC_EN_USBD		0x0010
+#define R92C_SYS_FUNC_EN_DIO_PCIE	0x0020
+#define R92C_SYS_FUNC_EN_PCIEA		0x0040
+#define R92C_SYS_FUNC_EN_PPLL		0x0080
+#define R92C_SYS_FUNC_EN_PCIED		0x0100
+#define R92C_SYS_FUNC_EN_DIOE		0x0200
+#define R92C_SYS_FUNC_EN_CPUEN		0x0400
+#define R92C_SYS_FUNC_EN_DCORE		0x0800
+#define R92C_SYS_FUNC_EN_ELDR		0x1000
+#define R92C_SYS_FUNC_EN_DIO_RF		0x2000
+#define R92C_SYS_FUNC_EN_HWPDN		0x4000
+#define R92C_SYS_FUNC_EN_MREGEN		0x8000
+
+/* Bits for R92C_APS_FSMCO. */
+#define R92C_APS_FSMCO_PFM_LDALL	0x00000001
+#define R92C_APS_FSMCO_PFM_ALDN		0x00000002
+#define R92C_APS_FSMCO_PFM_LDKP		0x00000004
+#define R92C_APS_FSMCO_PFM_WOWL		0x00000008
+#define R92C_APS_FSMCO_PDN_EN		0x00000010
+#define R92C_APS_FSMCO_PDN_PL		0x00000020
+#define R92C_APS_FSMCO_APFM_ONMAC	0x00000100
+#define R92C_APS_FSMCO_APFM_OFF		0x00000200
+#define R92C_APS_FSMCO_APFM_RSM		0x00000400
+#define R92C_APS_FSMCO_AFSM_HSUS	0x00000800
+#define R92C_APS_FSMCO_AFSM_PCIE	0x00001000
+#define R92C_APS_FSMCO_APDM_MAC		0x00002000
+#define R92C_APS_FSMCO_APDM_HOST	0x00004000
+#define R92C_APS_FSMCO_APDM_HPDN	0x00008000
+#define R92C_APS_FSMCO_RDY_MACON	0x00010000
+#define R92C_APS_FSMCO_SUS_HOST		0x00020000
+#define R92C_APS_FSMCO_ROP_ALD		0x00100000
+#define R92C_APS_FSMCO_ROP_PWR		0x00200000
+#define R92C_APS_FSMCO_ROP_SPS		0x00400000
+#define R92C_APS_FSMCO_SOP_MRST		0x02000000
+#define R92C_APS_FSMCO_SOP_FUSE		0x04000000
+#define R92C_APS_FSMCO_SOP_ABG		0x08000000
+#define R92C_APS_FSMCO_SOP_AMB		0x10000000
+#define R92C_APS_FSMCO_SOP_RCK		0x20000000
+#define R92C_APS_FSMCO_SOP_A8M		0x40000000
+#define R92C_APS_FSMCO_XOP_BTCK		0x80000000
+
+/* Bits for R92C_SYS_CLKR. */
+#define R92C_SYS_CLKR_ANAD16V_EN	0x00000001
+#define R92C_SYS_CLKR_ANA8M		0x00000002
+#define R92C_SYS_CLKR_MACSLP		0x00000010
+#define R92C_SYS_CLKR_LOADER_EN		0x00000020
+#define R92C_SYS_CLKR_80M_SSC_DIS	0x00000080
+#define R92C_SYS_CLKR_80M_SSC_EN_HO	0x00000100
+#define R92C_SYS_CLKR_PHY_SSC_RSTB	0x00000200
+#define R92C_SYS_CLKR_SEC_EN		0x00000400
+#define R92C_SYS_CLKR_MAC_EN		0x00000800
+#define R92C_SYS_CLKR_SYS_EN		0x00001000
+#define R92C_SYS_CLKR_RING_EN		0x00002000
+
+/* Bits for R92C_RF_CTRL. */
+#define R92C_RF_CTRL_EN		0x01
+#define R92C_RF_CTRL_RSTB	0x02
+#define R92C_RF_CTRL_SDMRSTB	0x04
+
+/* Bits for R92C_LDOV12D_CTRL. */
+#define R92C_LDOV12D_CTRL_LDV12_EN	0x01
+
+/* Bits for R92C_AFE_XTAL_CTRL. */
+#define R92C_AFE_XTAL_CTRL_ADDR_M	0x007ff800
+#define R92C_AFE_XTAL_CTRL_ADDR_S	11
+
+/* Bits for R92C_EFUSE_CTRL. */
+#define R92C_EFUSE_CTRL_DATA_M	0x000000ff
+#define R92C_EFUSE_CTRL_DATA_S	0
+#define R92C_EFUSE_CTRL_ADDR_M	0x0003ff00
+#define R92C_EFUSE_CTRL_ADDR_S	8
+#define R92C_EFUSE_CTRL_VALID	0x80000000
+
+/* Bits for R92C_GPIO_MUXCFG. */
+#define R92C_GPIO_MUXCFG_ENBT	0x0020
+
+/* Bits for R92C_LEDCFG0. */
+#define R92C_LEDCFG0_DIS	0x08
+
+/* Bits for R92C_MCUFWDL. */
+#define R92C_MCUFWDL_EN			0x00000001
+#define R92C_MCUFWDL_RDY		0x00000002
+#define R92C_MCUFWDL_CHKSUM_RPT		0x00000004
+#define R92C_MCUFWDL_MACINI_RDY		0x00000008
+#define R92C_MCUFWDL_BBINI_RDY		0x00000010
+#define R92C_MCUFWDL_RFINI_RDY		0x00000020
+#define R92C_MCUFWDL_WINTINI_RDY	0x00000040
+#define R92C_MCUFWDL_RAM_DL_SEL		0x00000080
+#define R92C_MCUFWDL_PAGE_M		0x00070000
+#define R92C_MCUFWDL_PAGE_S		16
+#define R92C_MCUFWDL_CPRST		0x00800000
+
+/* Bits for R88E_HIMR. */
+#define R88E_HIMR_CPWM			0x00000100
+#define R88E_HIMR_CPWM2			0x00000200
+#define R88E_HIMR_TBDER			0x04000000
+#define R88E_HIMR_PSTIMEOUT		0x20000000
+
+/* Bits for R88E_HIMRE.*/
+#define R88E_HIMRE_RXFOVW		0x00000100
+#define R88E_HIMRE_TXFOVW		0x00000200
+#define R88E_HIMRE_RXERR		0x00000400
+#define R88E_HIMRE_TXERR		0x00000800
+
+/* Bits for R92C_EFUSE_ACCESS. */
+#define R92C_EFUSE_ACCESS_OFF		0x00
+#define R92C_EFUSE_ACCESS_ON		0x69
+
+/* Bits for R92C_HPON_FSM. */
+#define R92C_HPON_FSM_CHIP_BONDING_ID_S		22
+#define R92C_HPON_FSM_CHIP_BONDING_ID_M		0x00c00000
+#define R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R	1
+
+/* Bits for R92C_SYS_CFG. */
+#define R92C_SYS_CFG_XCLK_VLD		0x00000001
+#define R92C_SYS_CFG_ACLK_VLD		0x00000002
+#define R92C_SYS_CFG_UCLK_VLD		0x00000004
+#define R92C_SYS_CFG_PCLK_VLD		0x00000008
+#define R92C_SYS_CFG_PCIRSTB		0x00000010
+#define R92C_SYS_CFG_V15_VLD		0x00000020
+#define R92C_SYS_CFG_TRP_B15V_EN	0x00000080
+#define R92C_SYS_CFG_SIC_IDLE		0x00000100
+#define R92C_SYS_CFG_BD_MAC2		0x00000200
+#define R92C_SYS_CFG_BD_MAC1		0x00000400
+#define R92C_SYS_CFG_IC_MACPHY_MODE	0x00000800
+#define R92C_SYS_CFG_CHIP_VER_RTL_M	0x0000f000
+#define R92C_SYS_CFG_CHIP_VER_RTL_S	12
+#define R92C_SYS_CFG_BT_FUNC		0x00010000
+#define R92C_SYS_CFG_VENDOR_UMC		0x00080000
+#define R92C_SYS_CFG_PAD_HWPD_IDN	0x00400000
+#define R92C_SYS_CFG_TRP_VAUX_EN	0x00800000
+#define R92C_SYS_CFG_TRP_BT_EN		0x01000000
+#define R92C_SYS_CFG_BD_PKG_SEL		0x02000000
+#define R92C_SYS_CFG_BD_HCI_SEL		0x04000000
+#define R92C_SYS_CFG_TYPE_92C		0x08000000
+
+/* Bits for R92C_CR. */
+#define R92C_CR_HCI_TXDMA_EN	0x00000001
+#define R92C_CR_HCI_RXDMA_EN	0x00000002
+#define R92C_CR_TXDMA_EN	0x00000004
+#define R92C_CR_RXDMA_EN	0x00000008
+#define R92C_CR_PROTOCOL_EN	0x00000010
+#define R92C_CR_SCHEDULE_EN	0x00000020
+#define R92C_CR_MACTXEN		0x00000040
+#define R92C_CR_MACRXEN		0x00000080
+#define R92C_CR_ENSEC		0x00000200
+#define R92C_CR_CALTMR_EN	0x00000400
+#define R92C_CR_NETTYPE_S	16
+#define R92C_CR_NETTYPE_M	0x00030000
+#define R92C_CR_NETTYPE_NOLINK	0
+#define R92C_CR_NETTYPE_ADHOC	1
+#define R92C_CR_NETTYPE_INFRA	2
+#define R92C_CR_NETTYPE_AP	3
+
+/* Bits for R92C_PBP. */
+#define R92C_PBP_PSRX_M		0x0f
+#define R92C_PBP_PSRX_S		0
+#define R92C_PBP_PSTX_M		0xf0
+#define R92C_PBP_PSTX_S		4
+#define R92C_PBP_64		0
+#define R92C_PBP_128		1
+#define R92C_PBP_256		2
+#define R92C_PBP_512		3
+#define R92C_PBP_1024		4
+
+/* Bits for R92C_TRXDMA_CTRL. */
+#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
+#define R92C_TRXDMA_CTRL_TXDMA_VIQ_MAP_M	0x00c0
+#define R92C_TRXDMA_CTRL_TXDMA_VIQ_MAP_S	6
+#define R92C_TRXDMA_CTRL_TXDMA_BEQ_MAP_M	0x0300
+#define R92C_TRXDMA_CTRL_TXDMA_BEQ_MAP_S	8
+#define R92C_TRXDMA_CTRL_TXDMA_BKQ_MAP_M	0x0c00
+#define R92C_TRXDMA_CTRL_TXDMA_BKQ_MAP_S	10
+#define R92C_TRXDMA_CTRL_TXDMA_MGQ_MAP_M	0x3000
+#define R92C_TRXDMA_CTRL_TXDMA_MGQ_MAP_S	12
+#define R92C_TRXDMA_CTRL_TXDMA_HIQ_MAP_M	0xc000
+#define R92C_TRXDMA_CTRL_TXDMA_HIQ_MAP_S	14
+#define R92C_TRXDMA_CTRL_QUEUE_LOW		1
+#define R92C_TRXDMA_CTRL_QUEUE_NORMAL		2
+#define R92C_TRXDMA_CTRL_QUEUE_HIGH		3
+#define R92C_TRXDMA_CTRL_QMAP_M			0xfff0
+/* Shortcuts. */
+#define R92C_TRXDMA_CTRL_QMAP_3EP		0xf5b0
+#define R92C_TRXDMA_CTRL_QMAP_HQ_LQ		0xf5f0
+#define R92C_TRXDMA_CTRL_QMAP_HQ_NQ		0xfaf0
+#define R92C_TRXDMA_CTRL_QMAP_LQ		0x5550
+#define R92C_TRXDMA_CTRL_QMAP_NQ		0xaaa0
+#define R92C_TRXDMA_CTRL_QMAP_HQ		0xfff0
+
+/* Bits for R92C_LLT_INIT. */
+#define R92C_LLT_INIT_DATA_M		0x000000ff
+#define R92C_LLT_INIT_DATA_S		0
+#define R92C_LLT_INIT_ADDR_M		0x0000ff00
+#define R92C_LLT_INIT_ADDR_S		8
+#define R92C_LLT_INIT_OP_M		0xc0000000
+#define R92C_LLT_INIT_OP_S		30
+#define R92C_LLT_INIT_OP_NO_ACTIVE	0
+#define R92C_LLT_INIT_OP_WRITE		1
+
+/* Bits for R92C_RQPN. */
+#define R92C_RQPN_HPQ_M		0x000000ff
+#define R92C_RQPN_HPQ_S		0
+#define R92C_RQPN_LPQ_M		0x0000ff00
+#define R92C_RQPN_LPQ_S		8
+#define R92C_RQPN_PUBQ_M	0x00ff0000
+#define R92C_RQPN_PUBQ_S	16
+#define R92C_RQPN_LD		0x80000000
+
+/* Bits for R92C_TDECTRL. */
+#define R92C_TDECTRL_BLK_DESC_NUM_M	0x0000000f
+#define R92C_TDECTRL_BLK_DESC_NUM_S	4
+
+/* Bits for R92C_FWHW_TXQ_CTRL. */
+#define R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW	0x80
+
+/* Bits for R92C_SPEC_SIFS. */
+#define R92C_SPEC_SIFS_CCK_M	0x00ff
+#define R92C_SPEC_SIFS_CCK_S	0
+#define R92C_SPEC_SIFS_OFDM_M	0xff00
+#define R92C_SPEC_SIFS_OFDM_S	8
+
+/* Bits for R92C_RL. */
+#define R92C_RL_LRL_M		0x003f
+#define R92C_RL_LRL_S		0
+#define R92C_RL_SRL_M		0x3f00
+#define R92C_RL_SRL_S		8
+
+/* Bits for R92C_RRSR. */
+#define R92C_RRSR_RATE_BITMAP_M		0x000fffff
+#define R92C_RRSR_RATE_BITMAP_S		0
+#define R92C_RRSR_RATE_CCK_ONLY_1M	0xffff1
+#define R92C_RRSR_RSC_LOWSUBCHNL	0x00200000
+#define R92C_RRSR_RSC_UPSUBCHNL		0x00400000
+#define R92C_RRSR_SHORT			0x00800000
+
+/* Bits for R92C_EDCA_XX_PARAM. */
+#define R92C_EDCA_PARAM_AIFS_M		0x000000ff
+#define R92C_EDCA_PARAM_AIFS_S		0
+#define R92C_EDCA_PARAM_ECWMIN_M	0x00000f00
+#define R92C_EDCA_PARAM_ECWMIN_S	8
+#define R92C_EDCA_PARAM_ECWMAX_M	0x0000f000
+#define R92C_EDCA_PARAM_ECWMAX_S	12
+#define R92C_EDCA_PARAM_TXOP_M		0xffff0000
+#define R92C_EDCA_PARAM_TXOP_S		16
+
+/* Bits for R92C_BCN_CTRL. */
+#define R92C_BCN_CTRL_EN_MBSSID		0x02
+#define R92C_BCN_CTRL_TXBCN_RPT		0x04
+#define R92C_BCN_CTRL_EN_BCN		0x08
+#define R92C_BCN_CTRL_DIS_TSF_UDT0	0x10
+
+/* Bits for R92C_APSD_CTRL. */
+#define R92C_APSD_CTRL_OFF		0x40
+#define R92C_APSD_CTRL_OFF_STATUS	0x80
+
+/* Bits for R92C_BWOPMODE. */
+#define R92C_BWOPMODE_11J	0x01
+#define R92C_BWOPMODE_5G	0x02
+#define R92C_BWOPMODE_20MHZ	0x04
+
+/* Bits for R92C_RCR. */
+#define R92C_RCR_AAP		0x00000001
+#define R92C_RCR_APM		0x00000002
+#define R92C_RCR_AM		0x00000004
+#define R92C_RCR_AB		0x00000008
+#define R92C_RCR_ADD3		0x00000010
+#define R92C_RCR_APWRMGT	0x00000020
+#define R92C_RCR_CBSSID_DATA	0x00000040
+#define R92C_RCR_CBSSID_BCN	0x00000080
+#define R92C_RCR_ACRC32		0x00000100
+#define R92C_RCR_AICV		0x00000200
+#define R92C_RCR_ADF		0x00000800
+#define R92C_RCR_ACF		0x00001000
+#define R92C_RCR_AMF		0x00002000
+#define R92C_RCR_HTC_LOC_CTRL	0x00004000
+#define R92C_RCR_MFBEN		0x00400000
+#define R92C_RCR_LSIGEN		0x00800000
+#define R92C_RCR_ENMBID		0x01000000
+#define R92C_RCR_APP_BA_SSN	0x08000000
+#define R92C_RCR_APP_PHYSTS	0x10000000
+#define R92C_RCR_APP_ICV	0x20000000
+#define R92C_RCR_APP_MIC	0x40000000
+#define R92C_RCR_APPFCS		0x80000000
+
+/* Bits for R92C_CAMCMD. */
+#define R92C_CAMCMD_ADDR_M	0x0000ffff
+#define R92C_CAMCMD_ADDR_S	0
+#define R92C_CAMCMD_WRITE	0x00010000
+#define R92C_CAMCMD_CLR		0x40000000
+#define R92C_CAMCMD_POLLING	0x80000000
+
+
+/*
+ * Baseband registers.
+ */
+#define R92C_FPGA0_RFMOD		0x800
+#define R92C_FPGA0_TXINFO		0x804
+#define R92C_HSSI_PARAM1(chain)		(0x820 + (chain) * 8)
+#define R92C_HSSI_PARAM2(chain)		(0x824 + (chain) * 8)
+#define R92C_TXAGC_RATE18_06(i)		(((i) == 0) ? 0xe00 : 0x830)
+#define R92C_TXAGC_RATE54_24(i)		(((i) == 0) ? 0xe04 : 0x834)
+#define R92C_TXAGC_A_CCK1_MCS32		0xe08
+#define R92C_TXAGC_B_CCK1_55_MCS32	0x838
+#define R92C_TXAGC_B_CCK11_A_CCK2_11	0x86c
+#define R92C_TXAGC_MCS03_MCS00(i)	(((i) == 0) ? 0xe10 : 0x83c)
+#define R92C_TXAGC_MCS07_MCS04(i)	(((i) == 0) ? 0xe14 : 0x848)
+#define R92C_TXAGC_MCS11_MCS08(i)	(((i) == 0) ? 0xe18 : 0x84c)
+#define R92C_TXAGC_MCS15_MCS12(i)	(((i) == 0) ? 0xe1c : 0x868)
+#define R92C_LSSI_PARAM(chain)		(0x840 + (chain) * 4)
+#define R92C_FPGA0_RFIFACEOE(chain)	(0x860 + (chain) * 4)
+#define R92C_FPGA0_RFIFACESW(idx)	(0x870 + (idx) * 4)
+#define R92C_FPGA0_RFPARAM(idx)		(0x878 + (idx) * 4)
+#define R92C_FPGA0_ANAPARAM2		0x884
+#define R92C_LSSI_READBACK(chain)	(0x8a0 + (chain) * 4)
+#define R92C_HSPI_READBACK(chain)	(0x8b8 + (chain) * 4)
+#define R92C_FPGA1_RFMOD		0x900
+#define R92C_FPGA1_TXINFO		0x90c
+#define R92C_CCK0_SYSTEM		0xa00
+#define R92C_CCK0_AFESETTING		0xa04
+#define R92C_OFDM0_TRXPATHENA		0xc04
+#define R92C_OFDM0_TRMUXPAR		0xc08
+#define R92C_OFDM0_AGCCORE1(chain)	(0xc50 + (chain) * 8)
+#define R92C_OFDM0_AGCPARAM1		0xc70
+#define R92C_OFDM0_AGCRSSITABLE		0xc78
+#define R92C_OFDM1_LSTF			0xd00
+
+/* Bits for R92C_FPGA[01]_RFMOD. */
+#define R92C_RFMOD_40MHZ	0x00000001
+#define R92C_RFMOD_JAPAN	0x00000002
+#define R92C_RFMOD_CCK_TXSC	0x00000030
+#define R92C_RFMOD_CCK_EN	0x01000000
+#define R92C_RFMOD_OFDM_EN	0x02000000
+
+/* Bits for R92C_HSSI_PARAM1(i). */
+#define R92C_HSSI_PARAM1_PI	0x00000100
+
+/* Bits for R92C_HSSI_PARAM2(i). */
+#define R92C_HSSI_PARAM2_CCK_HIPWR	0x00000200
+#define R92C_HSSI_PARAM2_ADDR_LENGTH	0x00000400
+#define R92C_HSSI_PARAM2_DATA_LENGTH	0x00000800
+#define R92C_HSSI_PARAM2_READ_ADDR_M	0x7f800000
+#define R92C_HSSI_PARAM2_READ_ADDR_S	23
+#define R92C_HSSI_PARAM2_READ_EDGE	0x80000000
+
+/* Bits for R92C_TXAGC_A_CCK1_MCS32. */
+#define R92C_TXAGC_A_CCK1_M	0x0000ff00
+#define R92C_TXAGC_A_CCK1_S	8
+
+/* Bits for R92C_TXAGC_B_CCK11_A_CCK2_11. */
+#define R92C_TXAGC_B_CCK11_M	0x000000ff
+#define R92C_TXAGC_B_CCK11_S	0
+#define R92C_TXAGC_A_CCK2_M	0x0000ff00
+#define R92C_TXAGC_A_CCK2_S	8
+#define R92C_TXAGC_A_CCK55_M	0x00ff0000
+#define R92C_TXAGC_A_CCK55_S	16
+#define R92C_TXAGC_A_CCK11_M	0xff000000
+#define R92C_TXAGC_A_CCK11_S	24
+
+/* Bits for R92C_TXAGC_B_CCK1_55_MCS32. */
+#define R92C_TXAGC_B_CCK1_M	0x0000ff00
+#define R92C_TXAGC_B_CCK1_S	8
+#define R92C_TXAGC_B_CCK2_M	0x00ff0000
+#define R92C_TXAGC_B_CCK2_S	16
+#define R92C_TXAGC_B_CCK55_M	0xff000000
+#define R92C_TXAGC_B_CCK55_S	24
+
+/* Bits for R92C_TXAGC_RATE18_06(x). */
+#define R92C_TXAGC_RATE06_M	0x000000ff
+#define R92C_TXAGC_RATE06_S	0
+#define R92C_TXAGC_RATE09_M	0x0000ff00
+#define R92C_TXAGC_RATE09_S	8
+#define R92C_TXAGC_RATE12_M	0x00ff0000
+#define R92C_TXAGC_RATE12_S	16
+#define R92C_TXAGC_RATE18_M	0xff000000
+#define R92C_TXAGC_RATE18_S	24
+
+/* Bits for R92C_TXAGC_RATE54_24(x). */
+#define R92C_TXAGC_RATE24_M	0x000000ff
+#define R92C_TXAGC_RATE24_S	0
+#define R92C_TXAGC_RATE36_M	0x0000ff00
+#define R92C_TXAGC_RATE36_S	8
+#define R92C_TXAGC_RATE48_M	0x00ff0000
+#define R92C_TXAGC_RATE48_S	16
+#define R92C_TXAGC_RATE54_M	0xff000000
+#define R92C_TXAGC_RATE54_S	24
+
+/* Bits for R92C_TXAGC_MCS03_MCS00(x). */
+#define R92C_TXAGC_MCS00_M	0x000000ff
+#define R92C_TXAGC_MCS00_S	0
+#define R92C_TXAGC_MCS01_M	0x0000ff00
+#define R92C_TXAGC_MCS01_S	8
+#define R92C_TXAGC_MCS02_M	0x00ff0000
+#define R92C_TXAGC_MCS02_S	16
+#define R92C_TXAGC_MCS03_M	0xff000000
+#define R92C_TXAGC_MCS03_S	24
+
+/* Bits for R92C_TXAGC_MCS07_MCS04(x). */
+#define R92C_TXAGC_MCS04_M	0x000000ff
+#define R92C_TXAGC_MCS04_S	0
+#define R92C_TXAGC_MCS05_M	0x0000ff00
+#define R92C_TXAGC_MCS05_S	8
+#define R92C_TXAGC_MCS06_M	0x00ff0000
+#define R92C_TXAGC_MCS06_S	16
+#define R92C_TXAGC_MCS07_M	0xff000000
+#define R92C_TXAGC_MCS07_S	24
+
+/* Bits for R92C_TXAGC_MCS11_MCS08(x). */
+#define R92C_TXAGC_MCS08_M	0x000000ff
+#define R92C_TXAGC_MCS08_S	0
+#define R92C_TXAGC_MCS09_M	0x0000ff00
+#define R92C_TXAGC_MCS09_S	8
+#define R92C_TXAGC_MCS10_M	0x00ff0000
+#define R92C_TXAGC_MCS10_S	16
+#define R92C_TXAGC_MCS11_M	0xff000000
+#define R92C_TXAGC_MCS11_S	24
+
+/* Bits for R92C_TXAGC_MCS15_MCS12(x). */
+#define R92C_TXAGC_MCS12_M	0x000000ff
+#define R92C_TXAGC_MCS12_S	0
+#define R92C_TXAGC_MCS13_M	0x0000ff00
+#define R92C_TXAGC_MCS13_S	8
+#define R92C_TXAGC_MCS14_M	0x00ff0000
+#define R92C_TXAGC_MCS14_S	16
+#define R92C_TXAGC_MCS15_M	0xff000000
+#define R92C_TXAGC_MCS15_S	24
+
+/* Bits for R92C_LSSI_PARAM(i). */
+#define R92C_LSSI_PARAM_DATA_M	0x000fffff
+#define R92C_LSSI_PARAM_DATA_S	0
+#define R92C_LSSI_PARAM_ADDR_M	0x03f00000
+#define R92C_LSSI_PARAM_ADDR_S	20
+#define R88E_LSSI_PARAM_ADDR_M	0x0ff00000
+#define R88E_LSSI_PARAM_ADDR_S	20
+
+/* Bits for R92C_FPGA0_ANAPARAM2. */
+#define R92C_FPGA0_ANAPARAM2_CBW20	0x00000400
+
+/* Bits for R92C_LSSI_READBACK(i). */
+#define R92C_LSSI_READBACK_DATA_M	0x000fffff
+#define R92C_LSSI_READBACK_DATA_S	0
+
+/* Bits for R92C_OFDM0_AGCCORE1(i). */
+#define R92C_OFDM0_AGCCORE1_GAIN_M	0x0000007f
+#define R92C_OFDM0_AGCCORE1_GAIN_S	0
+
+
+/*
+ * USB registers.
+ */
+#define R92C_USB_INFO			0xfe17
+#define R92C_USB_SPECIAL_OPTION		0xfe55
+#define R92C_USB_HCPWM			0xfe57
+#define R92C_USB_HRPWM			0xfe58
+#define R92C_USB_DMA_AGG_TO		0xfe5b
+#define R92C_USB_AGG_TO			0xfe5c
+#define R92C_USB_AGG_TH			0xfe5d
+#define R92C_USB_VID			0xfe60
+#define R92C_USB_PID			0xfe62
+#define R92C_USB_OPTIONAL		0xfe64
+#define R92C_USB_EP			0xfe65
+#define R92C_USB_PHY			0xfe68
+#define R92C_USB_MAC_ADDR		0xfe70
+#define R92C_USB_STRING			0xfe80
+
+/* Bits for R92C_USB_SPECIAL_OPTION. */
+#define R92C_USB_SPECIAL_OPTION_AGG_EN		0x08
+#define R92C_USB_SPECIAL_OPTION_INT_BULK_SEL	0x10
+
+/* Bits for R92C_USB_EP. */
+#define R92C_USB_EP_HQ_M	0x000f
+#define R92C_USB_EP_HQ_S	0
+#define R92C_USB_EP_NQ_M	0x00f0
+#define R92C_USB_EP_NQ_S	4
+#define R92C_USB_EP_LQ_M	0x0f00
+#define R92C_USB_EP_LQ_S	8
+
+
+/*
+ * Firmware base address.
+ */
+#define R92C_FW_START_ADDR	0x1000
+#define R92C_FW_PAGE_SIZE	4096
+
+
+/*
+ * RF (6052) registers.
+ */
+#define R92C_RF_AC		0x00
+#define R92C_RF_IQADJ_G(i)	(0x01 + (i))
+#define R92C_RF_POW_TRSW	0x05
+#define R92C_RF_GAIN_RX		0x06
+#define R92C_RF_GAIN_TX		0x07
+#define R92C_RF_TXM_IDAC	0x08
+#define R92C_RF_BS_IQGEN	0x0f
+#define R92C_RF_MODE1		0x10
+#define R92C_RF_MODE2		0x11
+#define R92C_RF_RX_AGC_HP	0x12
+#define R92C_RF_TX_AGC		0x13
+#define R92C_RF_BIAS		0x14
+#define R92C_RF_IPA		0x15
+#define R92C_RF_POW_ABILITY	0x17
+#define R92C_RF_CHNLBW		0x18
+#define R92C_RF_RX_G1		0x1a
+#define R92C_RF_RX_G2		0x1b
+#define R92C_RF_RX_BB2		0x1c
+#define R92C_RF_RX_BB1		0x1d
+#define R92C_RF_RCK1		0x1e
+#define R92C_RF_RCK2		0x1f
+#define R92C_RF_TX_G(i)		(0x20 + (i))
+#define R92C_RF_TX_BB1		0x23
+#define R92C_RF_T_METER		0x24
+#define R92C_RF_SYN_G(i)	(0x25 + (i))
+#define R92C_RF_RCK_OS		0x30
+#define R92C_RF_TXPA_G(i)	(0x31 + (i))
+
+/* Bits for R92C_RF_AC. */
+#define R92C_RF_AC_MODE_M	0x70000
+#define R92C_RF_AC_MODE_S	16
+#define R92C_RF_AC_MODE_STANDBY	1
+
+/* Bits for R92C_RF_CHNLBW. */
+#define R92C_RF_CHNLBW_CHNL_M	0x003ff
+#define R92C_RF_CHNLBW_CHNL_S	0
+#define R92C_RF_CHNLBW_BW20	0x00400
+#define R88E_RF_CHNLBW_BW20	0x00c00
+#define R92C_RF_CHNLBW_LCSTART	0x08000
+
+
+/*
+ * CAM entries.
+ */
+#define R92C_CAM_ENTRY_COUNT	32
+
+#define R92C_CAM_CTL0(entry)	((entry) * 8 + 0)
+#define R92C_CAM_CTL1(entry)	((entry) * 8 + 1)
+#define R92C_CAM_KEY(entry, i)	((entry) * 8 + 2 + (i))
+
+/* Bits for R92C_CAM_CTL0(i). */
+#define R92C_CAM_KEYID_M	0x00000003
+#define R92C_CAM_KEYID_S	0
+#define R92C_CAM_ALGO_M		0x0000001c
+#define R92C_CAM_ALGO_S		2
+#define R92C_CAM_ALGO_NONE	0
+#define R92C_CAM_ALGO_WEP40	1
+#define R92C_CAM_ALGO_TKIP	2
+#define R92C_CAM_ALGO_AES	4
+#define R92C_CAM_ALGO_WEP104	5
+#define R92C_CAM_VALID		0x00008000
+#define R92C_CAM_MACLO_M	0xffff0000
+#define R92C_CAM_MACLO_S	16
+
+/* Rate adaptation modes. */
+#define R92C_RAID_11GN	1
+#define R92C_RAID_11N	3
+#define R92C_RAID_11BG	4
+#define R92C_RAID_11G	5	/* "pure" 11g */
+#define R92C_RAID_11B	6
+
+
+/* Macros to access unaligned little-endian memory. */
+#define LE_READ_2(x)	((x)[0] | (x)[1] << 8)
+#define LE_READ_4(x)	((x)[0] | (x)[1] << 8 | (x)[2] << 16 | (x)[3] << 24)
+
+/*
+ * Macros to access subfields in registers.
+ */
+/* Mask and Shift (getter). */
+#define MS(val, field)							\
+	(((val) & field##_M) >> field##_S)
+
+/* Shift and Mask (setter). */
+#define SM(field, val)							\
+	(((val) << field##_S) & field##_M)
+
+/* Rewrite. */
+#define RW(var, field, val)						\
+	(((var) & ~field##_M) | SM(field, val))
+
+/*
+ * Firmware image header.
+ */
+struct r92c_fw_hdr {
+	/* QWORD0 */
+	uint16_t	signature;
+	uint8_t		category;
+	uint8_t		function;
+	uint16_t	version;
+	uint16_t	subversion;
+	/* QWORD1 */
+	uint8_t		month;
+	uint8_t		date;
+	uint8_t		hour;
+	uint8_t		minute;
+	uint16_t	ramcodesize;
+	uint16_t	reserved2;
+	/* QWORD2 */
+	uint32_t	svnidx;
+	uint32_t	reserved3;
+	/* QWORD3 */
+	uint32_t	reserved4;
+	uint32_t	reserved5;
+} __packed;
+
+/*
+ * Host to firmware commands.
+ */
+struct r92c_fw_cmd {
+	uint8_t	id;
+#define R92C_CMD_AP_OFFLOAD		0
+#define R92C_CMD_SET_PWRMODE		1
+#define R92C_CMD_JOINBSS_RPT		2
+#define R92C_CMD_RSVD_PAGE		3
+#define R92C_CMD_RSSI			4
+#define R92C_CMD_RSSI_SETTING		5
+#define R92C_CMD_MACID_CONFIG		6
+#define R92C_CMD_MACID_PS_MODE		7
+#define R92C_CMD_P2P_PS_OFFLOAD		8
+#define R92C_CMD_SELECTIVE_SUSPEND	9
+#define R92C_CMD_FLAG_EXT		0x80
+
+	uint8_t	msg[5];
+} __packed;
+
+/* Structure for R92C_CMD_RSSI_SETTING. */
+struct r92c_fw_cmd_rssi {
+	uint8_t	macid;
+	uint8_t	reserved;
+	uint8_t	pwdb;
+} __packed;
+
+/* Structure for R92C_CMD_MACID_CONFIG. */
+struct r92c_fw_cmd_macid_cfg {
+	uint32_t	mask;
+	uint8_t		macid;
+#define URTWN_MACID_BSS		0
+#define URTWN_MACID_BC		4	/* Broadcast. */
+#define URTWN_MACID_VALID	0x80
+} __packed;
+
+/*
+ * RTL8192CU ROM image.
+ */
+struct r92c_rom {
+	uint16_t	id;		/* 0x8192 */
+	uint8_t		reserved1[5];
+	uint8_t		dbg_sel;
+	uint16_t	reserved2;
+	uint16_t	vid;
+	uint16_t	pid;
+	uint8_t		usb_opt;
+	uint8_t		ep_setting;
+	uint16_t	reserved3;
+	uint8_t		usb_phy;
+	uint8_t		reserved4[3];
+	uint8_t		macaddr[6];
+	uint8_t		string[61];	/* "Realtek" */
+	uint8_t		subcustomer_id;
+	uint8_t		cck_tx_pwr[R92C_MAX_CHAINS][3];
+	uint8_t		ht40_1s_tx_pwr[R92C_MAX_CHAINS][3];
+	uint8_t		ht40_2s_tx_pwr_diff[3];
+	uint8_t		ht20_tx_pwr_diff[3];
+	uint8_t		ofdm_tx_pwr_diff[3];
+	uint8_t		ht40_max_pwr[3];
+	uint8_t		ht20_max_pwr[3];
+	uint8_t		xtal_calib;
+	uint8_t		tssi[R92C_MAX_CHAINS];
+	uint8_t		thermal_meter;
+	uint8_t		rf_opt1;
+#define R92C_ROM_RF1_REGULATORY_M	0x07
+#define R92C_ROM_RF1_REGULATORY_S	0
+#define R92C_ROM_RF1_BOARD_TYPE_M	0xe0
+#define R92C_ROM_RF1_BOARD_TYPE_S	5
+#define R92C_BOARD_TYPE_DONGLE		0
+#define R92C_BOARD_TYPE_HIGHPA		1
+#define R92C_BOARD_TYPE_MINICARD	2
+#define R92C_BOARD_TYPE_SOLO		3
+#define R92C_BOARD_TYPE_COMBO		4
+
+	uint8_t		rf_opt2;
+	uint8_t		rf_opt3;
+	uint8_t		rf_opt4;
+	uint8_t		channel_plan;
+	uint8_t		version;
+	uint8_t		curstomer_id;
+} __packed;
+
+/* Rx MAC descriptor. */
+struct r92c_rx_stat {
+	uint32_t	rxdw0;
+#define R92C_RXDW0_PKTLEN_M	0x00003fff
+#define R92C_RXDW0_PKTLEN_S	0
+#define R92C_RXDW0_CRCERR	0x00004000
+#define R92C_RXDW0_ICVERR	0x00008000
+#define R92C_RXDW0_INFOSZ_M	0x000f0000
+#define R92C_RXDW0_INFOSZ_S	16
+#define R92C_RXDW0_QOS		0x00800000
+#define R92C_RXDW0_SHIFT_M	0x03000000
+#define R92C_RXDW0_SHIFT_S	24
+#define R92C_RXDW0_PHYST	0x04000000
+#define R92C_RXDW0_DECRYPTED	0x08000000
+
+	uint32_t	rxdw1;
+	uint32_t	rxdw2;
+#define R92C_RXDW2_PKTCNT_M	0x00ff0000
+#define R92C_RXDW2_PKTCNT_S	16
+
+	uint32_t	rxdw3;
+#define R92C_RXDW3_RATE_M	0x0000003f
+#define R92C_RXDW3_RATE_S	0
+#define R92C_RXDW3_HT		0x00000040
+#define R92C_RXDW3_HTC		0x00000400
+
+	uint32_t	rxdw4;
+	uint32_t	rxdw5;
+} __packed __attribute__((aligned(4)));
+
+/* Rx PHY descriptor. */
+struct r92c_rx_phystat {
+	uint32_t	phydw0;
+	uint32_t	phydw1;
+	uint32_t	phydw2;
+	uint32_t	phydw3;
+	uint32_t	phydw4;
+	uint32_t	phydw5;
+	uint32_t	phydw6;
+	uint32_t	phydw7;
+} __packed __attribute__((aligned(4)));
+
+/* Rx PHY CCK descriptor. */
+struct r92c_rx_cck {
+	uint8_t		adc_pwdb[4];
+	uint8_t		sq_rpt;
+	uint8_t		agc_rpt;
+} __packed;
+
+struct r88e_rx_cck {
+	uint8_t		path_agc[2];
+	uint8_t		sig_qual;
+	uint8_t		agc_rpt;
+	uint8_t		rpt_b;
+	uint8_t 	reserved1;
+	uint8_t		noise_power;
+	uint8_t		path_cfotail[2];        
+	uint8_t		pcts_mask[2];   
+	uint8_t		stream_rxevm[2];        
+	uint8_t		path_rxsnr[2];
+	uint8_t		noise_power_db_lsb;
+	uint8_t		reserved2[3];
+	uint8_t		stream_csi[2];
+	uint8_t		stream_target_csi[2];
+	uint8_t		sig_evm;
+	uint8_t		reserved3;
+	uint8_t		reserved4;
+} __packed;
+
+/* Tx MAC descriptor. */
+struct r92c_tx_desc {
+	uint32_t	txdw0;
+#define R92C_TXDW0_PKTLEN_M	0x0000ffff
+#define R92C_TXDW0_PKTLEN_S	0
+#define R92C_TXDW0_OFFSET_M	0x00ff0000
+#define R92C_TXDW0_OFFSET_S	16
+#define R92C_TXDW0_BMCAST	0x01000000
+#define R92C_TXDW0_LSG		0x04000000
+#define R92C_TXDW0_FSG		0x08000000
+#define R92C_TXDW0_OWN		0x80000000
+
+	uint32_t	txdw1;
+#define R92C_TXDW1_MACID_M	0x0000001f
+#define R92C_TXDW1_MACID_S	0
+#define R88E_TXDW1_MACID_M	0x0000003f
+#define R88E_TXDW1_MACID_S	0
+#define R92C_TXDW1_AGGEN	0x00000020
+#define R92C_TXDW1_AGGBK	0x00000040
+#define R92C_TXDW1_QSEL_M	0x00001f00
+#define R92C_TXDW1_QSEL_S	8
+#define R92C_TXDW1_QSEL_BE	0x00
+#define R92C_TXDW1_QSEL_MGNT	0x12
+#define R92C_TXDW1_RAID_M	0x000f0000
+#define R92C_TXDW1_RAID_S	16
+#define R92C_TXDW1_CIPHER_M	0x00c00000
+#define R92C_TXDW1_CIPHER_S	22
+#define R92C_TXDW1_CIPHER_NONE	0
+#define R92C_TXDW1_CIPHER_RC4	1
+#define R92C_TXDW1_CIPHER_AES	3
+#define R92C_TXDW1_PKTOFF_M	0x7c000000
+#define R92C_TXDW1_PKTOFF_S	26
+
+	uint32_t	txdw2;
+#define R88E_TXDW2_AGGBK	0x00010000
+
+	uint16_t	txdw3;
+	uint16_t	txdseq;
+
+	uint32_t	txdw4;
+#define R92C_TXDW4_RTSRATE_M	0x0000003f
+#define R92C_TXDW4_RTSRATE_S	0
+#define R92C_TXDW4_QOS		0x00000040
+#define R92C_TXDW4_HWSEQ	0x00000080
+#define R92C_TXDW4_DRVRATE	0x00000100
+#define R92C_TXDW4_CTS2SELF	0x00000800
+#define R92C_TXDW4_RTSEN	0x00001000
+#define R92C_TXDW4_HWRTSEN	0x00002000
+#define R92C_TXDW4_SCO_M	0x003f0000
+#define R92C_TXDW4_SCO_S	20
+#define R92C_TXDW4_SCO_SCA	1
+#define R92C_TXDW4_SCO_SCB	2
+#define R92C_TXDW4_40MHZ	0x02000000
+
+	uint32_t	txdw5;
+#define R92C_TXDW5_DATARATE_M	0x0000003f
+#define R92C_TXDW5_DATARATE_S	0
+#define R92C_TXDW5_SGI		0x00000040
+#define R92C_TXDW5_AGGNUM_M	0xff000000
+#define R92C_TXDW5_AGGNUM_S	24
+
+	uint32_t	txdw6;
+	uint16_t	txdsum;
+	uint16_t	pad;
+} __packed __attribute__((aligned(4)));
+
+
+/*
+ * Driver definitions.
+ */
+#define URTWN_RX_LIST_COUNT		1
+#define URTWN_TX_LIST_COUNT		8
+#define URTWN_HOST_CMD_RING_COUNT	32
+
+#define URTWN_RXBUFSZ	(16 * 1024)
+#define URTWN_TXBUFSZ	(sizeof(struct r92c_tx_desc) + IEEE80211_MAX_LEN)
+#define	URTWN_RX_DESC_SIZE	(sizeof(struct r92c_rx_stat))
+#define	URTWN_TX_DESC_SIZE	(sizeof(struct r92c_tx_desc))
+
+#define URTWN_RIDX_COUNT	28
+
+#define URTWN_TX_TIMEOUT	5000	/* ms */
+
+#define URTWN_LED_LINK	0
+#define URTWN_LED_DATA	1
+
+struct urtwn_rx_radiotap_header {
+	struct ieee80211_radiotap_header wr_ihdr;
+	uint8_t		wr_flags;
+	uint8_t		wr_rate;
+	uint16_t	wr_chan_freq;
+	uint16_t	wr_chan_flags;
+	uint8_t		wr_dbm_antsignal;
+} __packed __aligned(8);
+
+#define URTWN_RX_RADIOTAP_PRESENT			\
+	(1 << IEEE80211_RADIOTAP_FLAGS |		\
+	 1 << IEEE80211_RADIOTAP_RATE |			\
+	 1 << IEEE80211_RADIOTAP_CHANNEL |		\
+	 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)
+
+struct urtwn_tx_radiotap_header {
+	struct ieee80211_radiotap_header wt_ihdr;
+	uint8_t		wt_flags;
+	uint16_t	wt_chan_freq;
+	uint16_t	wt_chan_flags;
+} __packed __aligned(8);
+
+#define URTWN_TX_RADIOTAP_PRESENT			\
+	(1 << IEEE80211_RADIOTAP_FLAGS |		\
+	 1 << IEEE80211_RADIOTAP_CHANNEL)
+
+struct urtwn_softc;
+
+struct urtwn_data {
+	struct urtwn_softc		*sc;
+	uint8_t				*buf;
+	uint16_t			buflen;
+	struct mbuf			*m;
+	struct ieee80211_node		*ni;
+	STAILQ_ENTRY(urtwn_data)	next;
+};
+typedef STAILQ_HEAD(, urtwn_data) urtwn_datahead;
+
+struct urtwn_cmdq {
+	void			*arg0;
+	void			*arg1;
+	void			(*func)(void *);
+	struct ieee80211_key	*k;
+	struct ieee80211_key	key;
+	uint8_t			mac[IEEE80211_ADDR_LEN];
+	uint8_t			wcid;
+};
+
+struct urtwn_fw_info {
+	const uint8_t		*data;
+	size_t			size;
+};
+
+struct urtwn_vap {
+	struct ieee80211vap		vap;
+	struct ieee80211_beacon_offsets	bo;
+
+	int				(*newstate)(struct ieee80211vap *,
+					    enum ieee80211_state, int);
+};
+#define	URTWN_VAP(vap)	((struct urtwn_vap *)(vap))
+
+struct urtwn_host_cmd {
+	void	(*cb)(struct urtwn_softc *, void *);
+	uint8_t	data[256];
+};
+
+struct urtwn_cmd_newstate {
+	enum ieee80211_state	state;
+	int			arg;
+};
+
+struct urtwn_cmd_key {
+	struct ieee80211_key	key;
+	uint16_t		associd;
+};
+
+enum {
+	URTWN_BULK_RX,
+	URTWN_BULK_TX_BE,	/* = WME_AC_BE */
+	URTWN_BULK_TX_BK,	/* = WME_AC_BK */
+	URTWN_BULK_TX_VI,	/* = WME_AC_VI */
+	URTWN_BULK_TX_VO,	/* = WME_AC_VI */
+	URTWN_N_TRANSFER = 5,
+};
+
+#define	URTWN_EP_QUEUES	URTWN_BULK_RX
+
+struct urtwn_softc {
+	struct ifnet			*sc_ifp;
+	device_t			sc_dev;
+	struct usb_device		*sc_udev;
+
+	int				ac2idx[WME_NUM_AC];
+	u_int				sc_flags;
+#define URTWN_FLAG_CCK_HIPWR	0x01
+#define URTWN_DETACHED		0x02
+
+	u_int				chip;
+#define	URTWN_CHIP_92C		0x01
+#define	URTWN_CHIP_92C_1T2R	0x02
+#define	URTWN_CHIP_UMC		0x04
+#define	URTWN_CHIP_UMC_A_CUT	0x08
+#define	URTWN_CHIP_88E		0x10
+
+	void				(*sc_rf_write)(struct urtwn_softc *,
+					    int, uint8_t, uint32_t);
+	int				(*sc_power_on)(struct urtwn_softc *);
+	int				(*sc_dma_init)(struct urtwn_softc *);
+
+	uint8_t				board_type;
+	uint8_t				regulatory;
+	uint8_t				pa_setting;
+	int				avg_pwdb;
+	int				thcal_state;
+	int				thcal_lctemp;
+	int				ntxchains;
+	int				nrxchains;
+	int				ledlink;
+	int				sc_txtimer;
+
+	int				fwcur;
+	struct urtwn_data		sc_rx[URTWN_RX_LIST_COUNT];
+	urtwn_datahead			sc_rx_active;
+	urtwn_datahead			sc_rx_inactive;
+	struct urtwn_data		sc_tx[URTWN_TX_LIST_COUNT];
+	urtwn_datahead			sc_tx_active;
+	urtwn_datahead			sc_tx_inactive;
+	urtwn_datahead			sc_tx_pending;
+
+	const char			*fwname;
+	const struct firmware		*fw_fp;
+	struct urtwn_fw_info		fw;
+	void				*fw_virtaddr;
+
+	struct r92c_rom			rom;
+	uint8_t				r88e_rom[512];
+	uint8_t				cck_tx_pwr[6];
+	uint8_t				ht40_tx_pwr[5];
+	int8_t				bw20_tx_pwr_diff;
+	int8_t				ofdm_tx_pwr_diff;
+	uint8_t				sc_bssid[IEEE80211_ADDR_LEN];
+		
+	struct callout			sc_watchdog_ch;
+	struct mtx			sc_mtx;
+
+/* need to be power of 2, otherwise URTWN_CMDQ_GET fails */
+#define	URTWN_CMDQ_MAX	16
+#define	URTWN_CMDQ_MASQ	(URTWN_CMDQ_MAX - 1)
+	struct urtwn_cmdq		cmdq[URTWN_CMDQ_MAX];
+	struct task			cmdq_task;
+	uint32_t			cmdq_store;
+	uint8_t                         cmdq_exec;
+	uint8_t                         cmdq_run;
+	uint8_t                         cmdq_key_set;
+#define	URTWN_CMDQ_ABORT	0
+#define	URTWN_CMDQ_GO		1
+
+	uint32_t			rf_chnlbw[R92C_MAX_CHAINS];
+	struct usb_xfer			*sc_xfer[URTWN_N_TRANSFER];
+
+	struct urtwn_rx_radiotap_header	sc_rxtap;
+	int				sc_rxtap_len;
+
+	struct urtwn_tx_radiotap_header	sc_txtap;
+	int				sc_txtap_len;
+};
+
+#define	URTWN_LOCK(sc)			mtx_lock(&(sc)->sc_mtx)
+#define	URTWN_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
+#define	URTWN_ASSERT_LOCKED(sc)		mtx_assert(&(sc)->sc_mtx, MA_OWNED)
+
+/*
+ * MAC initialization values.
+ */
+static const struct {
+	uint16_t	reg;
+	uint8_t		val;
+} rtl8188eu_mac[] = {
+	{ 0x026, 0x41 }, { 0x027, 0x35 }, { 0x040, 0x00 }, { 0x428, 0x0a },
+	{ 0x429, 0x10 }, { 0x430, 0x00 }, { 0x431, 0x01 }, { 0x432, 0x02 },
+	{ 0x433, 0x04 }, { 0x434, 0x05 }, { 0x435, 0x06 }, { 0x436, 0x07 },
+	{ 0x437, 0x08 }, { 0x438, 0x00 }, { 0x439, 0x00 }, { 0x43a, 0x01 },
+	{ 0x43b, 0x02 }, { 0x43c, 0x04 }, { 0x43d, 0x05 }, { 0x43e, 0x06 },
+	{ 0x43f, 0x07 }, { 0x440, 0x5d }, { 0x441, 0x01 }, { 0x442, 0x00 },
+	{ 0x444, 0x15 }, { 0x445, 0xf0 }, { 0x446, 0x0f }, { 0x447, 0x00 },
+	{ 0x458, 0x41 }, { 0x459, 0xa8 }, { 0x45a, 0x72 }, { 0x45b, 0xb9 },
+	{ 0x460, 0x66 }, { 0x461, 0x66 }, { 0x480, 0x08 }, { 0x4c8, 0xff },
+	{ 0x4c9, 0x08 }, { 0x4cc, 0xff }, { 0x4cd, 0xff }, { 0x4ce, 0x01 },
+	{ 0x4d3, 0x01 }, { 0x500, 0x26 }, { 0x501, 0xa2 }, { 0x502, 0x2f },
+	{ 0x503, 0x00 }, { 0x504, 0x28 }, { 0x505, 0xa3 }, { 0x506, 0x5e },
+	{ 0x507, 0x00 }, { 0x508, 0x2b }, { 0x509, 0xa4 }, { 0x50a, 0x5e },
+	{ 0x50b, 0x00 }, { 0x50c, 0x4f }, { 0x50d, 0xa4 }, { 0x50e, 0x00 },
+	{ 0x50f, 0x00 }, { 0x512, 0x1c }, { 0x514, 0x0a }, { 0x516, 0x0a },
+	{ 0x525, 0x4f }, { 0x550, 0x10 }, { 0x551, 0x10 }, { 0x559, 0x02 },
+	{ 0x55d, 0xff }, { 0x605, 0x30 }, { 0x608, 0x0e }, { 0x609, 0x2a },
+	{ 0x620, 0xff }, { 0x621, 0xff }, { 0x622, 0xff }, { 0x623, 0xff },
+	{ 0x624, 0xff }, { 0x625, 0xff }, { 0x626, 0xff }, { 0x627, 0xff },
+	{ 0x652, 0x20 }, { 0x63c, 0x0a }, { 0x63d, 0x0a }, { 0x63e, 0x0e },
+	{ 0x63f, 0x0e }, { 0x640, 0x40 }, { 0x66e, 0x05 }, { 0x700, 0x21 },
+	{ 0x701, 0x43 }, { 0x702, 0x65 }, { 0x703, 0x87 }, { 0x708, 0x21 },
+	{ 0x709, 0x43 }, { 0x70a, 0x65 }, { 0x70b, 0x87 }
+}, rtl8192cu_mac[] = {
+	{ 0x420, 0x80 }, { 0x423, 0x00 }, { 0x430, 0x00 }, { 0x431, 0x00 },
+	{ 0x432, 0x00 }, { 0x433, 0x01 }, { 0x434, 0x04 }, { 0x435, 0x05 },
+	{ 0x436, 0x06 }, { 0x437, 0x07 }, { 0x438, 0x00 }, { 0x439, 0x00 },
+	{ 0x43a, 0x00 }, { 0x43b, 0x01 }, { 0x43c, 0x04 }, { 0x43d, 0x05 },
+	{ 0x43e, 0x06 }, { 0x43f, 0x07 }, { 0x440, 0x5d }, { 0x441, 0x01 },
+	{ 0x442, 0x00 }, { 0x444, 0x15 }, { 0x445, 0xf0 }, { 0x446, 0x0f },
+	{ 0x447, 0x00 }, { 0x458, 0x41 }, { 0x459, 0xa8 }, { 0x45a, 0x72 },
+	{ 0x45b, 0xb9 }, { 0x460, 0x66 }, { 0x461, 0x66 }, { 0x462, 0x08 },
+	{ 0x463, 0x03 }, { 0x4c8, 0xff }, { 0x4c9, 0x08 }, { 0x4cc, 0xff },
+	{ 0x4cd, 0xff }, { 0x4ce, 0x01 }, { 0x500, 0x26 }, { 0x501, 0xa2 },
+	{ 0x502, 0x2f }, { 0x503, 0x00 }, { 0x504, 0x28 }, { 0x505, 0xa3 },
+	{ 0x506, 0x5e }, { 0x507, 0x00 }, { 0x508, 0x2b }, { 0x509, 0xa4 },
+	{ 0x50a, 0x5e }, { 0x50b, 0x00 }, { 0x50c, 0x4f }, { 0x50d, 0xa4 },
+	{ 0x50e, 0x00 }, { 0x50f, 0x00 }, { 0x512, 0x1c }, { 0x514, 0x0a },
+	{ 0x515, 0x10 }, { 0x516, 0x0a }, { 0x517, 0x10 }, { 0x51a, 0x16 },
+	{ 0x524, 0x0f }, { 0x525, 0x4f }, { 0x546, 0x40 }, { 0x547, 0x00 },
+	{ 0x550, 0x10 }, { 0x551, 0x10 }, { 0x559, 0x02 }, { 0x55a, 0x02 },
+	{ 0x55d, 0xff }, { 0x605, 0x30 }, { 0x608, 0x0e }, { 0x609, 0x2a },
+	{ 0x652, 0x20 }, { 0x63c, 0x0a }, { 0x63d, 0x0e }, { 0x63e, 0x0a },
+	{ 0x63f, 0x0e }, { 0x66e, 0x05 }, { 0x700, 0x21 }, { 0x701, 0x43 },
+	{ 0x702, 0x65 }, { 0x703, 0x87 }, { 0x708, 0x21 }, { 0x709, 0x43 },
+	{ 0x70a, 0x65 }, { 0x70b, 0x87 }
+};
+
+/*
+ * Baseband initialization values.
+ */
+struct urtwn_bb_prog {
+	int		count;
+	const uint16_t	*regs;
+	const uint32_t	*vals;
+	int		agccount;
+	const uint32_t	*agcvals;
+};
+
+/*
+ * RTL8192CU and RTL8192CE-VAU.
+ */
+static const uint16_t rtl8192ce_bb_regs[] = {
+	0x024, 0x028, 0x800, 0x804, 0x808, 0x80c, 0x810, 0x814, 0x818,
+	0x81c, 0x820, 0x824, 0x828, 0x82c, 0x830, 0x834, 0x838, 0x83c,
+	0x840, 0x844, 0x848, 0x84c, 0x850, 0x854, 0x858, 0x85c, 0x860,
+	0x864, 0x868, 0x86c, 0x870, 0x874, 0x878, 0x87c, 0x880, 0x884,
+	0x888, 0x88c, 0x890, 0x894, 0x898, 0x89c, 0x900, 0x904, 0x908,
+	0x90c, 0xa00, 0xa04, 0xa08, 0xa0c, 0xa10, 0xa14, 0xa18, 0xa1c,
+	0xa20, 0xa24, 0xa28, 0xa2c, 0xa70, 0xa74, 0xc00, 0xc04, 0xc08,
+	0xc0c, 0xc10, 0xc14, 0xc18, 0xc1c, 0xc20, 0xc24, 0xc28, 0xc2c,
+	0xc30, 0xc34, 0xc38, 0xc3c, 0xc40, 0xc44, 0xc48, 0xc4c, 0xc50,
+	0xc54, 0xc58, 0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
+	0xc78, 0xc7c, 0xc80, 0xc84, 0xc88, 0xc8c, 0xc90, 0xc94, 0xc98,
+	0xc9c, 0xca0, 0xca4, 0xca8, 0xcac, 0xcb0, 0xcb4, 0xcb8, 0xcbc,
+	0xcc0, 0xcc4, 0xcc8, 0xccc, 0xcd0, 0xcd4, 0xcd8, 0xcdc, 0xce0,
+	0xce4, 0xce8, 0xcec, 0xd00, 0xd04, 0xd08, 0xd0c, 0xd10, 0xd14,
+	0xd18, 0xd2c, 0xd30, 0xd34, 0xd38, 0xd3c, 0xd40, 0xd44, 0xd48,
+	0xd4c, 0xd50, 0xd54, 0xd58, 0xd5c, 0xd60, 0xd64, 0xd68, 0xd6c,
+	0xd70, 0xd74, 0xd78, 0xe00, 0xe04, 0xe08, 0xe10, 0xe14, 0xe18,
+	0xe1c, 0xe28, 0xe30, 0xe34, 0xe38, 0xe3c, 0xe40, 0xe44, 0xe48,
+	0xe4c, 0xe50, 0xe54, 0xe58, 0xe5c, 0xe60, 0xe68, 0xe6c, 0xe70,
+	0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, 0xed0, 0xed4,
+	0xed8, 0xedc, 0xee0, 0xeec, 0xf14, 0xf4c, 0xf00
+};
+
+static const uint32_t rtl8192ce_bb_vals[] = {
+	0x0011800d, 0x00ffdb83, 0x80040002, 0x00000003, 0x0000fc00,
+	0x0000000a, 0x10005388, 0x020c3d10, 0x02200385, 0x00000000,
+	0x01000100, 0x00390004, 0x01000100, 0x00390004, 0x27272727,
+	0x27272727, 0x27272727, 0x27272727, 0x00010000, 0x00010000,
+	0x27272727, 0x27272727, 0x00000000, 0x00000000, 0x569a569a,
+	0x0c1b25a4, 0x66e60230, 0x061f0130, 0x27272727, 0x2b2b2b27,
+	0x07000700, 0x22184000, 0x08080808, 0x00000000, 0xc0083070,
+	0x000004d5, 0x00000000, 0xcc0000c0, 0x00000800, 0xfffffffe,
+	0x40302010, 0x00706050, 0x00000000, 0x00000023, 0x00000000,
+	0x81121313, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e68120f,
+	0x9500bb78, 0x11144028, 0x00881117, 0x89140f00, 0x1a1b0000,
+	0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
+	0x48071d40, 0x03a05633, 0x000000e4, 0x6c6c6c6c, 0x08800000,
+	0x40000100, 0x08800000, 0x40000100, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x69e9ac44, 0x469652cf, 0x49795994,
+	0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f,
+	0x6954341e, 0x43bc0094, 0x6954341e, 0x433c0094, 0x00000000,
+	0x5116848b, 0x47c00bff, 0x00000036, 0x2c7f000d, 0x018610db,
+	0x0000001f, 0x00b91612, 0x40000100, 0x20f60000, 0x40000100,
+	0x20200000, 0x00121820, 0x00000000, 0x00121820, 0x00007f7f,
+	0x00000000, 0x00000080, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x28000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x64b22427,
+	0x00766932, 0x00222222, 0x00000000, 0x37644302, 0x2f97d40c,
+	0x00080740, 0x00020403, 0x0000907f, 0x20010201, 0xa0633333,
+	0x3333bc43, 0x7a8f5b6b, 0xcc979975, 0x00000000, 0x80608000,
+	0x00000000, 0x00027293, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x6437140a, 0x00000000, 0x00000000, 0x30032064,
+	0x4653de68, 0x04518a3c, 0x00002101, 0x2a201c16, 0x1812362e,
+	0x322c2220, 0x000e3c24, 0x2a2a2a2a, 0x2a2a2a2a, 0x03902a2a,
+	0x2a2a2a2a, 0x2a2a2a2a, 0x2a2a2a2a, 0x2a2a2a2a, 0x00000000,
+	0x1000dc1f, 0x10008c1f, 0x02140102, 0x681604c2, 0x01007c00,
+	0x01004800, 0xfb000000, 0x000028d1, 0x1000dc1f, 0x10008c1f,
+	0x02140102, 0x28160d05, 0x00000010, 0x001b25a4, 0x63db25a4,
+	0x63db25a4, 0x0c1b25a4, 0x0c1b25a4, 0x0c1b25a4, 0x0c1b25a4,
+	0x63db25a4, 0x0c1b25a4, 0x63db25a4, 0x63db25a4, 0x63db25a4,
+	0x63db25a4, 0x001b25a4, 0x001b25a4, 0x6fdb25a4, 0x00000003,
+	0x00000000, 0x00000300
+};
+
+static const uint32_t rtl8192ce_agc_vals[] = {
+	0x7b000001, 0x7b010001, 0x7b020001, 0x7b030001, 0x7b040001,
+	0x7b050001, 0x7a060001, 0x79070001, 0x78080001, 0x77090001,
+	0x760a0001, 0x750b0001, 0x740c0001, 0x730d0001, 0x720e0001,
+	0x710f0001, 0x70100001, 0x6f110001, 0x6e120001, 0x6d130001,
+	0x6c140001, 0x6b150001, 0x6a160001, 0x69170001, 0x68180001,
+	0x67190001, 0x661a0001, 0x651b0001, 0x641c0001, 0x631d0001,
+	0x621e0001, 0x611f0001, 0x60200001, 0x49210001, 0x48220001,
+	0x47230001, 0x46240001, 0x45250001, 0x44260001, 0x43270001,
+	0x42280001, 0x41290001, 0x402a0001, 0x262b0001, 0x252c0001,
+	0x242d0001, 0x232e0001, 0x222f0001, 0x21300001, 0x20310001,
+	0x06320001, 0x05330001, 0x04340001, 0x03350001, 0x02360001,
+	0x01370001, 0x00380001, 0x00390001, 0x003a0001, 0x003b0001,
+	0x003c0001, 0x003d0001, 0x003e0001, 0x003f0001, 0x7b400001,
+	0x7b410001, 0x7b420001, 0x7b430001, 0x7b440001, 0x7b450001,
+	0x7a460001, 0x79470001, 0x78480001, 0x77490001, 0x764a0001,
+	0x754b0001, 0x744c0001, 0x734d0001, 0x724e0001, 0x714f0001,
+	0x70500001, 0x6f510001, 0x6e520001, 0x6d530001, 0x6c540001,
+	0x6b550001, 0x6a560001, 0x69570001, 0x68580001, 0x67590001,
+	0x665a0001, 0x655b0001, 0x645c0001, 0x635d0001, 0x625e0001,
+	0x615f0001, 0x60600001, 0x49610001, 0x48620001, 0x47630001,
+	0x46640001, 0x45650001, 0x44660001, 0x43670001, 0x42680001,
+	0x41690001, 0x406a0001, 0x266b0001, 0x256c0001, 0x246d0001,
+	0x236e0001, 0x226f0001, 0x21700001, 0x20710001, 0x06720001,
+	0x05730001, 0x04740001, 0x03750001, 0x02760001, 0x01770001,
+	0x00780001, 0x00790001, 0x007a0001, 0x007b0001, 0x007c0001,
+	0x007d0001, 0x007e0001, 0x007f0001, 0x3800001e, 0x3801001e,
+	0x3802001e, 0x3803001e, 0x3804001e, 0x3805001e, 0x3806001e,
+	0x3807001e, 0x3808001e, 0x3c09001e, 0x3e0a001e, 0x400b001e,
+	0x440c001e, 0x480d001e, 0x4c0e001e, 0x500f001e, 0x5210001e,
+	0x5611001e, 0x5a12001e, 0x5e13001e, 0x6014001e, 0x6015001e,
+	0x6016001e, 0x6217001e, 0x6218001e, 0x6219001e, 0x621a001e,
+	0x621b001e, 0x621c001e, 0x621d001e, 0x621e001e, 0x621f001e
+};
+
+static const struct urtwn_bb_prog rtl8192ce_bb_prog = {
+	nitems(rtl8192ce_bb_regs),
+	rtl8192ce_bb_regs,
+	rtl8192ce_bb_vals,
+	nitems(rtl8192ce_agc_vals),
+	rtl8192ce_agc_vals
+};
+
+/*
+ * RTL8188CU.
+ */
+static const uint32_t rtl8192cu_bb_vals[] = {
+	0x0011800d, 0x00ffdb83, 0x80040002, 0x00000003, 0x0000fc00,
+	0x0000000a, 0x10005388, 0x020c3d10, 0x02200385, 0x00000000,
+	0x01000100, 0x00390004, 0x01000100, 0x00390004, 0x27272727,
+	0x27272727, 0x27272727, 0x27272727, 0x00010000, 0x00010000,
+	0x27272727, 0x27272727, 0x00000000, 0x00000000, 0x569a569a,
+	0x0c1b25a4, 0x66e60230, 0x061f0130, 0x27272727, 0x2b2b2b27,
+	0x07000700, 0x22184000, 0x08080808, 0x00000000, 0xc0083070,
+	0x000004d5, 0x00000000, 0xcc0000c0, 0x00000800, 0xfffffffe,
+	0x40302010, 0x00706050, 0x00000000, 0x00000023, 0x00000000,
+	0x81121313, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e68120f,
+	0x9500bb78, 0x11144028, 0x00881117, 0x89140f00, 0x1a1b0000,
+	0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
+	0x48071d40, 0x03a05633, 0x000000e4, 0x6c6c6c6c, 0x08800000,
+	0x40000100, 0x08800000, 0x40000100, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x69e9ac44, 0x469652cf, 0x49795994,
+	0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f,
+	0x6954341e, 0x43bc0094, 0x6954341e, 0x433c0094, 0x00000000,
+	0x5116848b, 0x47c00bff, 0x00000036, 0x2c7f000d, 0x0186115b,
+	0x0000001f, 0x00b99612, 0x40000100, 0x20f60000, 0x40000100,
+	0x20200000, 0x00121820, 0x00000000, 0x00121820, 0x00007f7f,
+	0x00000000, 0x00000080, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x28000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x64b22427,
+	0x00766932, 0x00222222, 0x00000000, 0x37644302, 0x2f97d40c,
+	0x00080740, 0x00020403, 0x0000907f, 0x20010201, 0xa0633333,
+	0x3333bc43, 0x7a8f5b6b, 0xcc979975, 0x00000000, 0x80608000,
+	0x00000000, 0x00027293, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x6437140a, 0x00000000, 0x00000000, 0x30032064,
+	0x4653de68, 0x04518a3c, 0x00002101, 0x2a201c16, 0x1812362e,
+	0x322c2220, 0x000e3c24, 0x2a2a2a2a, 0x2a2a2a2a, 0x03902a2a,
+	0x2a2a2a2a, 0x2a2a2a2a, 0x2a2a2a2a, 0x2a2a2a2a, 0x00000000,
+	0x1000dc1f, 0x10008c1f, 0x02140102, 0x681604c2, 0x01007c00,
+	0x01004800, 0xfb000000, 0x000028d1, 0x1000dc1f, 0x10008c1f,
+	0x02140102, 0x28160d05, 0x00000010, 0x001b25a4, 0x63db25a4,
+	0x63db25a4, 0x0c1b25a4, 0x0c1b25a4, 0x0c1b25a4, 0x0c1b25a4,
+	0x63db25a4, 0x0c1b25a4, 0x63db25a4, 0x63db25a4, 0x63db25a4,
+	0x63db25a4, 0x001b25a4, 0x001b25a4, 0x6fdb25a4, 0x00000003,
+	0x00000000, 0x00000300
+};
+
+static const struct urtwn_bb_prog rtl8192cu_bb_prog = {
+	nitems(rtl8192ce_bb_regs),
+	rtl8192ce_bb_regs,
+	rtl8192cu_bb_vals,
+	nitems(rtl8192ce_agc_vals),
+	rtl8192ce_agc_vals
+};
+
+/*
+ * RTL8188CE-VAU.
+ */
+static const uint32_t rtl8188ce_bb_vals[] = {
+	0x0011800d, 0x00ffdb83, 0x80040000, 0x00000001, 0x0000fc00,
+	0x0000000a, 0x10005388, 0x020c3d10, 0x02200385, 0x00000000,
+	0x01000100, 0x00390004, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x569a569a,
+	0x001b25a4, 0x66e60230, 0x061f0130, 0x00000000, 0x32323200,
+	0x07000700, 0x22004000, 0x00000808, 0x00000000, 0xc0083070,
+	0x000004d5, 0x00000000, 0xccc000c0, 0x00000800, 0xfffffffe,
+	0x40302010, 0x00706050, 0x00000000, 0x00000023, 0x00000000,
+	0x81121111, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e68120f,
+	0x9500bb78, 0x11144028, 0x00881117, 0x89140f00, 0x1a1b0000,
+	0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
+	0x48071d40, 0x03a05611, 0x000000e4, 0x6c6c6c6c, 0x08800000,
+	0x40000100, 0x08800000, 0x40000100, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x69e9ac44, 0x469652cf, 0x49795994,
+	0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f,
+	0x6954341e, 0x43bc0094, 0x6954341e, 0x433c0094, 0x00000000,
+	0x5116848b, 0x47c00bff, 0x00000036, 0x2c7f000d, 0x018610db,
+	0x0000001f, 0x00b91612, 0x40000100, 0x20f60000, 0x40000100,
+	0x20200000, 0x00121820, 0x00000000, 0x00121820, 0x00007f7f,
+	0x00000000, 0x00000080, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x28000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x64b22427,
+	0x00766932, 0x00222222, 0x00000000, 0x37644302, 0x2f97d40c,
+	0x00080740, 0x00020401, 0x0000907f, 0x20010201, 0xa0633333,
+	0x3333bc43, 0x7a8f5b6b, 0xcc979975, 0x00000000, 0x80608000,
+	0x00000000, 0x00027293, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x6437140a, 0x00000000, 0x00000000, 0x30032064,
+	0x4653de68, 0x04518a3c, 0x00002101, 0x2a201c16, 0x1812362e,
+	0x322c2220, 0x000e3c24, 0x2a2a2a2a, 0x2a2a2a2a, 0x03902a2a,
+	0x2a2a2a2a, 0x2a2a2a2a, 0x2a2a2a2a, 0x2a2a2a2a, 0x00000000,
+	0x1000dc1f, 0x10008c1f, 0x02140102, 0x681604c2, 0x01007c00,
+	0x01004800, 0xfb000000, 0x000028d1, 0x1000dc1f, 0x10008c1f,
+	0x02140102, 0x28160d05, 0x00000008, 0x001b25a4, 0x631b25a0,
+	0x631b25a0, 0x081b25a0, 0x081b25a0, 0x081b25a0, 0x081b25a0,
+	0x631b25a0, 0x081b25a0, 0x631b25a0, 0x631b25a0, 0x631b25a0,
+	0x631b25a0, 0x001b25a0, 0x001b25a0, 0x6b1b25a0, 0x00000003,
+	0x00000000, 0x00000300
+};
+
+static const uint32_t rtl8188ce_agc_vals[] = {
+	0x7b000001, 0x7b010001, 0x7b020001, 0x7b030001, 0x7b040001,
+	0x7b050001, 0x7a060001, 0x79070001, 0x78080001, 0x77090001,
+	0x760a0001, 0x750b0001, 0x740c0001, 0x730d0001, 0x720e0001,
+	0x710f0001, 0x70100001, 0x6f110001, 0x6e120001, 0x6d130001,
+	0x6c140001, 0x6b150001, 0x6a160001, 0x69170001, 0x68180001,
+	0x67190001, 0x661a0001, 0x651b0001, 0x641c0001, 0x631d0001,
+	0x621e0001, 0x611f0001, 0x60200001, 0x49210001, 0x48220001,
+	0x47230001, 0x46240001, 0x45250001, 0x44260001, 0x43270001,
+	0x42280001, 0x41290001, 0x402a0001, 0x262b0001, 0x252c0001,
+	0x242d0001, 0x232e0001, 0x222f0001, 0x21300001, 0x20310001,
+	0x06320001, 0x05330001, 0x04340001, 0x03350001, 0x02360001,
+	0x01370001, 0x00380001, 0x00390001, 0x003a0001, 0x003b0001,
+	0x003c0001, 0x003d0001, 0x003e0001, 0x003f0001, 0x7b400001,
+	0x7b410001, 0x7b420001, 0x7b430001, 0x7b440001, 0x7b450001,
+	0x7a460001, 0x79470001, 0x78480001, 0x77490001, 0x764a0001,
+	0x754b0001, 0x744c0001, 0x734d0001, 0x724e0001, 0x714f0001,
+	0x70500001, 0x6f510001, 0x6e520001, 0x6d530001, 0x6c540001,
+	0x6b550001, 0x6a560001, 0x69570001, 0x68580001, 0x67590001,
+	0x665a0001, 0x655b0001, 0x645c0001, 0x635d0001, 0x625e0001,
+	0x615f0001, 0x60600001, 0x49610001, 0x48620001, 0x47630001,
+	0x46640001, 0x45650001, 0x44660001, 0x43670001, 0x42680001,
+	0x41690001, 0x406a0001, 0x266b0001, 0x256c0001, 0x246d0001,
+	0x236e0001, 0x226f0001, 0x21700001, 0x20710001, 0x06720001,
+	0x05730001, 0x04740001, 0x03750001, 0x02760001, 0x01770001,
+	0x00780001, 0x00790001, 0x007a0001, 0x007b0001, 0x007c0001,
+	0x007d0001, 0x007e0001, 0x007f0001, 0x3800001e, 0x3801001e,
+	0x3802001e, 0x3803001e, 0x3804001e, 0x3805001e, 0x3806001e,
+	0x3807001e, 0x3808001e, 0x3c09001e, 0x3e0a001e, 0x400b001e,
+	0x440c001e, 0x480d001e, 0x4c0e001e, 0x500f001e, 0x5210001e,
+	0x5611001e, 0x5a12001e, 0x5e13001e, 0x6014001e, 0x6015001e,
+	0x6016001e, 0x6217001e, 0x6218001e, 0x6219001e, 0x621a001e,
+	0x621b001e, 0x621c001e, 0x621d001e, 0x621e001e, 0x621f001e
+};
+
+static const struct urtwn_bb_prog rtl8188ce_bb_prog = {
+	nitems(rtl8192ce_bb_regs),
+	rtl8192ce_bb_regs,
+	rtl8188ce_bb_vals,
+	nitems(rtl8188ce_agc_vals),
+	rtl8188ce_agc_vals
+};
+
+static const uint32_t rtl8188cu_bb_vals[] = {
+	0x0011800d, 0x00ffdb83, 0x80040000, 0x00000001, 0x0000fc00,
+	0x0000000a, 0x10005388, 0x020c3d10, 0x02200385, 0x00000000,
+	0x01000100, 0x00390004, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x569a569a,
+	0x001b25a4, 0x66e60230, 0x061f0130, 0x00000000, 0x32323200,
+	0x07000700, 0x22004000, 0x00000808, 0x00000000, 0xc0083070,
+	0x000004d5, 0x00000000, 0xccc000c0, 0x00000800, 0xfffffffe,
+	0x40302010, 0x00706050, 0x00000000, 0x00000023, 0x00000000,
+	0x81121111, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e68120f,
+	0x9500bb78, 0x11144028, 0x00881117, 0x89140f00, 0x1a1b0000,
+	0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
+	0x48071d40, 0x03a05611, 0x000000e4, 0x6c6c6c6c, 0x08800000,
+	0x40000100, 0x08800000, 0x40000100, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x69e9ac44, 0x469652cf, 0x49795994,
+	0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f,
+	0x6954341e, 0x43bc0094, 0x6954341e, 0x433c0094, 0x00000000,
+	0x5116848b, 0x47c00bff, 0x00000036, 0x2c7f000d, 0x018610db,
+	0x0000001f, 0x00b91612, 0x40000100, 0x20f60000, 0x40000100,
+	0x20200000, 0x00121820, 0x00000000, 0x00121820, 0x00007f7f,
+	0x00000000, 0x00000080, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x28000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x64b22427,
+	0x00766932, 0x00222222, 0x00000000, 0x37644302, 0x2f97d40c,
+	0x00080740, 0x00020401, 0x0000907f, 0x20010201, 0xa0633333,
+	0x3333bc43, 0x7a8f5b6b, 0xcc979975, 0x00000000, 0x80608000,
+	0x00000000, 0x00027293, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x6437140a, 0x00000000, 0x00000000, 0x30032064,
+	0x4653de68, 0x04518a3c, 0x00002101, 0x2a201c16, 0x1812362e,
+	0x322c2220, 0x000e3c24, 0x2a2a2a2a, 0x2a2a2a2a, 0x03902a2a,
+	0x2a2a2a2a, 0x2a2a2a2a, 0x2a2a2a2a, 0x2a2a2a2a, 0x00000000,
+	0x1000dc1f, 0x10008c1f, 0x02140102, 0x681604c2, 0x01007c00,
+	0x01004800, 0xfb000000, 0x000028d1, 0x1000dc1f, 0x10008c1f,
+	0x02140102, 0x28160d05, 0x00000008, 0x001b25a4, 0x631b25a0,
+	0x631b25a0, 0x081b25a0, 0x081b25a0, 0x081b25a0, 0x081b25a0,
+	0x631b25a0, 0x081b25a0, 0x631b25a0, 0x631b25a0, 0x631b25a0,
+	0x631b25a0, 0x001b25a0, 0x001b25a0, 0x6b1b25a0, 0x00000003,
+	0x00000000, 0x00000300
+};
+
+static const struct urtwn_bb_prog rtl8188cu_bb_prog = {
+	nitems(rtl8192ce_bb_regs),
+	rtl8192ce_bb_regs,
+	rtl8188cu_bb_vals,
+	nitems(rtl8188ce_agc_vals),
+	rtl8188ce_agc_vals
+};
+
+/*
+ * RTL8188EU.
+ */
+static const uint16_t rtl8188eu_bb_regs[] = {
+	0x800, 0x804, 0x808, 0x80c, 0x810, 0x814, 0x818, 0x81c,
+	0x820, 0x824, 0x828, 0x82c, 0x830, 0x834, 0x838, 0x83c,
+	0x840, 0x844, 0x848, 0x84c, 0x850, 0x854, 0x858, 0x85c,
+	0x860, 0x864, 0x868, 0x86c, 0x870, 0x874, 0x878, 0x87c,
+	0x880, 0x884, 0x888, 0x88c, 0x890, 0x894, 0x898, 0x89c,
+	0x900, 0x904, 0x908, 0x90c, 0x910, 0x914, 0xa00, 0xa04,
+	0xa08, 0xa0c, 0xa10, 0xa14, 0xa18, 0xa1c, 0xa20, 0xa24,
+	0xa28, 0xa2c, 0xa70, 0xa74, 0xa78, 0xa7c, 0xa80, 0xb2c,
+	0xc00, 0xc04, 0xc08, 0xc0c, 0xc10, 0xc14, 0xc18, 0xc1c,
+	0xc20, 0xc24, 0xc28, 0xc2c, 0xc30, 0xc34, 0xc38, 0xc3c,
+	0xc40, 0xc44, 0xc48, 0xc4c, 0xc50, 0xc54, 0xc58, 0xc5c,
+	0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74, 0xc78, 0xc7c,
+	0xc80, 0xc84, 0xc88, 0xc8c, 0xc90, 0xc94, 0xc98, 0xc9c,
+	0xca0, 0xca4, 0xca8, 0xcac, 0xcb0, 0xcb4, 0xcb8, 0xcbc,
+	0xcc0, 0xcc4, 0xcc8, 0xccc, 0xcd0, 0xcd4, 0xcd8, 0xcdc,
+	0xce0, 0xce4, 0xce8, 0xcec, 0xd00, 0xd04, 0xd08, 0xd0c,
+	0xd10, 0xd14, 0xd18, 0xd2c, 0xd30, 0xd34, 0xd38, 0xd3c,
+	0xd40, 0xd44, 0xd48, 0xd4c, 0xd50, 0xd54, 0xd58, 0xd5c,
+	0xd60, 0xd64, 0xd68, 0xd6c, 0xd70, 0xd74, 0xd78, 0xe00,
+	0xe04, 0xe08, 0xe10, 0xe14, 0xe18, 0xe1c, 0xe28, 0xe30,
+	0xe34, 0xe38, 0xe3c, 0xe40, 0xe44, 0xe48, 0xe4c, 0xe50,
+	0xe54, 0xe58, 0xe5c, 0xe60, 0xe68, 0xe6c, 0xe70, 0xe74,
+	0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, 0xed0, 0xed4,
+	0xed8, 0xedc, 0xee0, 0xee8, 0xeec, 0xf14, 0xf4c, 0xf00
+};
+
+static const uint32_t rtl8188eu_bb_vals[] = {
+	0x80040000, 0x00000003, 0x0000fc00, 0x0000000a, 0x10001331,
+	0x020c3d10, 0x02200385, 0x00000000, 0x01000100, 0x00390204,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x569a11a9, 0x01000014, 0x66f60110,
+	0x061f0649, 0x00000000, 0x27272700, 0x07000760, 0x25004000,
+	0x00000808, 0x00000000, 0xb0000c1c, 0x00000001, 0x00000000,
+	0xccc000c0, 0x00000800, 0xfffffffe, 0x40302010, 0x00706050,
+	0x00000000, 0x00000023, 0x00000000, 0x81121111, 0x00000002,
+	0x00000201, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e7f120f,
+	0x9500bb78, 0x1114d028, 0x00881117, 0x89140f00, 0x1a1b0000,
+	0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
+	0x00000900, 0x225b0606, 0x218075b1, 0x80000000, 0x48071d40,
+	0x03a05611, 0x000000e4, 0x6c6c6c6c, 0x08800000, 0x40000100,
+	0x08800000, 0x40000100, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x69e9ac47, 0x469652af, 0x49795994, 0x0a97971c,
+	0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f, 0x69553420,
+	0x43bc0094, 0x00013169, 0x00250492, 0x00000000, 0x7112848b,
+	0x47c00bff, 0x00000036, 0x2c7f000d, 0x020610db, 0x0000001f,
+	0x00b91612, 0x390000e4, 0x20f60000, 0x40000100, 0x20200000,
+	0x00091521, 0x00000000, 0x00121820, 0x00007f7f, 0x00000000,
+	0x000300a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x28000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x64b22427, 0x00766932,
+	0x00222222, 0x00000000, 0x37644302, 0x2f97d40c, 0x00000740,
+	0x00020401, 0x0000907f, 0x20010201, 0xa0633333, 0x3333bc43,
+	0x7a8f5b6f, 0xcc979975, 0x00000000, 0x80608000, 0x00000000,
+	0x00127353, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x6437140a, 0x00000000, 0x00000282, 0x30032064, 0x4653de68,
+	0x04518a3c, 0x00002101, 0x2a201c16, 0x1812362e, 0x322c2220,
+	0x000e3c24, 0x2d2d2d2d, 0x2d2d2d2d, 0x0390272d, 0x2d2d2d2d,
+	0x2d2d2d2d, 0x2d2d2d2d, 0x2d2d2d2d, 0x00000000, 0x1000dc1f,
+	0x10008c1f, 0x02140102, 0x681604c2, 0x01007c00, 0x01004800,
+	0xfb000000, 0x000028d1, 0x1000dc1f, 0x10008c1f, 0x02140102,
+	0x28160d05, 0x00000008, 0x001b25a4, 0x00c00014, 0x00c00014,
+	0x01000014, 0x01000014, 0x01000014, 0x01000014, 0x00c00014,
+	0x01000014, 0x00c00014, 0x00c00014, 0x00c00014, 0x00c00014,
+	0x00000014, 0x00000014, 0x21555448, 0x01c00014, 0x00000003,
+	0x00000000, 0x00000300
+};
+
+static const uint32_t rtl8188eu_agc_vals[] = {
+	0xfb000001, 0xfb010001, 0xfb020001, 0xfb030001, 0xfb040001,
+	0xfb050001, 0xfa060001, 0xf9070001, 0xf8080001, 0xf7090001,
+	0xf60a0001, 0xf50b0001, 0xf40c0001, 0xf30d0001, 0xf20e0001,
+	0xf10f0001, 0xf0100001, 0xef110001, 0xee120001, 0xed130001,
+	0xec140001, 0xeb150001, 0xea160001, 0xe9170001, 0xe8180001,
+	0xe7190001, 0xe61a0001, 0xe51b0001, 0xe41c0001, 0xe31d0001,
+	0xe21e0001, 0xe11f0001, 0x8a200001, 0x89210001, 0x88220001,
+	0x87230001, 0x86240001, 0x85250001, 0x84260001, 0x83270001,
+	0x82280001, 0x6b290001, 0x6a2a0001, 0x692b0001, 0x682c0001,
+	0x672d0001, 0x662e0001, 0x652f0001, 0x64300001, 0x63310001,
+	0x62320001, 0x61330001, 0x46340001, 0x45350001, 0x44360001,
+	0x43370001, 0x42380001, 0x41390001, 0x403a0001, 0x403b0001,
+	0x403c0001, 0x403d0001, 0x403e0001, 0x403f0001, 0xfb400001,
+	0xfb410001, 0xfb420001, 0xfb430001, 0xfb440001, 0xfb450001,
+	0xfb460001, 0xfb470001, 0xfb480001, 0xfa490001, 0xf94a0001,
+	0xf84B0001, 0xf74c0001, 0xf64d0001, 0xf54e0001, 0xf44f0001,
+	0xf3500001, 0xf2510001, 0xf1520001, 0xf0530001, 0xef540001,
+	0xee550001, 0xed560001, 0xec570001, 0xeb580001, 0xea590001,
+	0xe95a0001, 0xe85b0001, 0xe75c0001, 0xe65d0001, 0xe55e0001,
+	0xe45f0001, 0xe3600001, 0xe2610001, 0xc3620001, 0xc2630001,
+	0xc1640001, 0x8b650001, 0x8a660001, 0x89670001, 0x88680001,
+	0x87690001, 0x866a0001, 0x856b0001, 0x846c0001, 0x676d0001,
+	0x666e0001, 0x656f0001, 0x64700001, 0x63710001, 0x62720001,
+	0x61730001, 0x60740001, 0x46750001, 0x45760001, 0x44770001,
+	0x43780001, 0x42790001, 0x417a0001, 0x407b0001, 0x407c0001,
+	0x407d0001, 0x407e0001, 0x407f0001
+};
+
+static const struct urtwn_bb_prog rtl8188eu_bb_prog = {
+	nitems(rtl8188eu_bb_regs),
+	rtl8188eu_bb_regs,
+	rtl8188eu_bb_vals,
+	nitems(rtl8188eu_agc_vals),
+	rtl8188eu_agc_vals
+};
+
+/*
+ * RTL8188RU.
+ */
+static const uint16_t rtl8188ru_bb_regs[] = {
+	0x024, 0x028, 0x040, 0x800, 0x804, 0x808, 0x80c, 0x810, 0x814,
+	0x818, 0x81c, 0x820, 0x824, 0x828, 0x82c, 0x830, 0x834, 0x838,
+	0x83c, 0x840, 0x844, 0x848, 0x84c, 0x850, 0x854, 0x858, 0x85c,
+	0x860, 0x864, 0x868, 0x86c, 0x870, 0x874, 0x878, 0x87c, 0x880,
+	0x884, 0x888, 0x88c, 0x890, 0x894, 0x898, 0x89c, 0x900, 0x904,
+	0x908, 0x90c, 0xa00, 0xa04, 0xa08, 0xa0c, 0xa10, 0xa14, 0xa18,
+	0xa1c, 0xa20, 0xa24, 0xa28, 0xa2c, 0xa70, 0xa74, 0xc00, 0xc04,
+	0xc08, 0xc0c, 0xc10, 0xc14, 0xc18, 0xc1c, 0xc20, 0xc24, 0xc28,
+	0xc2c, 0xc30, 0xc34, 0xc38, 0xc3c, 0xc40, 0xc44, 0xc48, 0xc4c,
+	0xc50, 0xc54, 0xc58, 0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70,
+	0xc74, 0xc78, 0xc7c, 0xc80, 0xc84, 0xc88, 0xc8c, 0xc90, 0xc94,
+	0xc98, 0xc9c, 0xca0, 0xca4, 0xca8, 0xcac, 0xcb0, 0xcb4, 0xcb8,
+	0xcbc, 0xcc0, 0xcc4, 0xcc8, 0xccc, 0xcd0, 0xcd4, 0xcd8, 0xcdc,
+	0xce0, 0xce4, 0xce8, 0xcec, 0xd00, 0xd04, 0xd08, 0xd0c, 0xd10,
+	0xd14, 0xd18, 0xd2c, 0xd30, 0xd34, 0xd38, 0xd3c, 0xd40, 0xd44,
+	0xd48, 0xd4c, 0xd50, 0xd54, 0xd58, 0xd5c, 0xd60, 0xd64, 0xd68,
+	0xd6c, 0xd70, 0xd74, 0xd78, 0xe00, 0xe04, 0xe08, 0xe10, 0xe14,
+	0xe18, 0xe1c, 0xe28, 0xe30, 0xe34, 0xe38, 0xe3c, 0xe40, 0xe44,
+	0xe48, 0xe4c, 0xe50, 0xe54, 0xe58, 0xe5c, 0xe60, 0xe68, 0xe6c,
+	0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, 0xed0,
+	0xed4, 0xed8, 0xedc, 0xee0, 0xeec, 0xee8, 0xf14, 0xf4c, 0xf00
+};
+
+static const uint32_t rtl8188ru_bb_vals[] = {
+	0x0011800d, 0x00ffdb83, 0x000c0004, 0x80040000, 0x00000001,
+	0x0000fc00, 0x0000000a, 0x10005388, 0x020c3d10, 0x02200385,
+	0x00000000, 0x01000100, 0x00390204, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x569a569a, 0x001b25a4, 0x66e60230, 0x061f0130, 0x00000000,
+	0x32323200, 0x03000300, 0x22004000, 0x00000808, 0x00ffc3f1,
+	0xc0083070, 0x000004d5, 0x00000000, 0xccc000c0, 0x00000800,
+	0xfffffffe, 0x40302010, 0x00706050, 0x00000000, 0x00000023,
+	0x00000000, 0x81121111, 0x00d047c8, 0x80ff000c, 0x8c838300,
+	0x2e68120f, 0x9500bb78, 0x11144028, 0x00881117, 0x89140f00,
+	0x15160000, 0x070b0f12, 0x00000104, 0x00d30000, 0x101fbf00,
+	0x00000007, 0x48071d40, 0x03a05611, 0x000000e4, 0x6c6c6c6c,
+	0x08800000, 0x40000100, 0x08800000, 0x40000100, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x69e9ac44, 0x469652cf,
+	0x49795994, 0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107,
+	0x007f037f, 0x6954342e, 0x43bc0094, 0x6954342f, 0x433c0094,
+	0x00000000, 0x5116848b, 0x47c00bff, 0x00000036, 0x2c56000d,
+	0x018610db, 0x0000001f, 0x00b91612, 0x24000090, 0x20f60000,
+	0x24000090, 0x20200000, 0x00121820, 0x00000000, 0x00121820,
+	0x00007f7f, 0x00000000, 0x00000080, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x28000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x64b22427, 0x00766932, 0x00222222, 0x00000000, 0x37644302,
+	0x2f97d40c, 0x00080740, 0x00020401, 0x0000907f, 0x20010201,
+	0xa0633333, 0x3333bc43, 0x7a8f5b6b, 0xcc979975, 0x00000000,
+	0x80608000, 0x00000000, 0x00027293, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x6437140a, 0x00000000, 0x00000000,
+	0x30032064, 0x4653de68, 0x04518a3c, 0x00002101, 0x2a201c16,
+	0x1812362e, 0x322c2220, 0x000e3c24, 0x2a2a2a2a, 0x2a2a2a2a,
+	0x03902a2a, 0x2a2a2a2a, 0x2a2a2a2a, 0x2a2a2a2a, 0x2a2a2a2a,
+	0x00000000, 0x1000dc1f, 0x10008c1f, 0x02140102, 0x681604c2,
+	0x01007c00, 0x01004800, 0xfb000000, 0x000028d1, 0x1000dc1f,
+	0x10008c1f, 0x02140102, 0x28160d05, 0x00000010, 0x001b25a4,
+	0x631b25a0, 0x631b25a0, 0x081b25a0, 0x081b25a0, 0x081b25a0,
+	0x081b25a0, 0x631b25a0, 0x081b25a0, 0x631b25a0, 0x631b25a0,
+	0x631b25a0, 0x631b25a0, 0x001b25a0, 0x001b25a0, 0x6b1b25a0,
+	0x31555448, 0x00000003, 0x00000000, 0x00000300
+};
+
+static const uint32_t rtl8188ru_agc_vals[] = {
+	0x7b000001, 0x7b010001, 0x7b020001, 0x7b030001, 0x7b040001,
+	0x7b050001, 0x7b060001, 0x7b070001, 0x7b080001, 0x7a090001,
+	0x790a0001, 0x780b0001, 0x770c0001, 0x760d0001, 0x750e0001,
+	0x740f0001, 0x73100001, 0x72110001, 0x71120001, 0x70130001,
+	0x6f140001, 0x6e150001, 0x6d160001, 0x6c170001, 0x6b180001,
+	0x6a190001, 0x691a0001, 0x681b0001, 0x671c0001, 0x661d0001,
+	0x651e0001, 0x641f0001, 0x63200001, 0x62210001, 0x61220001,
+	0x60230001, 0x46240001, 0x45250001, 0x44260001, 0x43270001,
+	0x42280001, 0x41290001, 0x402a0001, 0x262b0001, 0x252c0001,
+	0x242d0001, 0x232e0001, 0x222f0001, 0x21300001, 0x20310001,
+	0x06320001, 0x05330001, 0x04340001, 0x03350001, 0x02360001,
+	0x01370001, 0x00380001, 0x00390001, 0x003a0001, 0x003b0001,
+	0x003c0001, 0x003d0001, 0x003e0001, 0x003f0001, 0x7b400001,
+	0x7b410001, 0x7b420001, 0x7b430001, 0x7b440001, 0x7b450001,
+	0x7b460001, 0x7b470001, 0x7b480001, 0x7a490001, 0x794a0001,
+	0x784b0001, 0x774c0001, 0x764d0001, 0x754e0001, 0x744f0001,
+	0x73500001, 0x72510001, 0x71520001, 0x70530001, 0x6f540001,
+	0x6e550001, 0x6d560001, 0x6c570001, 0x6b580001, 0x6a590001,
+	0x695a0001, 0x685b0001, 0x675c0001, 0x665d0001, 0x655e0001,
+	0x645f0001, 0x63600001, 0x62610001, 0x61620001, 0x60630001,
+	0x46640001, 0x45650001, 0x44660001, 0x43670001, 0x42680001,
+	0x41690001, 0x406a0001, 0x266b0001, 0x256c0001, 0x246d0001,
+	0x236e0001, 0x226f0001, 0x21700001, 0x20710001, 0x06720001,
+	0x05730001, 0x04740001, 0x03750001, 0x02760001, 0x01770001,
+	0x00780001, 0x00790001, 0x007a0001, 0x007b0001, 0x007c0001,
+	0x007d0001, 0x007e0001, 0x007f0001, 0x3800001e, 0x3801001e,
+	0x3802001e, 0x3803001e, 0x3804001e, 0x3805001e, 0x3806001e,
+	0x3807001e, 0x3808001e, 0x3c09001e, 0x3e0a001e, 0x400b001e,
+	0x440c001e, 0x480d001e, 0x4c0e001e, 0x500f001e, 0x5210001e,
+	0x5611001e, 0x5a12001e, 0x5e13001e, 0x6014001e, 0x6015001e,
+	0x6016001e, 0x6217001e, 0x6218001e, 0x6219001e, 0x621a001e,
+	0x621b001e, 0x621c001e, 0x621d001e, 0x621e001e, 0x621f001e
+};
+
+static const struct urtwn_bb_prog rtl8188ru_bb_prog = {
+	nitems(rtl8188ru_bb_regs),
+	rtl8188ru_bb_regs,
+	rtl8188ru_bb_vals,
+	nitems(rtl8188ru_agc_vals),
+	rtl8188ru_agc_vals
+};
+
+/*
+ * RF initialization values.
+ */
+struct urtwn_rf_prog {
+	int		count;
+	const uint8_t	*regs;
+	const uint32_t	*vals;
+};
+
+/*
+ * RTL8192CU and RTL8192CE-VAU.
+ */
+static const uint8_t rtl8192ce_rf1_regs[] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+	0x0f, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
+	0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2a, 0x2b,
+	0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b,
+	0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b,
+	0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a,
+	0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c,
+	0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b,
+	0x2c, 0x2a, 0x10, 0x11, 0x10, 0x11, 0x10, 0x11, 0x10, 0x11, 0x10,
+	0x11, 0x10, 0x11, 0x10, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13,
+	0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14,
+	0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x00,
+	0x18, 0xfe, 0xfe, 0x1f, 0xfe, 0xfe, 0x1e, 0x1f, 0x00
+};
+
+static const uint32_t rtl8192ce_rf1_vals[] = {
+	0x30159, 0x31284, 0x98000, 0x18c63, 0x210e7, 0x2044f, 0x1adb1,
+	0x54867, 0x8992e, 0x0e52c, 0x39ce7, 0x00451, 0x00000, 0x10255,
+	0x60a00, 0xfc378, 0xa1250, 0x4445f, 0x80001, 0x0b614, 0x6c000,
+	0x00000, 0x01558, 0x00060, 0x00483, 0x4f000, 0xec7d9, 0x577c0,
+	0x04783, 0x00001, 0x21334, 0x00000, 0x00054, 0x00001, 0x00808,
+	0x53333, 0x0000c, 0x00002, 0x00808, 0x5b333, 0x0000d, 0x00003,
+	0x00808, 0x63333, 0x0000d, 0x00004, 0x00808, 0x6b333, 0x0000d,
+	0x00005, 0x00808, 0x73333, 0x0000d, 0x00006, 0x00709, 0x5b333,
+	0x0000d, 0x00007, 0x00709, 0x63333, 0x0000d, 0x00008, 0x0060a,
+	0x4b333, 0x0000d, 0x00009, 0x0060a, 0x53333, 0x0000d, 0x0000a,
+	0x0060a, 0x5b333, 0x0000d, 0x0000b, 0x0060a, 0x63333, 0x0000d,
+	0x0000c, 0x0060a, 0x6b333, 0x0000d, 0x0000d, 0x0060a, 0x73333,
+	0x0000d, 0x0000e, 0x0050b, 0x66666, 0x0001a, 0xe0000, 0x4000f,
+	0xe31fc, 0x6000f, 0xff9f8, 0x2000f, 0x203f9, 0x3000f, 0xff500,
+	0x00000, 0x00000, 0x8000f, 0x3f100, 0x9000f, 0x23100, 0x32000,
+	0x71000, 0xb0000, 0xfc000, 0x287af, 0x244b7, 0x204ab, 0x1c49f,
+	0x18493, 0x14297, 0x10295, 0x0c298, 0x0819c, 0x040a8, 0x0001c,
+	0x1944c, 0x59444, 0x9944c, 0xd9444, 0x0f424, 0x4f424, 0x8f424,
+	0xcf424, 0xe0330, 0xa0330, 0x60330, 0x20330, 0x10159, 0x0f401,
+	0x00000, 0x00000, 0x80003, 0x00000, 0x00000, 0x44457, 0x80000,
+	0x30159
+};
+
+static const uint8_t rtl8192ce_rf2_regs[] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+	0x0f, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+	0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15,
+	0x15, 0x15, 0x16, 0x16, 0x16, 0x16
+};
+
+static const uint32_t rtl8192ce_rf2_vals[] = {
+	0x30159, 0x31284, 0x98000, 0x18c63, 0x210e7, 0x2044f, 0x1adb1,
+	0x54867, 0x8992e, 0x0e52c, 0x39ce7, 0x00451, 0x32000, 0x71000,
+	0xb0000, 0xfc000, 0x287af, 0x244b7, 0x204ab, 0x1c49f, 0x18493,
+	0x14297, 0x10295, 0x0c298, 0x0819c, 0x040a8, 0x0001c, 0x1944c,
+	0x59444, 0x9944c, 0xd9444, 0x0f424, 0x4f424, 0x8f424, 0xcf424,
+	0xe0330, 0xa0330, 0x60330, 0x20330
+};
+
+static const struct urtwn_rf_prog rtl8192ce_rf_prog[] = {
+	{
+		nitems(rtl8192ce_rf1_regs),
+		rtl8192ce_rf1_regs,
+		rtl8192ce_rf1_vals
+	},
+	{
+		nitems(rtl8192ce_rf2_regs),
+		rtl8192ce_rf2_regs,
+		rtl8192ce_rf2_vals
+	}
+};
+
+/*
+ * RTL8188CE-VAU.
+ */
+static const uint32_t rtl8188ce_rf_vals[] = {
+	0x30159, 0x31284, 0x98000, 0x18c63, 0x210e7, 0x2044f, 0x1adb1,
+	0x54867, 0x8992e, 0x0e52c, 0x39ce7, 0x00451, 0x00000, 0x10255,
+	0x60a00, 0xfc378, 0xa1250, 0x4445f, 0x80001, 0x0b614, 0x6c000,
+	0x00000, 0x01558, 0x00060, 0x00483, 0x4f200, 0xec7d9, 0x577c0,
+	0x04783, 0x00001, 0x21334, 0x00000, 0x00054, 0x00001, 0x00808,
+	0x53333, 0x0000c, 0x00002, 0x00808, 0x5b333, 0x0000d, 0x00003,
+	0x00808, 0x63333, 0x0000d, 0x00004, 0x00808, 0x6b333, 0x0000d,
+	0x00005, 0x00808, 0x73333, 0x0000d, 0x00006, 0x00709, 0x5b333,
+	0x0000d, 0x00007, 0x00709, 0x63333, 0x0000d, 0x00008, 0x0060a,
+	0x4b333, 0x0000d, 0x00009, 0x0060a, 0x53333, 0x0000d, 0x0000a,
+	0x0060a, 0x5b333, 0x0000d, 0x0000b, 0x0060a, 0x63333, 0x0000d,
+	0x0000c, 0x0060a, 0x6b333, 0x0000d, 0x0000d, 0x0060a, 0x73333,
+	0x0000d, 0x0000e, 0x0050b, 0x66666, 0x0001a, 0xe0000, 0x4000f,
+	0xe31fc, 0x6000f, 0xff9f8, 0x2000f, 0x203f9, 0x3000f, 0xff500,
+	0x00000, 0x00000, 0x8000f, 0x3f100, 0x9000f, 0x23100, 0x32000,
+	0x71000, 0xb0000, 0xfc000, 0x287b3, 0x244b7, 0x204ab, 0x1c49f,
+	0x18493, 0x1429b, 0x10299, 0x0c29c, 0x081a0, 0x040ac, 0x00020,
+	0x1944c, 0x59444, 0x9944c, 0xd9444, 0x0f424, 0x4f424, 0x8f424,
+	0xcf424, 0xe0330, 0xa0330, 0x60330, 0x20330, 0x10159, 0x0f401,
+	0x00000, 0x00000, 0x80003, 0x00000, 0x00000, 0x44457, 0x80000,
+	0x30159
+};
+
+static const struct urtwn_rf_prog rtl8188ce_rf_prog[] = {
+	{
+		nitems(rtl8192ce_rf1_regs),
+		rtl8192ce_rf1_regs,
+		rtl8188ce_rf_vals
+	}
+};
+
+
+/*
+ * RTL8188CU.
+ */
+static const uint32_t rtl8188cu_rf_vals[] = {
+	0x30159, 0x31284, 0x98000, 0x18c63, 0x210e7, 0x2044f, 0x1adb1,
+	0x54867, 0x8992e, 0x0e52c, 0x39ce7, 0x00451, 0x00000, 0x10255,
+	0x60a00, 0xfc378, 0xa1250, 0x4445f, 0x80001, 0x0b614, 0x6c000,
+	0x00000, 0x01558, 0x00060, 0x00483, 0x4f000, 0xec7d9, 0x577c0,
+	0x04783, 0x00001, 0x21334, 0x00000, 0x00054, 0x00001, 0x00808,
+	0x53333, 0x0000c, 0x00002, 0x00808, 0x5b333, 0x0000d, 0x00003,
+	0x00808, 0x63333, 0x0000d, 0x00004, 0x00808, 0x6b333, 0x0000d,
+	0x00005, 0x00808, 0x73333, 0x0000d, 0x00006, 0x00709, 0x5b333,
+	0x0000d, 0x00007, 0x00709, 0x63333, 0x0000d, 0x00008, 0x0060a,
+	0x4b333, 0x0000d, 0x00009, 0x0060a, 0x53333, 0x0000d, 0x0000a,
+	0x0060a, 0x5b333, 0x0000d, 0x0000b, 0x0060a, 0x63333, 0x0000d,
+	0x0000c, 0x0060a, 0x6b333, 0x0000d, 0x0000d, 0x0060a, 0x73333,
+	0x0000d, 0x0000e, 0x0050b, 0x66666, 0x0001a, 0xe0000, 0x4000f,
+	0xe31fc, 0x6000f, 0xff9f8, 0x2000f, 0x203f9, 0x3000f, 0xff500,
+	0x00000, 0x00000, 0x8000f, 0x3f100, 0x9000f, 0x23100, 0x32000,
+	0x71000, 0xb0000, 0xfc000, 0x287b3, 0x244b7, 0x204ab, 0x1c49f,
+	0x18493, 0x1429b, 0x10299, 0x0c29c, 0x081a0, 0x040ac, 0x00020,
+	0x1944c, 0x59444, 0x9944c, 0xd9444, 0x0f405, 0x4f405, 0x8f405,
+	0xcf405, 0xe0330, 0xa0330, 0x60330, 0x20330, 0x10159, 0x0f401,
+	0x00000, 0x00000, 0x80003, 0x00000, 0x00000, 0x44457, 0x80000,
+	0x30159
+};
+
+static const struct urtwn_rf_prog rtl8188cu_rf_prog[] = {
+	{
+		nitems(rtl8192ce_rf1_regs),
+		rtl8192ce_rf1_regs,
+		rtl8188cu_rf_vals
+	}
+};
+
+/*
+ * RTL8188EU.
+ */
+static const uint8_t rtl8188eu_rf_regs[] = {
+	0x00, 0x08, 0x18, 0x19, 0x1e, 0x1f, 0x2f, 0x3f, 0x42, 0x57,
+	0x58, 0x67, 0x83, 0xb0, 0xb1, 0xb2, 0xb4, 0xb6, 0xb7, 0xb8,
+	0xb9, 0xba, 0xbb, 0xbf, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+	0xc8, 0xc9, 0xca, 0xdf, 0xef, 0x51, 0x52, 0x53, 0x56,
+	0x35, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0xb6, 0x18, 0x5a,
+	0x19, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
+	0x34, 0x34, 0x00, 0x84, 0x86, 0x87, 0x8e, 0x8f, 0xef, 0x3b,
+	0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+	0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xef, 0x00, 0x18, 0xfe, 0xfe,
+	0x1f, 0xfe, 0xfe, 0x1e, 0x1f, 0x00
+};
+
+static const uint32_t rtl8188eu_rf_vals[] = {
+	0x30000, 0x84000, 0x00407, 0x00012, 0x80009, 0x00880, 0x1a060,
+	0x00000, 0x060c0, 0xd0000, 0xbe180, 0x01552, 0x00000, 0xff8fc,
+	0x54400, 0xccc19, 0x43003, 0x4953e, 0x1c718, 0x060ff, 0x80001,
+	0x40000, 0x00400, 0xc0000, 0x02400, 0x00009, 0x40c91, 0x99999,
+	0x000a3, 0x88820, 0x76c06, 0x00000, 0x80000, 0x00180, 0x001a0,
+	0x6b27d, 0x7e49d, 0x00073, 0x51ff3, 0x00086, 0x00186,
+	0x00286, 0x01c25, 0x09c25, 0x11c25, 0x19c25, 0x48538, 0x00c07,
+	0x4bd00, 0x739d0, 0x0adf3, 0x09df0, 0x08ded, 0x07dea, 0x06de7,
+	0x054ee, 0x044eb, 0x034e8, 0x0246b, 0x01468, 0x0006d, 0x30159,
+	0x68200, 0x000ce, 0x48a00, 0x65540, 0x88000, 0x020a0, 0xf02b0,
+	0xef7b0, 0xd4fb0, 0xcf060, 0xb0090, 0xa0080, 0x90080, 0x8f780,
+	0x722b0, 0x6f7b0, 0x54fb0, 0x4f060, 0x30090, 0x20080, 0x10080,
+	0x0f780, 0x000a0, 0x10159, 0x0f407, 0x00000, 0x00000, 0x80003,
+	0x00000, 0x00000, 0x00001, 0x80000, 0x33e60
+};
+
+static const struct urtwn_rf_prog rtl8188eu_rf_prog[] = {
+	{
+		nitems(rtl8188eu_rf_regs),
+		rtl8188eu_rf_regs,
+		rtl8188eu_rf_vals
+	}
+};
+
+/*
+ * RTL8188RU.
+ */
+static const uint32_t rtl8188ru_rf_vals[] = {
+	0x30159, 0x31284, 0x98000, 0x18c63, 0x210e7, 0x2044f, 0x1adb0,
+	0x54867, 0x8992e, 0x0e529, 0x39ce7, 0x00451, 0x00000, 0x00255,
+	0x60a00, 0xfc378, 0xa1250, 0x4445f, 0x80001, 0x0b614, 0x6c000,
+	0x0083c, 0x01558, 0x00060, 0x00483, 0x4f000, 0xec7d9, 0x977c0,
+	0x04783, 0x00001, 0x21334, 0x00000, 0x00054, 0x00001, 0x00808,
+	0x53333, 0x0000c, 0x00002, 0x00808, 0x5b333, 0x0000d, 0x00003,
+	0x00808, 0x63333, 0x0000d, 0x00004, 0x00808, 0x6b333, 0x0000d,
+	0x00005, 0x00808, 0x73333, 0x0000d, 0x00006, 0x00709, 0x5b333,
+	0x0000d, 0x00007, 0x00709, 0x63333, 0x0000d, 0x00008, 0x0060a,
+	0x4b333, 0x0000d, 0x00009, 0x0060a, 0x53333, 0x0000d, 0x0000a,
+	0x0060a, 0x5b333, 0x0000d, 0x0000b, 0x0060a, 0x63333, 0x0000d,
+	0x0000c, 0x0060a, 0x6b333, 0x0000d, 0x0000d, 0x0060a, 0x73333,
+	0x0000d, 0x0000e, 0x0050b, 0x66666, 0x0001a, 0xe0000, 0x4000f,
+	0xe31fc, 0x6000f, 0xff9f8, 0x2000f, 0x203f9, 0x3000f, 0xff500,
+	0x00000, 0x00000, 0x8000f, 0x3f100, 0x9000f, 0x23100, 0xd8000,
+	0x90000, 0x51000, 0x12000, 0x28fb4, 0x24fa8, 0x207a4, 0x1c798,
+	0x183a4, 0x14398, 0x101a4, 0x0c198, 0x080a4, 0x04098, 0x00014,
+	0x1944c, 0x59444, 0x9944c, 0xd9444, 0x0f405, 0x4f405, 0x8f405,
+	0xcf405, 0xe0330, 0xa0330, 0x60330, 0x20330, 0x10159, 0x0f401,
+	0x00000, 0x00000, 0x80003, 0x00000, 0x00000, 0x44457, 0x80000,
+	0x30159
+};
+
+static const struct urtwn_rf_prog rtl8188ru_rf_prog[] = {
+	{
+		nitems(rtl8192ce_rf1_regs),
+		rtl8192ce_rf1_regs,
+		rtl8188ru_rf_vals
+	}
+};
+
+struct urtwn_txpwr {
+	uint8_t	pwr[3][28];
+};
+
+struct urtwn_r88e_txpwr {
+	uint8_t	pwr[6][28];
+};
+
+/*
+ * Per RF chain/group/rate Tx gain values.
+ */
+static const struct urtwn_txpwr rtl8192cu_txagc[] = {
+	{ {	/* Chain 0. */
+	{	/* Group 0. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x0c, 0x0c, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02,	/* OFDM6~54. */
+	0x0e, 0x0d, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02,	/* MCS0~7. */
+	0x0e, 0x0d, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02	/* MCS8~15. */
+	},
+	{	/* Group 1. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	},
+	{	/* Group 2. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x04, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	}
+	} },
+	{ {	/* Chain 1. */
+	{	/* Group 0. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	},
+	{	/* Group 1. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	},
+	{	/* Group 2. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x04, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	}
+	} }
+};
+
+static const struct urtwn_txpwr rtl8188ru_txagc[] = {
+	{ {	/* Chain 0. */
+	{	/* Group 0. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x08, 0x08, 0x08, 0x06, 0x06, 0x04, 0x04, 0x00,	/* OFDM6~54. */
+	0x08, 0x06, 0x06, 0x04, 0x04, 0x02, 0x02, 0x00,	/* MCS0~7. */
+	0x08, 0x06, 0x06, 0x04, 0x04, 0x02, 0x02, 0x00	/* MCS8~15. */
+	},
+	{	/* Group 1. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	},
+	{	/* Group 2. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	}
+	} }
+};
+
+static const struct urtwn_r88e_txpwr rtl8188eu_txagc[] = {
+	{ {	/* Chain 0. */
+	{	/* Group 0. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	},
+	{	/* Group 1. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	},
+	{	/* Group 2. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	},
+	{	/* Group 3. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	},
+	{	/* Group 4. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	},
+	{	/* Group 5. */
+	0x00, 0x00, 0x00, 0x00,				/* CCK1~11. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* OFDM6~54. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* MCS0~7. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	/* MCS8~15. */
+	}
+	} }
+};


Property changes on: trunk/sys/dev/usb/wlan/if_urtwnreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/dev/usb/wlan/if_urtwreg.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_urtwreg.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_urtwreg.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,4 +1,5 @@
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_urtwreg.h 198194 2009-10-18 00:11:49Z weongyo $	*/
+/* $MidnightBSD$ */
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_urtwreg.h 261455 2014-02-04 03:36:42Z eadler $	*/
 
 /*-
  * Copyright (c) 2008 Weongyo Jeong <weongyo at FreeBSD.org>
@@ -72,7 +73,7 @@
 #define	URTW_TX_HWMASK			(7 << 25)
 #define	URTW_TX_DISREQQSIZE		(1 << 28)
 #define	URTW_TX_HW_SEQNUM		(1 << 30)
-#define	URTW_TX_CWMIN			(1 << 31)
+#define	URTW_TX_CWMIN			(1U << 31)
 #define	URTW_TX_NOICV			(0x80000)
 #define	URTW_RX				0x0044		/* 4 byte  */
 #define	URTW_RX_9356SEL			(1 << 6)
@@ -106,7 +107,7 @@
 #define	URTW_MAX_RX_DMA_2048		(7 << URTW_MAX_RX_DMA_SHIFT)
 #define	URTW_MAX_RX_DMA_1024		(6)
 #define	URTW_MAX_RX_DMA_SHIFT		(10)
-#define	URTW_RCR_ONLYERLPKT		(1 << 31)
+#define	URTW_RCR_ONLYERLPKT		(1U << 31)
 #define	URTW_INT_TIMEOUT		0x0048		/* 4 byte  */
 #define	URTW_INT_TBDA			0x004c		/* 4 byte  */
 #define	URTW_EPROM_CMD			0x0050		/* 1 byte  */
@@ -330,7 +331,7 @@
 #define	URTW_RX_FLAG_LAST	(1 << 28)
 #define	URTW_RX_FLAG_FIRST	(1 << 29)
 #define	URTW_RX_FLAG_EOR	(1 << 30)
-#define	URTW_RX_FLAG_OWN	(1 << 31)
+#define	URTW_RX_FLAG_OWN	(1U << 31)
 	uint64_t		mactime;
 	uint8_t			noise;
 	uint8_t			rssi;
@@ -367,7 +368,7 @@
 #define	URTW_TX_FLAG_LAST	(1 << 28)
 #define	URTW_TX_FLAG_FIRST	(1 << 29)
 #define	URTW_TX_FLAG_DMA	(1 << 30)
-#define	URTW_TX_FLAG_OWN	(1 << 31)
+#define	URTW_TX_FLAG_OWN	(1U << 31)
 	uint16_t		rtsdur;
 	uint16_t		len;
 #define	URTW_TX_LEN				/*  0 ~ 14 bits */

Modified: trunk/sys/dev/usb/wlan/if_urtwvar.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_urtwvar.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_urtwvar.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,4 +1,5 @@
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_urtwvar.h 259460 2013-12-16 09:34:01Z hselasky $	*/
+/* $MidnightBSD$ */
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_urtwvar.h 253757 2013-07-29 05:54:13Z hselasky $	*/
 
 /*-
  * Copyright (c) 2008 Weongyo Jeong <weongyo at FreeBSD.org>

Modified: trunk/sys/dev/usb/wlan/if_zyd.c
===================================================================
--- trunk/sys/dev/usb/wlan/if_zyd.c	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_zyd.c	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,6 +1,7 @@
+/* $MidnightBSD$ */
 /*	$OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $	*/
 /*	$NetBSD: if_zyd.c,v 1.7 2007/06/21 04:04:29 kiyohara Exp $	*/
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_zyd.c 269267 2014-07-29 22:00:54Z hselasky $	*/
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_zyd.c 269266 2014-07-29 21:59:24Z hselasky $	*/
 
 /*-
  * Copyright (c) 2006 by Damien Bergamini <damien.bergamini at free.fr>
@@ -20,7 +21,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/9/sys/dev/usb/wlan/if_zyd.c 269267 2014-07-29 22:00:54Z hselasky $");
+__FBSDID("$FreeBSD: stable/10/sys/dev/usb/wlan/if_zyd.c 269266 2014-07-29 21:59:24Z hselasky $");
 
 /*
  * ZyDAS ZD1211/ZD1211B USB WLAN driver.
@@ -2506,7 +2507,7 @@
 		}
 	}
 
-	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
 		k = ieee80211_crypto_encap(ni, m0);
 		if (k == NULL) {
 			m_freem(m0);

Modified: trunk/sys/dev/usb/wlan/if_zydfw.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_zydfw.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_zydfw.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (C) 2001, 2002, 2003,2004 ZyDAS Technology Corporation.
  * All rights reserved.
@@ -24,7 +25,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_zydfw.h 196219 2009-08-14 20:03:53Z jhb $	*/
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_zydfw.h 196219 2009-08-14 20:03:53Z jhb $	*/
 
 uint8_t zd1211_firmware[] = {
 	0x08, 0x91, 0xFF, 0xED, 0x09, 0x93, 0x1E, 0xEE,

Modified: trunk/sys/dev/usb/wlan/if_zydreg.h
===================================================================
--- trunk/sys/dev/usb/wlan/if_zydreg.h	2018-05-27 22:33:45 UTC (rev 10042)
+++ trunk/sys/dev/usb/wlan/if_zydreg.h	2018-05-27 22:35:11 UTC (rev 10043)
@@ -1,6 +1,7 @@
+/* $MidnightBSD$ */
 /*	$OpenBSD: if_zydreg.h,v 1.19 2006/11/30 19:28:07 damien Exp $	*/
 /*	$NetBSD: if_zydreg.h,v 1.2 2007/06/16 11:18:45 kiyohara Exp $	*/
-/*	$FreeBSD: stable/9/sys/dev/usb/wlan/if_zydreg.h 269267 2014-07-29 22:00:54Z hselasky $	*/
+/*	$FreeBSD: stable/10/sys/dev/usb/wlan/if_zydreg.h 269266 2014-07-29 21:59:24Z hselasky $	*/
 
 /*-
  * Copyright (c) 2006 by Damien Bergamini <damien.bergamini at free.fr>
@@ -112,7 +113,7 @@
 #define ZYD_MACB_MAX_RETRY	0x9b28
 
 /*
- * Miscellanous registers.
+ * Miscellaneous registers.
  */
 #define ZYD_FIRMWARE_START_ADDR	0xee00
 #define ZYD_FIRMWARE_BASE_ADDR	0xee1d /* Firmware base address */
@@ -1007,7 +1008,7 @@
 #define ZYD_FILTER_CTS		(1 << 28)
 #define ZYD_FILTER_ACK		(1 << 29)
 #define ZYD_FILTER_CFE		(1 << 30)
-#define ZYD_FILTER_CFE_A	(1 << 31)
+#define ZYD_FILTER_CFE_A	(1U << 31)
 
 /* helpers for register ZYD_MAC_RXFILTER */
 #define ZYD_FILTER_MONITOR	0xffffffff



More information about the Midnightbsd-cvs mailing list