Wed Oct 12 03:23:29 2016 UTC ()
Add support for Realtek 8192EU.

OK christos@


(nat)
diff -r1.14 -r1.15 src/share/man/man4/urtwn.4
diff -r1.48 -r1.49 src/sys/dev/usb/if_urtwn.c
diff -r1.3 -r1.4 src/sys/dev/usb/if_urtwn_data.h
diff -r1.9 -r1.10 src/sys/dev/usb/if_urtwnreg.h
diff -r1.9 -r1.10 src/sys/dev/usb/if_urtwnvar.h

cvs diff -r1.14 -r1.15 src/share/man/man4/urtwn.4 (expand / switch to context diff)
--- src/share/man/man4/urtwn.4 2014/07/25 15:07:03 1.14
+++ src/share/man/man4/urtwn.4 2016/10/12 03:23:29 1.15
@@ -1,4 +1,4 @@
-.\" $NetBSD: urtwn.4,v 1.14 2014/07/25 15:07:03 nonaka Exp $
+.\" $NetBSD: urtwn.4,v 1.15 2016/10/12 03:23:29 nat Exp $
 .\" $OpenBSD: urtwn.4,v 1.15 2011/11/26 06:39:33 ckuethe Exp $
 .\"
 .\" Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -20,14 +20,15 @@
 .Os
 .Sh NAME
 .Nm urtwn
-.Nd Realtek RTL8188CU/RTL8188EU/RTL8192CU USB IEEE 802.11b/g/n wireless network device
+.Nd Realtek RTL8188CU/RTL8188EU/RTL8192CU/RTL8192EU USB IEEE 802.11b/g/n wireless network device
 .Sh SYNOPSIS
 .Cd "urtwn* at uhub? port ?"
 .Sh DESCRIPTION
 The
 .Nm
 driver supports USB 2.0 wireless network devices based on Realtek
-RTL8188CUS, RTL8188CE-VAU, RTL8188EUS, RTL8188RU, and RTL8192CU chipsets.
+RTL8188CUS, RTL8188CE-VAU, RTL8188EUS, RTL8188RU, RTL8192CU and RTL8192EU
+chipsets.
 .Pp
 The RTL8188CUS and RTL8188EUS are highly integrated 802.11n adapters that
 combine a MAC, a 1T1R capable baseband and an RF in a single chip.
@@ -36,8 +37,8 @@
 The RTL8188CE-VAU is a PCI Express Mini Card adapter that attaches
 to the USB interface.
 .Pp
-The RTL8192CU is a highly integrated multiple-in, multiple-out (MIMO)
-802.11n adapter that combines a MAC, a 2T2R capable baseband and an
+The RTL8192CU and RTL8192EU are highly integrated multiple-in, multiple-out
+(MIMO) 802.11n adapters that combine a MAC, a 2T2R capable baseband and an
 RF in a single chip.
 It operates in the 2GHz spectrum only.
 .Pp
@@ -96,6 +97,7 @@
 .It /libdata/firmware/if_urtwn/rtl8188eufw.bin
 .It /libdata/firmware/if_urtwn/rtl8192cfw.bin
 .It /libdata/firmware/if_urtwn/rtl8192cfwU.bin
+.It /libdata/firmware/if_urtwn/rtl8192efw.bin
 .El
 .Sh HARDWARE
 The following adapters should work:

cvs diff -r1.48 -r1.49 src/sys/dev/usb/if_urtwn.c (expand / switch to context diff)
--- src/sys/dev/usb/if_urtwn.c 2016/10/12 02:56:45 1.48
+++ src/sys/dev/usb/if_urtwn.c 2016/10/12 03:23:29 1.49
@@ -1,9 +1,10 @@
-/*	$NetBSD: if_urtwn.c,v 1.48 2016/10/12 02:56:45 nat Exp $	*/
+/*	$NetBSD: if_urtwn.c,v 1.49 2016/10/12 03:23:29 nat Exp $	*/
 /*	$OpenBSD: if_urtwn.c,v 1.42 2015/02/10 23:25:46 mpi Exp $	*/
 
 /*-
  * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
  * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,11 +20,12 @@
  */
 
 /*-
- * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188EU/RTL8188RU/RTL8192CU.
+ * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188EU/RTL8188RU/RTL8192CU
+ * RTL8192EU.
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.48 2016/10/12 02:56:45 nat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.49 2016/10/12 03:23:29 nat Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -99,10 +101,13 @@
 #define URTWN_DEV(v,p)	{ { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, 0 }
 #define URTWN_RTL8188E_DEV(v,p) \
 	{ { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, FLAG_RTL8188E }
+#define URTWN_RTL8192EU_DEV(v,p) \
+	{ { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, FLAG_RTL8192E }
 static const struct urtwn_dev {
 	struct usb_devno	dev;
 	uint32_t		flags;
 #define	FLAG_RTL8188E	__BIT(0)
+#define	FLAG_RTL8192E	__BIT(1)
 } urtwn_devs[] = {
 	URTWN_DEV(ABOCOM,	RTL8188CU_1),
 	URTWN_DEV(ABOCOM,	RTL8188CU_2),
@@ -184,9 +189,13 @@
 	URTWN_RTL8188E_DEV(ELECOM, WDC150SU2M),
 	URTWN_RTL8188E_DEV(REALTEK, RTL8188ETV),
 	URTWN_RTL8188E_DEV(REALTEK, RTL8188EU),
+	
+	/* URTWN_RTL8192EU */
+	URTWN_RTL8192EU_DEV(REALTEK,	RTL8192EU),
 };
 #undef URTWN_DEV
 #undef URTWN_RTL8188E_DEV
+#undef URTWN_RTL8192EU_DEV
 
 static int	urtwn_match(device_t, cfdata_t, void *);
 static void	urtwn_attach(device_t, device_t, void *);
@@ -223,6 +232,8 @@
 		    uint32_t);
 static void	urtwn_r88e_rf_write(struct urtwn_softc *, int, uint8_t,
 		    uint32_t);
+static void	urtwn_r92e_rf_write(struct urtwn_softc *, int, uint8_t,
+		    uint32_t);
 static uint32_t	urtwn_rf_read(struct urtwn_softc *, int, uint8_t);
 static int	urtwn_llt_write(struct urtwn_softc *, uint32_t, uint32_t);
 static uint8_t	urtwn_efuse_read_1(struct urtwn_softc *, uint16_t);
@@ -262,6 +273,7 @@
 static void	urtwn_watchdog(struct ifnet *);
 static int	urtwn_ioctl(struct ifnet *, u_long, void *);
 static int	urtwn_r92c_power_on(struct urtwn_softc *);
+static int	urtwn_r92e_power_on(struct urtwn_softc *);
 static int	urtwn_r88e_power_on(struct urtwn_softc *);
 static int	urtwn_llt_init(struct urtwn_softc *);
 static void	urtwn_fw_reset(struct urtwn_softc *);
@@ -293,6 +305,7 @@
 static int	urtwn_reset(struct ifnet *);
 static void	urtwn_chip_stop(struct urtwn_softc *);
 static void	urtwn_newassoc(struct ieee80211_node *, int);
+static void	urtwn_delay_ms(struct urtwn_softc *, int ms);
 
 /* Aliases. */
 #define	urtwn_bb_write	urtwn_write_4
@@ -313,8 +326,8 @@
 {
 	struct usb_attach_arg *uaa = aux;
 
-	return urtwn_lookup(urtwn_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL ?
-	    UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
+	return urtwn_lookup(urtwn_devs, uaa->uaa_vendor, uaa->uaa_product) !=
+	    NULL ?  UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
 }
 
 static void
@@ -337,6 +350,8 @@
 	dev = urtwn_lookup(urtwn_devs, uaa->uaa_vendor, uaa->uaa_product);
 	if (dev != NULL && ISSET(dev->flags, FLAG_RTL8188E))
 		SET(sc->chip, URTWN_CHIP_88E);
+	if (dev != NULL && ISSET(dev->flags, FLAG_RTL8192E))
+		SET(sc->chip, URTWN_CHIP_92EU);
 
 	aprint_naive("\n");
 	aprint_normal("\n");
@@ -357,6 +372,7 @@
 
 	mutex_init(&sc->sc_task_mtx, MUTEX_DEFAULT, IPL_NET);
 	mutex_init(&sc->sc_tx_mtx, MUTEX_DEFAULT, IPL_NONE);
+	mutex_init(&sc->sc_rx_mtx, MUTEX_DEFAULT, IPL_NONE);
 	mutex_init(&sc->sc_fwcmd_mtx, MUTEX_DEFAULT, IPL_NONE);
 	mutex_init(&sc->sc_write_mtx, MUTEX_DEFAULT, IPL_NONE);
 
@@ -391,17 +407,22 @@
 	if (sc->chip & URTWN_CHIP_92C) {
 		sc->ntxchains = (sc->chip & URTWN_CHIP_92C_1T2R) ? 1 : 2;
 		sc->nrxchains = 2;
+	} else if (sc->chip & URTWN_CHIP_92EU) {
+		sc->ntxchains = 2;
+		sc->nrxchains = 2;
 	} else {
 		sc->ntxchains = 1;
 		sc->nrxchains = 1;
 	}
 
-	if (ISSET(sc->chip, URTWN_CHIP_88E))
+	if (ISSET(sc->chip, URTWN_CHIP_88E) ||
+	    ISSET(sc->chip, URTWN_CHIP_92EU))
 		urtwn_r88e_read_rom(sc);
 	else
 		urtwn_read_rom(sc);
 
 	aprint_normal_dev(self, "MAC/BB RTL%s, RF 6052 %zdT%zdR, address %s\n",
+	    (sc->chip & URTWN_CHIP_92EU) ? "8192EU" :
 	    (sc->chip & URTWN_CHIP_92C) ? "8192CU" :
 	    (sc->chip & URTWN_CHIP_88E) ? "8188EU" :
 	    (sc->board_type == R92C_BOARD_TYPE_HIGHPA) ? "8188RU" :
@@ -539,6 +560,7 @@
 	mutex_destroy(&sc->sc_write_mtx);
 	mutex_destroy(&sc->sc_fwcmd_mtx);
 	mutex_destroy(&sc->sc_tx_mtx);
+	mutex_destroy(&sc->sc_rx_mtx);
 	mutex_destroy(&sc->sc_task_mtx);
 
 	return 0;
@@ -564,10 +586,11 @@
 urtwn_open_pipes(struct urtwn_softc *sc)
 {
 	/* Bulk-out endpoints addresses (from highest to lowest prio). */
-	static const uint8_t epaddr[] = { 0x02, 0x03, 0x05 };
+	static uint8_t epaddr[3];
+	static uint8_t rxepaddr[3];
 	usb_interface_descriptor_t *id;
 	usb_endpoint_descriptor_t *ed;
-	size_t i, ntx = 0;
+	size_t i, ntx = 0, nrx = 0;
 	int error;
 
 	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
@@ -578,8 +601,16 @@
 		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
 		if (ed != NULL &&
 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK &&
-		    UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
+		    UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) {
+			epaddr[ntx] = ed->bEndpointAddress;
 			ntx++;
+		}
+		if (ed != NULL &&
+		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK &&
+		    UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) {
+			rxepaddr[nrx] = ed->bEndpointAddress;
+			nrx++;
+		}
 	}
 	DPRINTFN(DBG_INIT, ("%s: %s: found %zd bulk-out pipes\n",
 	    device_xname(sc->sc_dev), __func__, ntx));
@@ -588,16 +619,19 @@
 		    "%zd: invalid number of Tx bulk pipes\n", ntx);
 		return EIO;
 	}
-	sc->rx_npipe = 1;
+	sc->rx_npipe = nrx;
 	sc->tx_npipe = ntx;
 
 	/* Open bulk-in pipe at address 0x81. */
-	error = usbd_open_pipe(sc->sc_iface, 0x81, USBD_EXCLUSIVE_USE,
-	    &sc->rx_pipe);
-	if (error != 0) {
-		aprint_error_dev(sc->sc_dev, "could not open Rx bulk pipe"
-		    ": %d\n", error);
-		goto fail;
+	for (i = 0; i < nrx; i++) {
+		error = usbd_open_pipe(sc->sc_iface, rxepaddr[i],
+		    USBD_EXCLUSIVE_USE, &sc->rx_pipe[i]);
+		if (error != 0) {
+			aprint_error_dev(sc->sc_dev,
+			    "could not open Rx bulk pipe 0x%02x: %d\n",
+			    rxepaddr[i], error);
+			goto fail;
+		}
 	}
 
 	/* Open bulk-out pipes (up to 3). */
@@ -632,14 +666,17 @@
 
 	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
-	/* Close Rx pipe. */
+	/* Close Rx pipes. */
 	CTASSERT(sizeof(pipe) == sizeof(void *));
-	pipe = atomic_swap_ptr(&sc->rx_pipe, NULL);
-	if (pipe != NULL) {
-		usbd_close_pipe(pipe);
+	for (i = 0; i < sc->rx_npipe; i++) {
+		pipe = atomic_swap_ptr(&sc->rx_pipe[i], NULL);
+		if (pipe != NULL) {
+			usbd_close_pipe(pipe);
+		}
 	}
+
 	/* Close Tx pipes. */
-	for (i = 0; i < R92C_MAX_EPOUT; i++) {
+	for (i = 0; i < sc->tx_npipe; i++) {
 		pipe = atomic_swap_ptr(&sc->tx_pipe[i], NULL);
 		if (pipe != NULL) {
 			usbd_close_pipe(pipe);
@@ -656,20 +693,24 @@
 
 	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
-	for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
-		data = &sc->rx_data[i];
+	for (size_t j = 0; j < sc->rx_npipe; j++) {
+		TAILQ_INIT(&sc->rx_free_list[j]);
+		for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
+			data = &sc->rx_data[j][i];
 
-		data->sc = sc;	/* Backpointer for callbacks. */
+			data->sc = sc;	/* Backpointer for callbacks. */
 
-		error = usbd_create_xfer(sc->rx_pipe, URTWN_RXBUFSZ,
-		    USBD_SHORT_XFER_OK, 0, &data->xfer);
-		if (error) {
-			aprint_error_dev(sc->sc_dev,
-			    "could not allocate xfer\n");
-			break;
-		}
+			error = usbd_create_xfer(sc->rx_pipe[j], URTWN_RXBUFSZ,
+			    USBD_SHORT_XFER_OK, 0, &data->xfer);
+			if (error) {
+				aprint_error_dev(sc->sc_dev,
+				    "could not allocate xfer\n");
+				break;
+			}
 
-		data->buf = usbd_get_buffer(data->xfer);
+			data->buf = usbd_get_buffer(data->xfer);
+			TAILQ_INSERT_TAIL(&sc->rx_free_list[j], data, next);
+		}
 	}
 	if (error != 0)
 		urtwn_free_rx_list(sc);
@@ -685,11 +726,13 @@
 	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
 	/* NB: Caller must abort pipe first. */
-	for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
-		CTASSERT(sizeof(xfer) == sizeof(void *));
-		xfer = atomic_swap_ptr(&sc->rx_data[i].xfer, NULL);
-		if (xfer != NULL)
-			usbd_destroy_xfer(xfer);
+	for (size_t j = 0; j < sc->rx_npipe; j++) {
+		for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
+			CTASSERT(sizeof(xfer) == sizeof(void *));
+			xfer = atomic_swap_ptr(&sc->rx_data[j][i].xfer, NULL);
+			if (xfer != NULL)
+				usbd_destroy_xfer(xfer);
+		}
 	}
 }
 
@@ -977,7 +1020,7 @@
 	for (ntries = 0; ntries < 100; ntries++) {
 		if (!(urtwn_read_1(sc, R92C_HMETFR) & (1 << fwcur)))
 			break;
-		DELAY(1);
+		DELAY(10);
 	}
 	if (ntries == 100) {
 		aprint_error_dev(sc->sc_dev,
@@ -991,13 +1034,23 @@
 
 	/* Write the first word last since that will trigger the FW. */
 	cp = (uint8_t *)&cmd;
+	cmd.id = id;
 	if (len >= 4) {
-		cmd.id = id | R92C_CMD_FLAG_EXT;
-		urtwn_write_region(sc, R92C_HMEBOX_EXT(fwcur), &cp[1], 2);
-		urtwn_write_4(sc, R92C_HMEBOX(fwcur),
-		    cp[0] + (cp[3] << 8) + (cp[4] << 16) + (cp[5] << 24));
+		if (!ISSET(sc->chip, URTWN_CHIP_92EU)) {
+			cmd.id |= R92C_CMD_FLAG_EXT;
+			urtwn_write_region(sc, R92C_HMEBOX_EXT(fwcur),
+			    &cp[1], 2);
+			urtwn_write_4(sc, R92C_HMEBOX(fwcur),
+			    cp[0] + (cp[3] << 8) + (cp[4] << 16) +
+			    (cp[5] << 24));
+		} else {
+			urtwn_write_region(sc, R92E_HMEBOX_EXT(fwcur),
+			    &cp[4], 2);
+			urtwn_write_4(sc, R92C_HMEBOX(fwcur),
+			    cp[0] + (cp[1] << 8) + (cp[2] << 16) +
+			    (cp[3] << 24));
+		}
 	} else {
-		cmd.id = id;
 		urtwn_write_region(sc, R92C_HMEBOX(fwcur), cp, len);
 	}
 
@@ -1029,6 +1082,15 @@
 	    SM(R88E_LSSI_PARAM_ADDR, addr) | SM(R92C_LSSI_PARAM_DATA, val));
 }
 
+static void
+urtwn_r92e_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr,
+    uint32_t val)
+{
+
+	urtwn_bb_write(sc, R92C_LSSI_PARAM(chain),
+	    SM(R88E_LSSI_PARAM_ADDR, addr) | SM(R92C_LSSI_PARAM_DATA, val));
+}
+
 static uint32_t
 urtwn_rf_read(struct urtwn_softc *sc, int chain, uint8_t addr)
 {
@@ -1184,7 +1246,8 @@
 
 	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
-	if (ISSET(sc->chip, URTWN_CHIP_88E))
+	if (ISSET(sc->chip, URTWN_CHIP_88E) ||
+	    ISSET(sc->chip, URTWN_CHIP_92EU))
 		return 0;
 
 	reg = urtwn_read_4(sc, R92C_SYS_CFG);
@@ -1349,7 +1412,7 @@
 
 	/* Read full ROM image. */
 	memset(&sc->r88e_rom, 0xff, sizeof(sc->r88e_rom));
-	while (addr < 1024) {
+	while (addr < 4096) {
 		reg = urtwn_efuse_read_1(sc, addr);
 		if (reg == 0xff)
 			break;
@@ -1392,8 +1455,13 @@
 
 	IEEE80211_ADDR_COPY(ic->ic_myaddr, &sc->r88e_rom[0xd7]);
 
-	sc->sc_rf_write = urtwn_r88e_rf_write;
-	sc->sc_power_on = urtwn_r88e_power_on;
+	if (ISSET(sc->chip, URTWN_CHIP_92EU)) {
+		sc->sc_power_on = urtwn_r92e_power_on;
+		sc->sc_rf_write = urtwn_r92e_rf_write;
+	} else {
+		sc->sc_power_on = urtwn_r88e_power_on;
+		sc->sc_rf_write = urtwn_r88e_rf_write;
+	}
 	sc->sc_dma_init = urtwn_r88e_dma_init;
 
 	mutex_exit(&sc->sc_write_mtx);
@@ -1433,7 +1501,7 @@
 	struct ieee80211_rateset *rs = &ni->ni_rates;
 	struct r92c_fw_cmd_macid_cfg cmd;
 	uint32_t rates, basicrates;
-	uint32_t mask;
+	uint32_t mask, rrsr_mask, rrsr_rate;
 	uint8_t mode;
 	size_t maxrate, maxbasicrate, i, j;
 	int error;
@@ -1443,7 +1511,7 @@
 	KASSERT(mutex_owned(&sc->sc_write_mtx));
 
 	/* Get normal and basic rates mask. */
-	rates = basicrates = 0;
+	rates = basicrates = 1;
 	maxrate = maxbasicrate = 0;
 	for (i = 0; i < rs->rs_nrates; i++) {
 		/* Convert 802.11 rate to HW rate index. */
@@ -1478,12 +1546,17 @@
 	    "maxrate=%zx, maxbasicrate=%zx\n",
 	    device_xname(sc->sc_dev), __func__, mode, rates, basicrates,
 	    maxrate, maxbasicrate));
-	if (basicrates == 0) {
-		basicrates |= 1;	/* add 1Mbps */
+
+	if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) {
+		maxbasicrate |= R92C_RATE_SHORTGI;
+		maxrate |= R92C_RATE_SHORTGI;
 	}
 
 	/* Set rates mask for group addressed frames. */
 	cmd.macid = URTWN_MACID_BC | URTWN_MACID_VALID;
+	if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)
+		cmd.macid |= URTWN_MACID_SHORTGI;
+
 	mask = (mode << 28) | basicrates;
 	cmd.mask[0] = (uint8_t)mask;
 	cmd.mask[1] = (uint8_t)(mask >> 8);
@@ -1502,6 +1575,9 @@
 
 	/* Set rates mask for unicast frames. */
 	cmd.macid = URTWN_MACID_BSS | URTWN_MACID_VALID;
+	if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)
+		cmd.macid |= URTWN_MACID_SHORTGI;
+
 	mask = (mode << 28) | rates;
 	cmd.mask[0] = (uint8_t)mask;
 	cmd.mask[1] = (uint8_t)(mask >> 8);
@@ -1517,6 +1593,13 @@
 	    __func__, maxrate));
 	urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(URTWN_MACID_BSS), maxrate);
 
+	rrsr_rate = ic->ic_fixed_rate;
+	if (rrsr_rate == -1)
+		rrsr_rate = 11;
+
+	rrsr_mask = 0xffff >> (15 - rrsr_rate);
+	urtwn_write_2(sc, R92C_RRSR, rrsr_mask);
+
 	/* Indicate highest supported rate. */
 	ni->ni_txrate = rs->rs_nrates - 1;
 
@@ -1603,7 +1686,17 @@
 	KASSERT(mutex_owned(&sc->sc_write_mtx));
 
 	if (led == URTWN_LED_LINK) {
-		if (ISSET(sc->chip, URTWN_CHIP_88E)) {
+		if (ISSET(sc->chip, URTWN_CHIP_92EU)) {
+			urtwn_write_1(sc, 0x64, urtwn_read_1(sc, 0x64) & 0xfe);
+			reg = urtwn_read_1(sc, R92C_LEDCFG1) & R92E_LEDSON;
+			urtwn_write_1(sc, R92C_LEDCFG1, reg |
+			    (R92C_LEDCFG0_DIS << 1));
+			if (on) {
+				reg = urtwn_read_1(sc, R92C_LEDCFG1) &
+				    R92E_LEDSON;
+				urtwn_write_1(sc, R92C_LEDCFG1, reg);
+			}
+		} else if (ISSET(sc->chip, URTWN_CHIP_88E)) {
 			reg = urtwn_read_1(sc, R92C_LEDCFG2) & 0xf0;
 			urtwn_write_1(sc, R92C_LEDCFG2, reg | 0x60);
 			if (!on) {
@@ -1644,6 +1737,7 @@
 urtwn_calib_to_cb(struct urtwn_softc *sc, void *arg)
 {
 	struct r92c_fw_cmd_rssi cmd;
+	struct r92e_fw_cmd_rssi cmde;
 
 	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
@@ -1654,11 +1748,20 @@
 	if (sc->avg_pwdb != -1) {
 		/* Indicate Rx signal strength to FW for rate adaptation. */
 		memset(&cmd, 0, sizeof(cmd));
+		memset(&cmde, 0, sizeof(cmde));
 		cmd.macid = 0;	/* BSS. */
+		cmde.macid = 0;	/* BSS. */
 		cmd.pwdb = sc->avg_pwdb;
+		cmde.pwdb = sc->avg_pwdb;
 		DPRINTFN(DBG_RF, ("%s: %s: sending RSSI command avg=%d\n",
 		    device_xname(sc->sc_dev), __func__, sc->avg_pwdb));
-		urtwn_fw_cmd(sc, R92C_CMD_RSSI_SETTING, &cmd, sizeof(cmd));
+		if (!ISSET(sc->chip, URTWN_CHIP_92EU)) {
+			urtwn_fw_cmd(sc, R92C_CMD_RSSI_SETTING, &cmd,
+			    sizeof(cmd));
+		} else {
+			urtwn_fw_cmd(sc, R92E_CMD_RSSI_REPORT, &cmde,
+			    sizeof(cmde));
+		}
 	}
 
 	/* Do temperature compensation. */
@@ -1863,20 +1966,12 @@
 	case IEEE80211_S_AUTH:
 		/* Set initial gain under link. */
 		reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0));
-#ifdef doaslinux
 		reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
-#else
-		reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
-#endif
 		urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);
 
 		if (!ISSET(sc->chip, URTWN_CHIP_88E)) {
 			reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
-#ifdef doaslinux
 			reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
-#else
-			reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
-#endif
 			urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
 		}
 
@@ -1994,7 +2089,8 @@
 		urtwn_write_1(sc, R92C_T2T_SIFS + 1, sifs_time);
 
 		/* Intialize rate adaptation. */
-		if (ISSET(sc->chip, URTWN_CHIP_88E))
+		if (ISSET(sc->chip, URTWN_CHIP_88E) ||
+		    ISSET(sc->chip, URTWN_CHIP_92EU))
 			ni->ni_txrate = ni->ni_rates.rs_nrates - 1;
 		else
 			urtwn_ra_init(sc);
@@ -2252,7 +2348,7 @@
 
 	/* Get RSSI from PHY status descriptor if present. */
 	if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
-		if (ISSET(sc->chip, URTWN_CHIP_88E))
+		if (!ISSET(sc->chip, URTWN_CHIP_92C))
 			rssi = urtwn_r88e_get_rssi(sc, rate, &stat[1]);
 		else
 			rssi = urtwn_get_rssi(sc, rate, &stat[1]);
@@ -2338,6 +2434,7 @@
 	struct urtwn_rx_data *data = priv;
 	struct urtwn_softc *sc = data->sc;
 	struct r92c_rx_stat *stat;
+	size_t pidx = data->pidx;
 	uint32_t rxdw0;
 	uint8_t *buf;
 	int len, totlen, pktlen, infosz, npkts;
@@ -2345,9 +2442,15 @@
 	DPRINTFN(DBG_FN|DBG_RX, ("%s: %s: status=%d\n",
 	    device_xname(sc->sc_dev), __func__, status));
 
+	mutex_enter(&sc->sc_rx_mtx);
+	TAILQ_REMOVE(&sc->rx_free_list[pidx], data, next);
+	TAILQ_INSERT_TAIL(&sc->rx_free_list[pidx], data, next);
+	/* Put this Rx buffer back to our free list. */
+	mutex_exit(&sc->sc_rx_mtx);
+
 	if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall_async(sc->rx_pipe);
+			usbd_clear_endpoint_stall_async(sc->rx_pipe[pidx]);
 		else if (status != USBD_CANCELLED)
 			goto resubmit;
 		return;
@@ -2439,6 +2542,7 @@
 				struct usbd_pipe *pipe = sc->tx_pipe[pidx];
 				usbd_clear_endpoint_stall_async(pipe);
 			}
+			printf("ERROR1\n");
 			ifp->if_oerrors++;
 		}
 		splx(s);
@@ -2447,8 +2551,8 @@
 
 	ifp->if_opackets++;
 	urtwn_start(ifp);
-
 	splx(s);
+
 }
 
 static int
@@ -2459,7 +2563,7 @@
 	struct ieee80211_frame *wh;
 	struct ieee80211_key *k = NULL;
 	struct r92c_tx_desc *txd;
-	size_t i, padsize, xferlen;
+	size_t i, padsize, xferlen, txd_len;
 	uint16_t seq, sum;
 	uint8_t raid, type, tid;
 	int s, hasqos, error;
@@ -2468,7 +2572,11 @@
 
 	wh = mtod(m, struct ieee80211_frame *);
 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+	txd_len = sizeof(*txd);
 
+	if (!ISSET(sc->chip, URTWN_CHIP_92EU))
+		txd_len = 32;
+
 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
 		k = ieee80211_crypto_encap(ic, ni, m);
 		if (k == NULL)
@@ -2502,19 +2610,25 @@
 		tid = R92C_TXDW1_QSEL_MGNT;
 	}
 
-	if (((sizeof(*txd) + m->m_pkthdr.len) % 64) == 0) /* XXX: 64 */
+	if (((txd_len + m->m_pkthdr.len) % 64) == 0) /* XXX: 64 */
 		padsize = 8;
 	else
 		padsize = 0;
 
+	if (ISSET(sc->chip, URTWN_CHIP_92EU))
+		padsize = 0;
+
 	/* Fill Tx descriptor. */
 	txd = (struct r92c_tx_desc *)data->buf;
-	memset(txd, 0, sizeof(*txd) + padsize);
+	memset(txd, 0, txd_len + padsize);
 
 	txd->txdw0 |= htole32(
 	    SM(R92C_TXDW0_PKTLEN, m->m_pkthdr.len) |
-	    SM(R92C_TXDW0_OFFSET, sizeof(*txd)) |
-	    R92C_TXDW0_OWN | R92C_TXDW0_FSG | R92C_TXDW0_LSG);
+	    SM(R92C_TXDW0_OFFSET, txd_len));
+	if (!ISSET(sc->chip, URTWN_CHIP_92EU)) {
+		txd->txdw0 |= htole32(
+		    R92C_TXDW0_OWN | R92C_TXDW0_FSG | R92C_TXDW0_LSG);
+	}
 
 	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
 		txd->txdw0 |= htole32(R92C_TXDW0_BMCAST);
@@ -2536,13 +2650,12 @@
 		    ("%s: %s: data packet: tid=%d, raid=%d\n",
 		    device_xname(sc->sc_dev), __func__, tid, raid));
 
-		if (ISSET(sc->chip, URTWN_CHIP_88E)) {
+		if (!ISSET(sc->chip, URTWN_CHIP_92C)) {
 			txd->txdw1 |= htole32(
 			    SM(R88E_TXDW1_MACID, URTWN_MACID_BSS) |
 			    SM(R92C_TXDW1_QSEL, tid) |
 			    SM(R92C_TXDW1_RAID, raid) |
 			    R92C_TXDW1_AGGBK);
-			txd->txdw2 |= htole32(R88E_TXDW2_AGGBK);
 		} else
 			txd->txdw1 |= htole32(
 			    SM(R92C_TXDW1_MACID, URTWN_MACID_BSS) |
@@ -2550,6 +2663,11 @@
 			    SM(R92C_TXDW1_RAID, raid) |
 			    R92C_TXDW1_AGGBK);
 
+		if (ISSET(sc->chip, URTWN_CHIP_88E))
+			txd->txdw2 |= htole32(R88E_TXDW2_AGGBK);
+		if (ISSET(sc->chip, URTWN_CHIP_92EU))
+			txd->txdw3 |= htole32(R92E_TXDW3_AGGBK);
+
 		if (hasqos) {
 			txd->txdw4 |= htole32(R92C_TXDW4_QOS);
 		}
@@ -2597,25 +2715,34 @@
 		/* Use 1Mbps */
 		txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 0));
 	}
-
 	/* Set sequence number */
 	seq = LE_READ_2(&wh->i_seq[0]) >> IEEE80211_SEQ_SEQ_SHIFT;
-	txd->txdseq |= htole16(seq);
+	if (!ISSET(sc->chip, URTWN_CHIP_92EU)) {
+		txd->txdseq |= htole16(seq);
 
-	if (!hasqos) {
-		/* Use HW sequence numbering for non-QoS frames. */
-		txd->txdw4  |= htole32(R92C_TXDW4_HWSEQ);
-		txd->txdseq |= htole16(0x8000);		/* WTF? */
+		if (!hasqos) {
+			/* Use HW sequence numbering for non-QoS frames. */
+			txd->txdw4  |= htole32(R92C_TXDW4_HWSEQ);
+			txd->txdseq |= htole16(R92C_HWSEQ_EN);
+		}
+	} else {
+		txd->txdseq2 |= htole16((seq & R92E_HWSEQ_MASK) <<
+		    R92E_HWSEQ_SHIFT);
+		if (!hasqos) {
+			/* Use HW sequence numbering for non-QoS frames. */
+			txd->txdw4  |= htole32(R92C_TXDW4_HWSEQ);
+			txd->txdw7 |= htole16(R92C_HWSEQ_EN);
+		}
 	}
 
 	/* Compute Tx descriptor checksum. */
 	sum = 0;
-	for (i = 0; i < sizeof(*txd) / 2; i++)
+	for (i = 0; i < R92C_TXDESC_SUMSIZE / 2; i++)
 		sum ^= ((uint16_t *)txd)[i];
 	txd->txdsum = sum;	/* NB: already little endian. */
 
-	xferlen = sizeof(*txd) + m->m_pkthdr.len + padsize;
-	m_copydata(m, 0, m->m_pkthdr.len, (char *)&txd[1] + padsize);
+	xferlen = txd_len + m->m_pkthdr.len + padsize;
+	m_copydata(m, 0, m->m_pkthdr.len, (char *)&txd[0] + txd_len + padsize);
 
 	s = splnet();
 	usbd_setup_xfer(data->xfer, data, data->buf, xferlen,
@@ -2714,6 +2841,7 @@
 
 		if (m->m_len < (int)sizeof(*eh) &&
 		    (m = m_pullup(m, sizeof(*eh))) == NULL) {
+			printf("ERROR6\n");
 			ifp->if_oerrors++;
 			continue;
 		}
@@ -2721,6 +2849,7 @@
 		ni = ieee80211_find_txnode(ic, eh->ether_dhost);
 		if (ni == NULL) {
 			m_freem(m);
+			printf("ERROR5\n");
 			ifp->if_oerrors++;
 			continue;
 		}
@@ -2729,6 +2858,7 @@
 
 		if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
 			ieee80211_free_node(ni);
+			printf("ERROR4\n");
 			ifp->if_oerrors++;
 			continue;
 		}
@@ -2738,6 +2868,7 @@
 		if (urtwn_tx(sc, m, ni, data) != 0) {
 			m_freem(m);
 			ieee80211_free_node(ni);
+			printf("ERROR3\n");
 			ifp->if_oerrors++;
 			continue;
 		}
@@ -2761,6 +2892,7 @@
 		if (--sc->tx_timer == 0) {
 			aprint_error_dev(sc->sc_dev, "device timeout\n");
 			/* urtwn_init(ifp); XXX needs a process context! */
+			printf("ERROR2\n");
 			ifp->if_oerrors++;
 			return;
 		}
@@ -2858,7 +2990,7 @@
 	urtwn_write_1(sc, R92C_RSV_CTRL, 0);
 	/* Move SPS into PWM mode. */
 	urtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b);
-	DELAY(100);
+	DELAY(5);
 
 	reg = urtwn_read_1(sc, R92C_LDOV12D_CTRL);
 	if (!(reg & R92C_LDOV12D_CTRL_LDV12_EN)) {
@@ -2877,7 +3009,7 @@
 		if (!(urtwn_read_2(sc, R92C_APS_FSMCO) &
 		    R92C_APS_FSMCO_APFM_ONMAC))
 			break;
-		DELAY(5);
+		DELAY(100);
 	}
 	if (ntries == 1000) {
 		aprint_error_dev(sc->sc_dev,
@@ -2925,6 +3057,86 @@
 }
 
 static int
+urtwn_r92e_power_on(struct urtwn_softc *sc)
+{
+	uint32_t reg;
+	uint32_t val;
+	int ntries;
+
+	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
+
+	KASSERT(mutex_owned(&sc->sc_write_mtx));
+
+	/* Enable radio, GPIO and LED functions. */
+	KASSERT((R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_PDN_EN |
+	    R92C_APS_FSMCO_PFM_ALDN) == 0x0812);
+	urtwn_write_2(sc, R92C_APS_FSMCO,
+	    R92C_APS_FSMCO_AFSM_HSUS |
+	    R92C_APS_FSMCO_PDN_EN |
+	    R92C_APS_FSMCO_PFM_ALDN);
+
+	if (urtwn_read_4(sc, R92E_SYS_CFG1_8192E) & R92E_SPSLDO_SEL){
+		/* LDO. */
+		urtwn_write_1(sc, R92E_LDO_SWR_CTRL, 0xc3); 
+	}
+	else	{
+		urtwn_write_2(sc, R92C_SYS_SWR_CTRL2, urtwn_read_2(sc,
+		    R92C_SYS_SWR_CTRL2) & 0xffff);
+		urtwn_write_1(sc, R92E_LDO_SWR_CTRL, 0x83);
+	}
+
+	for (ntries = 0; ntries < 2; ntries++) {
+		urtwn_write_1(sc, R92C_AFE_PLL_CTRL,
+		    urtwn_read_1(sc, R92C_AFE_PLL_CTRL));
+		urtwn_write_2(sc, R92C_AFE_CTRL4, urtwn_read_2(sc,
+		    R92C_AFE_CTRL4));
+	}
+
+	/* Reset BB. */
+	urtwn_write_1(sc, R92C_SYS_FUNC_EN,
+	urtwn_read_1(sc, R92C_SYS_FUNC_EN) & ~(R92C_SYS_FUNC_EN_BBRSTB |
+	    R92C_SYS_FUNC_EN_BB_GLB_RST));
+
+	urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 2, urtwn_read_1(sc,
+	    R92C_AFE_XTAL_CTRL + 2) | 0x80);
+
+	/* Disable HWPDN. */
+	urtwn_write_2(sc, R92C_APS_FSMCO, urtwn_read_2(sc,
+	    R92C_APS_FSMCO) & ~R92C_APS_FSMCO_APDM_HPDN);
+
+	/* Disable WL suspend. */
+	urtwn_write_2(sc, R92C_APS_FSMCO, urtwn_read_2(sc,
+	    R92C_APS_FSMCO) & ~(R92C_APS_FSMCO_AFSM_PCIE |
+	    R92C_APS_FSMCO_AFSM_HSUS));
+
+	urtwn_write_4(sc, R92C_APS_FSMCO, urtwn_read_4(sc,
+	    R92C_APS_FSMCO) | R92C_APS_FSMCO_RDY_MACON);
+	urtwn_write_2(sc, R92C_APS_FSMCO, urtwn_read_2(sc,
+	    R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC);
+	for (ntries = 0; ntries < 10000; ntries++) {
+		val = urtwn_read_2(sc, R92C_APS_FSMCO) &
+		 R92C_APS_FSMCO_APFM_ONMAC;
+		if (val == 0x0)
+			break;
+		DELAY(10);
+	}
+	if (ntries == 10000) {
+		aprint_error_dev(sc->sc_dev,
+		    "timeout waiting for chip power up\n");
+		return ETIMEDOUT;
+	}
+	    
+	urtwn_write_2(sc, R92C_CR, 0x00);
+	reg = urtwn_read_2(sc, R92C_CR);
+	reg |= R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
+	    R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN |
+	    R92C_CR_SCHEDULE_EN | R92C_CR_ENSEC;
+	urtwn_write_2(sc, R92C_CR, reg);
+
+	return 0;
+}
+
+static int
 urtwn_r88e_power_on(struct urtwn_softc *sc)
 {
 	uint32_t reg;
@@ -2988,17 +3200,36 @@
 urtwn_llt_init(struct urtwn_softc *sc)
 {
 	size_t i, page_count, pktbuf_count;
+	uint32_t val;
 	int error;
 
 	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
 	KASSERT(mutex_owned(&sc->sc_write_mtx));
 
-	page_count = (sc->chip & URTWN_CHIP_88E) ?
-	    R88E_TX_PAGE_COUNT : R92C_TX_PAGE_COUNT;
-	pktbuf_count = (sc->chip & URTWN_CHIP_88E) ?
-	    R88E_TXPKTBUF_COUNT : R92C_TXPKTBUF_COUNT;
+	if (sc->chip & URTWN_CHIP_88E) 
+		page_count = R88E_TX_PAGE_COUNT;
+	else if (sc->chip & URTWN_CHIP_92EU) 
+		page_count = R92E_TX_PAGE_COUNT;
+	else
+		page_count = R92C_TX_PAGE_COUNT;
+	if (sc->chip & URTWN_CHIP_88E)
+		pktbuf_count = R88E_TXPKTBUF_COUNT;
+	else if (sc->chip & URTWN_CHIP_92EU)
+		pktbuf_count = R88E_TXPKTBUF_COUNT;
+	else
+		pktbuf_count = R92C_TXPKTBUF_COUNT;
 
+	if (sc->chip & URTWN_CHIP_92EU) {
+		val = urtwn_read_4(sc, R92E_AUTO_LLT) | R92E_AUTO_LLT_EN;
+		urtwn_write_4(sc, R92E_AUTO_LLT, val);
+		DELAY(100);
+		val = urtwn_read_4(sc, R92E_AUTO_LLT);
+		if (val & R92E_AUTO_LLT_EN)
+			return EIO;
+		return 0;
+	}
+
 	/* Reserve pages [0; page_count]. */
 	for (i = 0; i < page_count; i++) {
 		if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
@@ -3054,9 +3285,25 @@
 
 	KASSERT(mutex_owned(&sc->sc_write_mtx));
 
+	if (ISSET(sc->chip, URTWN_CHIP_92EU)) {
+		reg = urtwn_read_2(sc, R92C_RSV_CTRL) & ~R92E_RSV_MIO_EN;
+		urtwn_write_2(sc,R92C_RSV_CTRL, reg);
+	}
+	DELAY(50);
+
 	reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
 	urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
+	DELAY(50);
+
 	urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg | R92C_SYS_FUNC_EN_CPUEN);
+	DELAY(50);
+
+	if (ISSET(sc->chip, URTWN_CHIP_92EU)) {
+		reg = urtwn_read_2(sc, R92C_RSV_CTRL) | R92E_RSV_MIO_EN;
+		urtwn_write_2(sc,R92C_RSV_CTRL, reg);
+	}
+	DELAY(50);
+
 }
 
 static int
@@ -3108,6 +3355,8 @@
 	/* Read firmware image from the filesystem. */
 	if (ISSET(sc->chip, URTWN_CHIP_88E))
 		name = "rtl8188eufw.bin";
+	else if (ISSET(sc->chip, URTWN_CHIP_92EU))
+		name = "rtl8192eefw.bin";
 	else if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
 	    URTWN_CHIP_UMC_A_CUT)
 		name = "rtl8192cfwU.bin";
@@ -3136,11 +3385,13 @@
 		return error;
 	}
 
+	len = fwlen;
 	ptr = fw;
 	hdr = (const struct r92c_fw_hdr *)ptr;
 	/* Check if there is a valid FW header and skip it. */
 	if ((le16toh(hdr->signature) >> 4) == 0x88c ||
 	    (le16toh(hdr->signature) >> 4) == 0x88e ||
+	    (le16toh(hdr->signature) >> 4) == 0x92e ||
 	    (le16toh(hdr->signature) >> 4) == 0x92c) {
 		DPRINTFN(DBG_INIT, ("%s: %s: FW V%d.%d %02d-%02d %02d:%02d\n",
 		    device_xname(sc->sc_dev), __func__,
@@ -3151,13 +3402,14 @@
 	}
 
 	if (urtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL) {
-		if (ISSET(sc->chip, URTWN_CHIP_88E))
+		if (ISSET(sc->chip, URTWN_CHIP_88E) ||
+		    ISSET(sc->chip, URTWN_CHIP_92EU))
 			urtwn_r88e_fw_reset(sc);
 		else
 			urtwn_fw_reset(sc);
-		urtwn_write_1(sc, R92C_MCUFWDL, 0);
 	}
-	if (!ISSET(sc->chip, URTWN_CHIP_88E)) {
+	if (!ISSET(sc->chip, URTWN_CHIP_88E) &&
+	    !ISSET(sc->chip, URTWN_CHIP_92EU)) {
 		urtwn_write_2(sc, R92C_SYS_FUNC_EN,
 		    urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
 		    R92C_SYS_FUNC_EN_CPUEN);
@@ -3171,8 +3423,9 @@
 
 	/* Reset the FWDL checksum. */
 	urtwn_write_1(sc, R92C_MCUFWDL,
-	    urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_CHKSUM_RPT);
+   	    urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_CHKSUM_RPT);
 
+	DELAY(50);
 	/* download firmware */
 	for (page = 0; len > 0; page++) {
 		mlen = MIN(len, R92C_FW_PAGE_SIZE);
@@ -3208,7 +3461,8 @@
 	reg = urtwn_read_4(sc, R92C_MCUFWDL);
 	reg = (reg & ~R92C_MCUFWDL_WINTINI_RDY) | R92C_MCUFWDL_RDY;
 	urtwn_write_4(sc, R92C_MCUFWDL, reg);
-	if (ISSET(sc->chip, URTWN_CHIP_88E))
+	if (ISSET(sc->chip, URTWN_CHIP_88E) ||
+	    ISSET(sc->chip, URTWN_CHIP_92EU))
 		urtwn_r88e_fw_reset(sc);
 	for (ntries = 0; ntries < 1000; ntries++) {
 		if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_WINTINI_RDY)
@@ -3390,6 +3644,10 @@
 		for (i = 0; i < __arraycount(rtl8188eu_mac); i++)
 			urtwn_write_1(sc, rtl8188eu_mac[i].reg,
 			    rtl8188eu_mac[i].val);
+ 	} else if (ISSET(sc->chip, URTWN_CHIP_92EU)) {
+		for (i = 0; i < __arraycount(rtl8192eu_mac); i++)
+			urtwn_write_1(sc, rtl8192eu_mac[i].reg,
+			    rtl8192eu_mac[i].val);
 	} else {
 		for (i = 0; i < __arraycount(rtl8192cu_mac); i++)
 			urtwn_write_1(sc, rtl8192cu_mac[i].reg,
@@ -3415,7 +3673,8 @@
 	    R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST |
 	    R92C_SYS_FUNC_EN_DIO_RF);
 
-	if (!ISSET(sc->chip, URTWN_CHIP_88E)) {
+	if (!ISSET(sc->chip, URTWN_CHIP_88E) &&
+	    !ISSET(sc->chip, URTWN_CHIP_92EU)) {
 		urtwn_write_1(sc, R92C_AFE_PLL_CTRL, 0x83);
 		urtwn_write_1(sc, R92C_AFE_PLL_CTRL + 1, 0xdb);
 	}
@@ -3426,7 +3685,8 @@
 	    R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD |
 	    R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB);
 
-	if (!ISSET(sc->chip, URTWN_CHIP_88E)) {
+	if (!ISSET(sc->chip, URTWN_CHIP_88E) &&
+	    !ISSET(sc->chip, URTWN_CHIP_92EU)) {
 		urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
 		urtwn_write_1(sc, 0x15, 0xe9);
 		urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
@@ -3435,6 +3695,8 @@
 	/* Select BB programming based on board type. */
 	if (ISSET(sc->chip, URTWN_CHIP_88E))
 		prog = &rtl8188eu_bb_prog;
+	else if (ISSET(sc->chip, URTWN_CHIP_92EU))
+		prog = &rtl8192eu_bb_prog;
 	else if (!(sc->chip & URTWN_CHIP_92C)) {
 		if (sc->board_type == R92C_BOARD_TYPE_MINICARD) {
 			prog = &rtl8188ce_bb_prog;
@@ -3455,13 +3717,13 @@
 		/* additional delay depend on registers */
 		switch (prog->regs[i]) {
 		case 0xfe:
-			usbd_delay_ms(sc->sc_udev, 50);
+			urtwn_delay_ms(sc, 50);
 			break;
 		case 0xfd:
-			usbd_delay_ms(sc->sc_udev, 5);
+			urtwn_delay_ms(sc, 5);
 			break;
 		case 0xfc:
-			usbd_delay_ms(sc->sc_udev, 1);
+			urtwn_delay_ms(sc, 1);
 			break;
 		case 0xfb:
 			DELAY(50);
@@ -3522,12 +3784,18 @@
 		DELAY(1);
 	}
 
-	if (ISSET(sc->chip, URTWN_CHIP_88E)) {
+	if (ISSET(sc->chip, URTWN_CHIP_88E) ||
+	    ISSET(sc->chip, URTWN_CHIP_92EU)) {
 		urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553422);
 		DELAY(1);
 		urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553420);
 		DELAY(1);
 
+		if (ISSET(sc->chip, URTWN_CHIP_92EU)) {
+			urtwn_write_2(sc, R92C_AFE_CTRL3, urtwn_read_2(sc,
+			    R92C_AFE_CTRL3));
+		}
+
 		crystalcap = sc->r88e_rom[0xb9];
 		if (crystalcap == 0xff)
 			crystalcap = 0x20;
@@ -3556,6 +3824,8 @@
 	/* Select RF programming based on board type. */
 	if (ISSET(sc->chip, URTWN_CHIP_88E))
 		prog = rtl8188eu_rf_prog;
+	else if (ISSET(sc->chip, URTWN_CHIP_92EU))
+		prog = rtl8192eu_rf_prog;
 	else if (!(sc->chip & URTWN_CHIP_92C)) {
 		if (sc->board_type == R92C_BOARD_TYPE_MINICARD) {
 			prog = rtl8188ce_rf_prog;
@@ -3578,23 +3848,23 @@
 		reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i));
 		reg |= 0x100000;
 		urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg);
-		DELAY(1);
+		DELAY(50);
 
 		/* Set RF_ENV output high. */
 		reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i));
 		reg |= 0x10;
 		urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg);
-		DELAY(1);
+		DELAY(50);
 
 		/* Set address and data lengths of RF registers. */
 		reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i));
 		reg &= ~R92C_HSSI_PARAM2_ADDR_LENGTH;
 		urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg);
-		DELAY(1);
+		DELAY(50);
 		reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i));
 		reg &= ~R92C_HSSI_PARAM2_DATA_LENGTH;
 		urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg);
-		DELAY(1);
+		DELAY(50);
 
 		/* Write RF initialization values for this chain. */
 		for (j = 0; j < prog[i].count; j++) {
@@ -3604,11 +3874,11 @@
 				 * These are fake RF registers offsets that
 				 * indicate a delay is required.
 				 */
-				usbd_delay_ms(sc->sc_udev, 50);
+				urtwn_delay_ms(sc, 50);
 				continue;
 			}
 			urtwn_rf_write(sc, i, prog[i].regs[j], prog[i].vals[j]);
-			DELAY(1);
+			DELAY(5);
 		}
 
 		/* Restore RF_ENV control type. */
@@ -3638,6 +3908,8 @@
 	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
 	KASSERT(mutex_owned(&sc->sc_write_mtx));
+	if (ISSET(sc->chip, URTWN_CHIP_92EU))
+		return;
 
 	for (idx = 0; idx < R92C_CAM_ENTRY_COUNT; idx++) {
 		content = (idx & 3)
@@ -4008,7 +4280,8 @@
 
 	for (i = 0; i < sc->ntxchains; i++) {
 		/* Compute per-rate Tx power values. */
-		if (ISSET(sc->chip, URTWN_CHIP_88E))
+		if (ISSET(sc->chip, URTWN_CHIP_88E) ||
+		    ISSET(sc->chip, URTWN_CHIP_92EU))
 			urtwn_r88e_get_txpower(sc, i, chan, ht40m, power);
 		else
 			urtwn_get_txpower(sc, i, chan, ht40m, power);
@@ -4091,7 +4364,8 @@
 		urtwn_bb_write(sc, R92C_FPGA1_RFMOD,
 		    urtwn_bb_read(sc, R92C_FPGA1_RFMOD) & ~R92C_RFMOD_40MHZ);
 
-		if (!ISSET(sc->chip, URTWN_CHIP_88E)) {
+		if (!ISSET(sc->chip, URTWN_CHIP_88E) &&
+		    !ISSET(sc->chip, URTWN_CHIP_92EU)) {
 			urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
 			    urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) |
 			    R92C_FPGA0_ANAPARAM2_CBW20);
@@ -4100,7 +4374,8 @@
 		/* Select 20MHz bandwidth. */
 		urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
 		    (sc->rf_chnlbw[0] & ~0xfff) | chan |
-		    (ISSET(sc->chip, URTWN_CHIP_88E) ?
+		    (ISSET(sc->chip, URTWN_CHIP_88E) ||
+		     ISSET(sc->chip, URTWN_CHIP_92EU) ?
 		      R88E_RF_CHNLBW_BW20 : R92C_RF_CHNLBW_BW20));
 	}
 }
@@ -4284,7 +4559,7 @@
 	    urtwn_rf_read(sc, 0, R92C_RF_CHNLBW) | R92C_RF_CHNLBW_LCSTART);
 
 	/* Give calibration the time to complete. */
-	usbd_delay_ms(sc->sc_udev, 100);
+	urtwn_delay_ms(sc, 100);
 
 	/* Restore configuration. */
 	if ((txmode & 0x70) != 0) {
@@ -4303,17 +4578,22 @@
 static void
 urtwn_temp_calib(struct urtwn_softc *sc)
 {
-	int temp;
+	int temp, t_meter_reg;
 
 	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
 	KASSERT(mutex_owned(&sc->sc_write_mtx));
 
+	if (!ISSET(sc->chip, URTWN_CHIP_92EU))
+		t_meter_reg = R92C_RF_T_METER;
+	else
+		t_meter_reg = R92E_RF_T_METER;
+
 	if (sc->thcal_state == 0) {
 		/* Start measuring temperature. */
 		DPRINTFN(DBG_RF, ("%s: %s: start measuring temperature\n",
 		    device_xname(sc->sc_dev), __func__));
-		urtwn_rf_write(sc, 0, R92C_RF_T_METER, 0x60);
+		urtwn_rf_write(sc, 0, t_meter_reg, 0x60);
 		sc->thcal_state = 1;
 		return;
 	}
@@ -4323,7 +4603,7 @@
 	temp = urtwn_rf_read(sc, 0, R92C_RF_T_METER) & 0x1f;
 	DPRINTFN(DBG_RF, ("%s: %s: temperature=%d\n", device_xname(sc->sc_dev),
 	    __func__, temp));
-	if (temp == 0)	/* Read failed, skip. */
+	if (temp == 0)		/* Read failed, skip. */
 		return;
 
 	/*
@@ -4398,15 +4678,20 @@
 	urtwn_write_1(sc, R92C_RX_DRVINFO_SZ, 4);
 
 	/* Init interrupts. */
-	if (ISSET(sc->chip, URTWN_CHIP_88E)) {
+	if (ISSET(sc->chip, URTWN_CHIP_88E) ||
+	     ISSET(sc->chip, URTWN_CHIP_92EU)) {
 		urtwn_write_4(sc, R88E_HISR, 0xffffffff);
 		urtwn_write_4(sc, R88E_HIMR, R88E_HIMR_CPWM | R88E_HIMR_CPWM2 |
 		    R88E_HIMR_TBDER | R88E_HIMR_PSTIMEOUT);
 		urtwn_write_4(sc, R88E_HIMRE, R88E_HIMRE_RXFOVW |
 		    R88E_HIMRE_TXFOVW | R88E_HIMRE_RXERR | R88E_HIMRE_TXERR);
-		urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
-		    urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
-		      R92C_USB_SPECIAL_OPTION_INT_BULK_SEL);
+		if (ISSET(sc->chip, URTWN_CHIP_88E)) {
+			urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
+			    urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
+			      R92C_USB_SPECIAL_OPTION_INT_BULK_SEL);
+		}
+		if (ISSET(sc->chip, URTWN_CHIP_92EU))
+			urtwn_write_1(sc, R92C_USB_HRPWM, 0);
 	} else {
 		urtwn_write_4(sc, R92C_HISR, 0xffffffff);
 		urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
@@ -4447,7 +4732,8 @@
 	urtwn_edca_init(sc);
 
 	/* Setup rate fallback. */
-	if (!ISSET(sc->chip, URTWN_CHIP_88E)) {
+	if (!ISSET(sc->chip, URTWN_CHIP_88E) &&
+	    !ISSET(sc->chip, URTWN_CHIP_92EU)) {
 		urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000);
 		urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404);
 		urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201);
@@ -4473,7 +4759,8 @@
 	    urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) &
 	      ~R92C_USB_SPECIAL_OPTION_AGG_EN);
 	urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
-	if (ISSET(sc->chip, URTWN_CHIP_88E))
+	if (ISSET(sc->chip, URTWN_CHIP_88E) ||
+	    ISSET(sc->chip, URTWN_CHIP_92EU))
 		urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH + 1, 4);
 	else
 		urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
@@ -4485,7 +4772,8 @@
 	urtwn_write_1(sc, R92C_BCNDMATIM, R92C_DMA_ATIME_INT_TIME);
 	urtwn_write_2(sc, R92C_BCNTCFG, 0x660f);
 
-	if (!ISSET(sc->chip, URTWN_CHIP_88E)) {
+	if (!ISSET(sc->chip, URTWN_CHIP_88E) &&
+	    !ISSET(sc->chip, URTWN_CHIP_92EU)) {
 		/* Setup AMPDU aggregation. */
 		urtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631);	/* MCS7~0 */
 		urtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
@@ -4512,7 +4800,8 @@
 	urtwn_bb_init(sc);
 	urtwn_rf_init(sc);
 
-	if (ISSET(sc->chip, URTWN_CHIP_88E)) {
+	if (ISSET(sc->chip, URTWN_CHIP_88E) ||
+	    ISSET(sc->chip, URTWN_CHIP_92EU)) {
 		urtwn_write_2(sc, R92C_CR,
 		    urtwn_read_2(sc, R92C_CR) | R92C_CR_MACTXEN |
 		      R92C_CR_MACRXEN);
@@ -4539,7 +4828,8 @@
 	/* Perform LC calibration. */
 	urtwn_lc_calib(sc);
 
-	if (!ISSET(sc->chip, URTWN_CHIP_88E)) {
+	if (!ISSET(sc->chip, URTWN_CHIP_88E) &&
+	    !ISSET(sc->chip, URTWN_CHIP_92EU)) {
 		/* Fix USB interference issue. */
 		urtwn_write_1(sc, 0xfe40, 0xe0);
 		urtwn_write_1(sc, 0xfe41, 0x8d);
@@ -4549,7 +4839,8 @@
 		urtwn_pa_bias_init(sc);
 	}
 
-	if (!(sc->chip & (URTWN_CHIP_92C | URTWN_CHIP_92C_1T2R))) {
+	if (!(sc->chip & (URTWN_CHIP_92C | URTWN_CHIP_92C_1T2R)) ||
+	    !(sc->chip & URTWN_CHIP_92EU)) {
 		/* 1T1R */
 		urtwn_bb_write(sc, R92C_FPGA0_RFPARAM(0),
 		    urtwn_bb_read(sc, R92C_FPGA0_RFPARAM(0)) | __BIT(13));
@@ -4560,26 +4851,31 @@
 	    urtwn_read_1(sc, R92C_GPIO_MUXCFG) & ~R92C_GPIO_MUXCFG_ENBT);
 
 	/* Fix for lower temperature. */
-	if (!ISSET(sc->chip, URTWN_CHIP_88E))
+	if (!ISSET(sc->chip, URTWN_CHIP_88E) &&
+	    !ISSET(sc->chip, URTWN_CHIP_92EU))
 		urtwn_write_1(sc, 0x15, 0xe9);
 
 	/* Set default channel. */
 	urtwn_set_chan(sc, ic->ic_curchan, IEEE80211_HTINFO_2NDCHAN_NONE);
 
 	/* Queue Rx xfers. */
-	for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
-		data = &sc->rx_data[i];
-		usbd_setup_xfer(data->xfer, data, data->buf, URTWN_RXBUFSZ,
-		    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtwn_rxeof);
-		error = usbd_transfer(data->xfer);
-		if (__predict_false(error != USBD_NORMAL_COMPLETION &&
-		    error != USBD_IN_PROGRESS))
-			goto fail;
+	for (size_t j = 0; j < sc->rx_npipe; j++) {
+		for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
+			data = &sc->rx_data[j][i];
+			usbd_setup_xfer(data->xfer, data, data->buf,
+			    URTWN_RXBUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
+			    urtwn_rxeof);
+			error = usbd_transfer(data->xfer);
+			if (__predict_false(error != USBD_NORMAL_COMPLETION &&
+			    error != USBD_IN_PROGRESS))
+				goto fail;
+		}
 	}
 
 	/* We're ready to go. */
 	ifp->if_flags &= ~IFF_OACTIVE;
 	ifp->if_flags |= IFF_RUNNING;
+	sc->sc_running = true;
 
 	mutex_exit(&sc->sc_write_mtx);
 
@@ -4621,18 +4917,22 @@
 	callout_stop(&sc->sc_calib_to);
 
 	/* Abort Tx. */
-	for (i = 0; i < R92C_MAX_EPOUT; i++) {
+	for (i = 0; i < sc->tx_npipe; i++) {
 		if (sc->tx_pipe[i] != NULL)
 			usbd_abort_pipe(sc->tx_pipe[i]);
 	}
 
 	/* Stop Rx pipe. */
-	usbd_abort_pipe(sc->rx_pipe);
+	for (i = 0; i < sc->rx_npipe; i++) {
+		if (sc->rx_pipe[i] != NULL)
+			usbd_abort_pipe(sc->rx_pipe[i]);
+	}
 
 	/* Free Tx/Rx buffers. */
 	urtwn_free_tx_list(sc);
 	urtwn_free_rx_list(sc);
 
+	sc->sc_running = false;
 	if (disable)
 		urtwn_chip_stop(sc);
 }
@@ -4659,6 +4959,9 @@
 
 	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
+	if (ISSET(sc->chip, URTWN_CHIP_92EU))
+		return;
+
 	mutex_enter(&sc->sc_write_mtx);
 
 	/*
@@ -4688,7 +4991,8 @@
 		urtwn_write_1(sc, R92C_MCUFWDL, 0);
 		/* If firmware in ram code, do reset */
 		if (ISSET(sc->sc_flags, URTWN_FLAG_FWREADY)) {
-			if (ISSET(sc->chip, URTWN_CHIP_88E))
+			if (ISSET(sc->chip, URTWN_CHIP_88E) ||
+			    ISSET(sc->chip, URTWN_CHIP_92EU))
 				urtwn_r88e_fw_reset(sc);
 			else
 				urtwn_fw_reset(sc);
@@ -4767,6 +5071,15 @@
 	urtwn_write_1(sc, R92C_RSV_CTRL, 0x0E);
 
 	mutex_exit(&sc->sc_write_mtx);
+}
+
+static void
+urtwn_delay_ms(struct urtwn_softc *sc, int ms)
+{
+	if (sc->sc_running == false)
+		DELAY(ms * 1000);
+	else
+		usbd_delay_ms(sc->sc_udev, ms);
 }
 
 MODULE(MODULE_CLASS_DRIVER, if_urtwn, "bpf");

cvs diff -r1.3 -r1.4 src/sys/dev/usb/Attic/if_urtwn_data.h (expand / switch to context diff)
--- src/sys/dev/usb/Attic/if_urtwn_data.h 2014/07/20 13:25:23 1.3
+++ src/sys/dev/usb/Attic/if_urtwn_data.h 2016/10/12 03:23:29 1.4
@@ -1,8 +1,9 @@
-/*	$NetBSD: if_urtwn_data.h,v 1.3 2014/07/20 13:25:23 nonaka Exp $	*/
+/*	$NetBSD: if_urtwn_data.h,v 1.4 2016/10/12 03:23:29 nat Exp $	*/
 /*	$OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $	*/
 
 /*-
  * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -23,7 +24,34 @@
 static const struct {
 	uint16_t	reg;
 	uint8_t		val;
-} rtl8188eu_mac[] = {
+} rtl8192eu_mac[]={
+	{ 0x011, 0xeb }, { 0x012, 0x07 }, { 0x014, 0x75 }, { 0x303, 0xa7 },
+	{ 0x428, 0x0a }, { 0x429, 0x10 }, { 0x430, 0x00 }, { 0x431, 0x00 },
+	{ 0x432, 0x00 }, { 0x433, 0x01 }, { 0x434, 0x04 }, { 0x435, 0x05 },
+	{ 0x436, 0x07 }, { 0x437, 0x08 }, { 0x43c, 0x04 }, { 0x43d, 0x05 },
+	{ 0x43e, 0x07 }, { 0x43f, 0x08 }, { 0x440, 0x5d }, { 0x441, 0x01 },
+	{ 0x442, 0x00 }, { 0x444, 0x10 }, { 0x445, 0x00 }, { 0x446, 0x00 },
+	{ 0x447, 0x00 }, { 0x448, 0x00 }, { 0x449, 0xf0 }, { 0x44a, 0x0f },
+	{ 0x44b, 0x3e }, { 0x44c, 0x10 }, { 0x44d, 0x00 }, { 0x44e, 0x00 },
+	{ 0x44f, 0x00 }, { 0x450, 0x00 }, { 0x451, 0xf0 }, { 0x452, 0x0f },
+	{ 0x453, 0x00 }, { 0x456, 0x5e }, { 0x460, 0x66 }, { 0x461, 0x66 },
+	{ 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 }, { 0x516, 0x0a },
+	{ 0x525, 0x4f }, { 0x540, 0x12 }, { 0x541, 0x64 }, { 0x550, 0x10 },
+	{ 0x551, 0x10 }, { 0x559, 0x02 }, { 0x55c, 0x50 }, { 0x55d, 0xff },
+	{ 0x605, 0x30 }, { 0x608, 0x0e }, { 0x609, 0x2a }, { 0x620, 0xff },
+	{ 0x621, 0xff }, { 0x622, 0xff }, { 0x623, 0xff }, { 0x624, 0xff },
+	{ 0x625, 0xff }, { 0x626, 0xff }, { 0x627, 0xff }, { 0x638, 0x50 },
+	{ 0x63c, 0x0a }, { 0x63d, 0x0a }, { 0x63e, 0x0e }, { 0x63f, 0x0e },
+	{ 0x640, 0x40 }, { 0x642, 0x40 }, { 0x643, 0x00 }, { 0x652, 0xc8 },
+	{ 0x66e, 0x05 }, { 0x700, 0x21 }, { 0x701, 0x43 }, { 0x702, 0x65 },
+	{ 0x703, 0x87 }, { 0x708, 0x21 }, { 0x709, 0x43 }, { 0x70a, 0x65 },
+	{ 0x70b, 0x87 }, 
+}, 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 },
@@ -492,6 +520,120 @@
 };
 
 /*
+ * RTL819E.
+ */
+static const uint16_t rtl8192eu_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, 0x900,
+	0x904, 0x908, 0x90c, 0x910, 0x914, 0x918, 0x91c, 0x924,
+	0x928, 0x92c, 0x930, 0x934, 0x938, 0x93c, 0x940, 0x944,
+	0x94c, 0xa00, 0xa04, 0xa08, 0xa0c, 0xa10, 0xa14, 0xa18,
+	0xa1c, 0xa20, 0xa24, 0xa28, 0xa2c, 0xa70, 0xa74, 0xa78,
+	0xa7c, 0xa80, 0xb38, 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, 0xd1c, 0xd2c,
+	0xd30, 0xd34, 0xd38, 0xd3c, 0xd40, 0xd44, 0xd48, 0xd4c,
+	0xd50, 0xd54, 0xd58, 0xd5c, 0xd60, 0xd64, 0xd68, 0xd6c,
+	0xd70, 0xd74, 0xd78, 0xd80, 0xd84, 0xd88, 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, 0xee4, 0xee8, 0xf14, 0xf4c, 0xf00, 
+};
+
+static const uint32_t rtl8192eu_bb_vals[] = {
+	0x80040000, 0x00000003, 0x0000fc00, 0x0000000a, 0x10001331,
+	0x020c3d10, 0x02220385, 0x00000000, 0x01000100, 0x00390204,
+	0x01000100, 0x00390204, 0x32323232, 0x30303030, 0x30303030,
+	0x30303030, 0x00010000, 0x00010000, 0x28282828, 0x28282828,
+	0x00000000, 0x00000000, 0x009a009a, 0x01000014, 0x66f60000,
+	0x061f0000, 0x30303030, 0x30303030, 0x00000000, 0x55004200,
+	0x08080808, 0x00000000, 0xb0000c1c, 0x00000001, 0x00000000,
+	0xcc0000c0, 0x00000800, 0xfffffffe, 0x40302010, 0x00000000,
+	0x00000023, 0x00000000, 0x81121313, 0x806c0001, 0x00000001,
+	0x00000000, 0x00010000, 0x00000001, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000008, 0x00d0c7c8, 0x81ff000c, 0x8c838300,
+	0x2e68120f, 0x95009b78, 0x1114d028, 0x00881117, 0x89140f00,
+	0x1a1b0000, 0x090e1317, 0x00000204, 0x00d30000, 0x101fff00,
+	0x00000007, 0x00000900, 0x225b0606, 0x218075b1, 0x00000000,
+	0x48071d40, 0x03a05633, 0x000000e4, 0x6c6c6c6c, 0x08800000,
+	0x40000100, 0x08800000, 0x40000100, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x69e9ac47, 0x469652af, 0x49795994,
+	0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f,
+	0x00340020, 0x0080801f, 0x00000020, 0x00248492, 0x00000000,
+	0x7112848b, 0x47c00bff, 0x00000036, 0x00000600, 0x02013169,
+	0x0000001f, 0x00b91612, 0x40000100, 0x21f60000, 0x40000100,
+	0xa0e40000, 0x00121820, 0x00000000, 0x00121820, 0x00007f7f,
+	0x00000000, 0x000300a0, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x28000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x64b22427,
+	0x00766932, 0x00222222, 0x00040000, 0x77644302, 0x2f97d40c,
+	0x00080740, 0x00020403, 0x0000907f, 0x20010201, 0xa0633333,
+	0x3333bc43, 0x7a8f5b6b, 0x0000007f, 0xcc979975, 0x00000000,
+	0x80608000, 0x00000000, 0x00127353, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x6437140a, 0x00000000, 0x00000282,
+	0x30032064, 0x4653de68, 0x04518a3c, 0x00002101, 0x2a201c16,
+	0x1812362e, 0x322c2220, 0x000e3c24, 0x01081008, 0x00000800,
+	0xf0b50000, 0x30303030, 0x30303030, 0x03903030, 0x30303030,
+	0x30303030, 0x30303030, 0x30303030, 0x00000000, 0x1000dc1f,
+	0x10008c1f, 0x02140102, 0x681604c2, 0x01007c00, 0x01004800,
+	0xfb000000, 0x000028d1, 0x1000dc1f, 0x10008c1f, 0x02140102,
+	0x28160d05, 0x00000008, 0x0fc05656, 0x03c09696, 0x03c09696,
+	0x0c005656, 0x0c005656, 0x0c005656, 0x0c005656, 0x03c09696,
+	0x0c005656, 0x03c09696, 0x03c09696, 0x03c09696, 0x03c09696,
+	0x0000d6d6, 0x0000d6d6, 0x0fc01616, 0xb0000c1c, 0x00000001,
+	0x00000003, 0x00000000, 0x00000300,
+};
+
+static const uint32_t rtl8192eu_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, 0xc81a0001, 0xc71b0001, 0xc61c0001, 0x071d0001,
+	0x061e0001, 0x051f0001, 0x04200001, 0x03210001, 0xaa220001,
+	0xa9230001, 0xa8240001, 0xa7250001, 0xa6260001, 0x85270001,
+	0x84280001, 0x83290001, 0x252a0001, 0x242b0001, 0x232c0001,
+	0x222d0001, 0x672e0001, 0x662f0001, 0x65300001, 0x64310001,
+	0x63320001, 0x62330001, 0x61340001, 0x45350001, 0x44360001,
+	0x43370001, 0x42380001, 0x41390001, 0x403a0001, 0x403b0001,
+	0x403c0001, 0x403d0001, 0x403e0001, 0x403f0001, 0xfb400001,
+	0xfb410001, 0xfb420001, 0xfb430001, 0xfb440001, 0xfb450001,
+	0xfa460001, 0xf9470001, 0xf8480001, 0xf7490001, 0xf64a0001,
+	0xf54b0001, 0xf44c0001, 0xf34d0001, 0xf24e0001, 0xf14f0001,
+	0xf0500001, 0xef510001, 0xee520001, 0xed530001, 0xec540001,
+	0xeb550001, 0xea560001, 0xe9570001, 0xe8580001, 0xe7590001,
+	0xe65a0001, 0xe55b0001, 0xe45c0001, 0xe35d0001, 0xe25e0001,
+	0xe15f0001, 0x8a600001, 0x89610001, 0x88620001, 0x87630001,
+	0x86640001, 0x85650001, 0x84660001, 0x83670001, 0x82680001,
+	0x6b690001, 0x6a6a0001, 0x696b0001, 0x686c0001, 0x676d0001,
+	0x666e0001, 0x656f0001, 0x64700001, 0x63710001, 0x62720001,
+	0x61730001, 0x49740001, 0x48750001, 0x47760001, 0x46770001,
+	0x45780001, 0x44790001, 0x437a0001, 0x427b0001, 0x417c0001,
+	0x407d0001, 0x407e0001, 0x407f0001,
+};
+
+static const struct urtwn_bb_prog rtl8192eu_bb_prog = {
+	__arraycount(rtl8192eu_bb_regs),
+	rtl8192eu_bb_regs,
+	rtl8192eu_bb_vals,
+	__arraycount(rtl8192eu_agc_vals),
+	rtl8192eu_agc_vals
+};
+
+/*
  * RTL8188RU.
  */
 static const uint16_t rtl8188ru_bb_regs[] = {
@@ -751,6 +893,83 @@
 		__arraycount(rtl8192ce_rf1_regs),
 		rtl8192ce_rf1_regs,
 		rtl8188cu_rf_vals
+	}
+};
+
+/*
+ * RTL8192EU.
+ */
+static const uint8_t rtl8192eu_rf_regs[] = {
+	0x7f, 0x81, 0x00, 0x08, 0x18, 0x19, 0x1b, 0x1e, 0x1f, 0x2f,
+	0x3f, 0x42, 0x57, 0x58, 0x67, 0x83, 0xb0, 0xb1, 0xb2, 0xb4,
+	0xb5, 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,
+	0x18, 0x5a, 0x19, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
+	0x34, 0x34, 0x34, 0x34, 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, 0x3b, 0x3b,
+	0xef, 0xfe, 0x18, 0xfe, 0xfe, 0xfe, 0xfe, 0x1e, 0x1f, 0x00, 
+};
+
+static const uint32_t rtl8192eu_rf_vals[] = {
+	0x00082, 0x3fc00, 0x30000, 0x08400, 0x00407, 0x00012, 0x00064,
+	0x80009, 0x00880, 0x1a060, 0x00000, 0x060c0, 0xd0000, 0xbe180,
+	0x01552, 0x00000, 0xff9f1, 0x55418, 0x8cc00, 0x43083, 0x08166,
+	0x0803e, 0x1c69f, 0x0407f, 0x80001, 0x40001, 0x00400, 0xc0000,
+	0x02400, 0x00009, 0x40c91, 0x99999, 0x000a3, 0x88820, 0x76c06,
+	0x00000, 0x80000, 0x00180, 0x001a0, 0x69545, 0x7e45e, 0x00071,
+	0x51ff3, 0x000a8, 0x001e2, 0x002a8, 0x01c24, 0x09c24, 0x11c24,
+	0x19c24, 0x00c07, 0x48000, 0x739d0, 0x0a093, 0x0908f, 0x0808c,
+	0x0704d, 0x0604a, 0x05047, 0x0400a, 0x03007, 0x02004, 0x01001,
+	0x00000, 0x0add7, 0x09dd4, 0x08dd1, 0x07dce, 0x06dcb, 0x05dc8,
+	0x04dc5, 0x034cc, 0x0244f, 0x0144c, 0x00014, 0x30159, 0x68180,
+	0x0014e, 0x48e00, 0x65540, 0x88000, 0x020a0, 0xf07b0, 0xf02b0,
+	0xef7b0, 0xd4fb0, 0xcf060, 0xb0090, 0xa0080, 0x90080, 0x8f780,
+	0x787b0, 0x78730, 0x60fb0, 0x5ffa0, 0x40620, 0x37090, 0x20080,
+	0x1f060, 0x0ffb0, 0x000a0, 0x00000, 0x0fc07, 0x00000, 0x00000,
+	0x00000, 0x00000, 0x00001, 0x80000, 0x33e70, 
+};
+
+static const uint8_t rtl8192eu_rf2_regs[] = {
+	0x7f, 0x81, 0x00, 0x08, 0x18, 0x19, 0x1b, 0x1e, 0x1f, 0x2f,
+	0x3f, 0x42, 0x57, 0x58, 0x67, 0x7f, 0x81, 0x83, 0xdf, 0xef,
+	0x51, 0x52, 0x53, 0x56, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36,
+	0x36, 0x18, 0x5a, 0x19, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
+	0x34, 0x34, 0x34, 0x34, 0x34, 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, 0x3b,
+	0x3b, 0xef, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x1e, 0x1f, 0x00, 
+};
+
+static const uint32_t rtl8192eu_rf2_vals[] = {
+	0x00082, 0x3fc00, 0x30000, 0x08400, 0x00407, 0x00012, 0x00064,
+	0x80009, 0x00880, 0x1a060, 0x00000, 0x060c0, 0xd0000, 0xbe180,
+	0x01552, 0x00082, 0x3f000, 0x00000, 0x00180, 0x001a0, 0x69545,
+	0x7e42e, 0x00071, 0x51ff3, 0x000a8, 0x001e0, 0x002a8, 0x01ca8,
+	0x09c24, 0x11c24, 0x19c24, 0x00c07, 0x48000, 0x739d0, 0x0a093,
+	0x0908f, 0x0808c, 0x0704d, 0x0604a, 0x05047, 0x0400a, 0x03007,
+	0x02004, 0x01001, 0x00000, 0x0add7, 0x09dd4, 0x08dd1, 0x07dce,
+	0x06dcb, 0x05dc8, 0x04dc5, 0x034cc, 0x0244f, 0x0144c, 0x00014,
+	0x30159, 0x68180, 0x000ce, 0x48a00, 0x65540, 0x88000, 0x020a0,
+	0xf07b0, 0xf02b0, 0xef7b0, 0xd4fb0, 0xcf060, 0xb0090, 0xa0080,
+	0x90080, 0x8f780, 0x787b0, 0x78730, 0x60fb0, 0x5ffa0, 0x40620,
+	0x37090, 0x20080, 0x1f060, 0x0ffb0, 0x000a0, 0x10159, 0x00000,
+	0x00000, 0x00000, 0x00000, 0x00001, 0x80000, 0x33e70, 
+};
+
+static const struct urtwn_rf_prog rtl8192eu_rf_prog[] = {
+	{
+		__arraycount(rtl8192eu_rf_regs),
+		rtl8192eu_rf_regs,
+		rtl8192eu_rf_vals
+	},
+	{
+		__arraycount(rtl8192eu_rf2_regs),
+		rtl8192eu_rf2_regs,
+		rtl8192eu_rf2_vals
 	}
 };
 

cvs diff -r1.9 -r1.10 src/sys/dev/usb/if_urtwnreg.h (expand / switch to context diff)
--- src/sys/dev/usb/if_urtwnreg.h 2016/10/12 02:56:45 1.9
+++ src/sys/dev/usb/if_urtwnreg.h 2016/10/12 03:23:29 1.10
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_urtwnreg.h,v 1.9 2016/10/12 02:56:45 nat Exp $	*/
+/*	$NetBSD: if_urtwnreg.h,v 1.10 2016/10/12 03:23:29 nat Exp $	*/
 /*	$OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $	*/
 
 /*-
@@ -23,6 +23,7 @@
 
 /* Maximum number of output pipes is 3. */
 #define R92C_MAX_EPOUT	3
+#define R92C_MAX_EPIN	3
 
 #define R92C_MAX_TX_PWR	0x3f
 
@@ -33,6 +34,10 @@
 #define R88E_TXPKTBUF_COUNT	177
 #define R88E_TX_PAGE_COUNT	169
 #define R88E_TX_PAGE_BOUNDARY	(R88E_TX_PAGE_COUNT + 1)
+#define R92E_TXPKTBUF_COUNT	256
+#define R92E_TX_PAGE_COUNT	243
+#define R92E_TX_PAGE_BOUNDARY	(R92E_TX_PAGE_COUNT + 1)
+#define R92C_TXDESC_SUMSIZE	32
 
 #define R92C_H2C_NBOX	4
 
@@ -49,6 +54,7 @@
 #define R92C_SYS_CLKR			0x008
 #define R92C_AFE_MISC			0x010
 #define R92C_SPS0_CTRL			0x011
+#define R92C_SYS_SWR_CTRL2		0x014
 #define R92C_SPS_OCP_CFG		0x018
 #define R92C_RSV_CTRL			0x01c
 #define R92C_RF_CTRL			0x01f
@@ -58,6 +64,7 @@
 #define R92C_LPLDO_CTRL			0x023
 #define R92C_AFE_XTAL_CTRL		0x024
 #define R92C_AFE_PLL_CTRL		0x028
+#define R92C_AFE_CTRL3			0x02c
 #define R92C_EFUSE_CTRL			0x030
 #define R92C_EFUSE_TEST			0x034
 #define R92C_PWR_DATA			0x038
@@ -76,6 +83,7 @@
 #define R92C_FSISR			0x054
 #define R92C_HSIMR			0x058
 #define R92C_HSISR			0x05c
+#define R92C_AFE_CTRL4			0x078
 #define R92C_MCUFWDL			0x080
 #define R92C_HMEBOX_EXT(idx)		(0x088 + (idx) * 2)
 #define R88E_HIMR			0x0b0
@@ -125,6 +133,7 @@
 #define R92C_BB_ACCESS_CTRL		0x1e8
 #define R92C_BB_ACCESS_DATA		0x1ec
 #define R88E_HMEBOX_EXT(idx)		(0x1f0 + (idx) * 4)
+#define R92E_HMEBOX_EXT(idx)		(0x1f0 + (idx) * 4)
 /* Tx DMA Configuration. */
 #define R92C_RQPN			0x200
 #define R92C_FIFOPAGE			0x204
@@ -482,6 +491,7 @@
 #define R92C_LLT_INIT_OP_S		30
 #define R92C_LLT_INIT_OP_NO_ACTIVE	0
 #define R92C_LLT_INIT_OP_WRITE		1
+#define R92C_LLT_INIT_OP_READ		2
 
 /* Bits for R92C_RQPN. */
 #define R92C_RQPN_HPQ_M		0x000000ff
@@ -592,7 +602,7 @@
 #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_FPGA0_XA_HSSIPARAM1	0x820
+#define R92C_FPGA0_XA_HSSIPARAM1	0x820
 #define R92C_TXAGC_B_CCK1_55_MCS32	0x838
 #define R92C_FPGA0_XCD_SWITCHCTL	0x85c
 #define R92C_TXAGC_B_CCK11_A_CCK2_11	0x86c
@@ -647,7 +657,6 @@
 #define R92C_SLEEP 			0xee0
 #define R92C_PMPD_ANAEN			0xeec
 
-
 /* Bits for R92C_FPGA[01]_RFMOD. */
 #define R92C_RFMOD_40MHZ	0x00000001
 #define R92C_RFMOD_JAPAN	0x00000002
@@ -801,6 +810,9 @@
 /* Bits for R92C_RD_CTRL. */
 #define R92C_RD_CTRL_DIS_EDCA_CNT_DWN	__BIT(11)
 
+/* Bits for R92C_INIDATA_RATE_SEL. */
+#define R92C_RATE_SHORTGI	__BIT(6)
+
 /*
  * Firmware base address.
  */
@@ -876,6 +888,7 @@
 #define R92C_CAM_MACLO_S	16
 
 /* Rate adaptation modes. */
+#define R92C_RAID_11BGN 0
 #define R92C_RAID_11GN	1
 #define R92C_RAID_11N	3
 #define R92C_RAID_11BG	4
@@ -942,6 +955,7 @@
 #define R92C_CMD_MACID_PS_MODE		7
 #define R92C_CMD_P2P_PS_OFFLOAD		8
 #define R92C_CMD_SELECTIVE_SUSPEND	9
+#define R92C_CMD_USB_SUSPEND		43
 #define R92C_CMD_FLAG_EXT		0x80
 
 	uint8_t	msg[5];
@@ -961,8 +975,52 @@
 #define URTWN_MACID_BSS		0
 #define URTWN_MACID_BC		4	/* Broadcast. */
 #define URTWN_MACID_VALID	0x80
+#define URTWN_MACID_SHORTGI	0x20
 } __packed;
 
+/* Structure for R92C_CMD_SET_PWRMODE. */
+struct r92c_fw_cmd_setpwrmode {
+	uint8_t	mode;
+	uint8_t	smartps;
+	uint8_t	bcn_time;	/* 100ms increments */
+} __packed;
+
+#define R92E_CMD_KEEP_ALIVE	0x03
+#define R92E_CMD_SET_PWRMODE	0x20
+#define R92E_CMD_RSSI_REPORT	0x42
+
+/* Structure for R92E_CMD_KEEP_ALIVE. */
+struct r92e_fw_cmd_keepalive {
+	uint8_t mode;
+	uint8_t period;
+} __packed;
+
+/* Structure for R92E_CMD_SET_PWRMODE. */
+struct r92e_fw_cmd_setpwrmode {
+	uint8_t mode;
+#define FWMODE_ACTIVE		0
+#define FWMODE_LOW_POWER	1
+#define FWMODE_WMMPS		2
+	uint8_t	smartps;
+#define SRTPS_LOW_POWER		0
+#define SRTPS_POLL		0x10
+#define SRTPS_WMMPS		0x20
+	uint8_t awake_int;	/* 100ms increments. */
+	uint8_t	all_queue_apsd;
+	uint8_t	pwr_state;
+#define PS_RFOFF		0x0
+#define PS_RFON			0x4
+#define PS_ALLON		0xc
+} __packed;
+
+/* Structure for R92E_CMD_RSSI_REPORT. */
+struct r92e_fw_cmd_rssi {
+	uint8_t	macid;
+	uint8_t	reserved;
+	uint8_t	pwdb;
+	uint8_t	reserved2;
+} __packed;
+
 /*
  * RTL8192CU ROM image.
  */
@@ -1116,7 +1174,9 @@
 #define R88E_TXDW2_AGGBK	0x00010000
 
 	uint16_t	txdw3;
+#define R92E_TXDW3_AGGBK	0x00000100
 	uint16_t	txdseq;
+#define R92C_HWSEQ_EN		0x00008000
 
 	uint32_t	txdw4;
 #define R92C_TXDW4_RTSRATE_M	0x0000003f
@@ -1143,7 +1203,28 @@
 	uint32_t	txdw6;
 	uint16_t	txdsum;
 	uint16_t	pad;
+	uint32_t	txdw7;
+	uint16_t	txdseq2;
+#define R92E_HWSEQ_SHIFT	11
+#define R92E_HWSEQ_MASK		0x00000fffff
+
+	uint16_t	txdw8;
 } __packed __aligned(4);
+#define R92E_RF_T_METER		0x042
+#define R92E_STBC_SETTING	0x04c4
+#define R92E_SYS_CFG1_8192E	0x00f0
+#define R92E_LDO_SWR_CTRL	0x007C
+#define R92E_AUTO_LLT		0x224
+#define R92E_AUTO_LLT_EN	__BIT(16)
+#define R92E_RSV_MIO_EN		0x0100
+#define R92E_LEDSON		0x60
+
+/* Bits for SYS_CFG1_8192E. */
+#define R92E_SPSLDO_SEL		__BIT(24)
+
+/* Values for R92C_CMD_USB_SUSPEND. */
+#define USB_RESUME		0
+#define USB_SLEEP		1
 
 /* Values for IQ calibration. */
 #define R92C_IQK_TRXPATHENA	0x5600

cvs diff -r1.9 -r1.10 src/sys/dev/usb/if_urtwnvar.h (expand / switch to context diff)
--- src/sys/dev/usb/if_urtwnvar.h 2016/04/23 10:15:32 1.9
+++ src/sys/dev/usb/if_urtwnvar.h 2016/10/12 03:23:29 1.10
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_urtwnvar.h,v 1.9 2016/04/23 10:15:32 skrll Exp $	*/
+/*	$NetBSD: if_urtwnvar.h,v 1.10 2016/10/12 03:23:29 nat Exp $	*/
 /*	$OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $	*/
 
 /*-
@@ -66,9 +66,11 @@
 struct urtwn_softc;
 
 struct urtwn_rx_data {
-	struct urtwn_softc	*sc;
-	struct usbd_xfer	*xfer;
-	uint8_t			*buf;
+	struct urtwn_softc		*sc;
+	size_t				pidx;
+	struct usbd_xfer		*xfer;
+	uint8_t				*buf;
+	TAILQ_ENTRY(urtwn_rx_data)	next;
 };
 
 struct urtwn_tx_data {
@@ -129,9 +131,10 @@
 	kmutex_t			sc_task_mtx;
 	kmutex_t			sc_fwcmd_mtx;
 	kmutex_t			sc_tx_mtx;
+	kmutex_t			sc_rx_mtx;
 	kmutex_t			sc_write_mtx;
 
-	struct usbd_pipe *		rx_pipe;
+	struct usbd_pipe *		rx_pipe[R92C_MAX_EPIN];
 	int				rx_npipe;
 	struct usbd_pipe *		tx_pipe[R92C_MAX_EPOUT];
 	int				tx_npipe;
@@ -143,6 +146,7 @@
 #define URTWN_CHIP_UMC		0x04
 #define URTWN_CHIP_UMC_A_CUT	0x08
 #define URTWN_CHIP_88E		0x10
+#define URTWN_CHIP_92EU		0x20
 
 	void				(*sc_rf_write)(struct urtwn_softc *,
 					    int, uint8_t, uint32_t);
@@ -164,12 +168,13 @@
 
 	struct urtwn_host_cmd_ring	cmdq;
 	int				fwcur;
-	struct urtwn_rx_data		rx_data[URTWN_RX_LIST_COUNT];
+	struct urtwn_rx_data		rx_data[R92C_MAX_EPIN][URTWN_RX_LIST_COUNT];
 	struct urtwn_tx_data		tx_data[R92C_MAX_EPOUT][URTWN_TX_LIST_COUNT];
 	TAILQ_HEAD(, urtwn_tx_data)	tx_free_list[R92C_MAX_EPOUT];
+	TAILQ_HEAD(, urtwn_rx_data)	rx_free_list[R92C_MAX_EPIN];
 
 	struct r92c_rom			rom;
-	uint8_t				r88e_rom[512];
+	uint8_t				r88e_rom[4096];
 	uint8_t				cck_tx_pwr[6];
 	uint8_t				ht40_tx_pwr[5];
 	int8_t				bw20_tx_pwr_diff;
@@ -190,6 +195,7 @@
 	}				sc_txtapu;
 #define sc_txtap	sc_txtapu.th
 	int				sc_txtap_len;
+	bool				sc_running;
 };
 
 #endif /* _IF_URTWNVAR_H_ */