Module Name: src Committed By: nat Date: Wed Oct 12 03:23:29 UTC 2016
Modified Files: src/share/man/man4: urtwn.4 src/sys/dev/usb: if_urtwn.c if_urtwn_data.h if_urtwnreg.h if_urtwnvar.h Log Message: Add support for Realtek 8192EU. OK christos@ To generate a diff of this commit: cvs rdiff -u -r1.14 -r1.15 src/share/man/man4/urtwn.4 cvs rdiff -u -r1.48 -r1.49 src/sys/dev/usb/if_urtwn.c cvs rdiff -u -r1.3 -r1.4 src/sys/dev/usb/if_urtwn_data.h cvs rdiff -u -r1.9 -r1.10 src/sys/dev/usb/if_urtwnreg.h \ src/sys/dev/usb/if_urtwnvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/share/man/man4/urtwn.4 diff -u src/share/man/man4/urtwn.4:1.14 src/share/man/man4/urtwn.4:1.15 --- src/share/man/man4/urtwn.4:1.14 Fri Jul 25 15:07:03 2014 +++ src/share/man/man4/urtwn.4 Wed Oct 12 03:23:29 2016 @@ -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.bergam...@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 RTL8188RU is a high-power variant of 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 @@ which are loaded when an interface is at .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: Index: src/sys/dev/usb/if_urtwn.c diff -u src/sys/dev/usb/if_urtwn.c:1.48 src/sys/dev/usb/if_urtwn.c:1.49 --- src/sys/dev/usb/if_urtwn.c:1.48 Wed Oct 12 02:56:45 2016 +++ src/sys/dev/usb/if_urtwn.c Wed Oct 12 03:23:29 2016 @@ -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.bergam...@free.fr> * Copyright (c) 2014 Kevin Lo <ke...@freebsd.org> + * Copyright (c) 2016 Nathanial Sloss <nathanialsl...@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 @@ u_int urtwn_debug = 0; #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 @@ static const struct urtwn_dev { 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 @@ static void urtwn_r92c_rf_write(struct u 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_start(struct ifnet *); 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 void urtwn_stop(struct ifnet *, i 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 @@ urtwn_match(device_t parent, cfdata_t ma { 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 @@ urtwn_attach(device_t parent, device_t s 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 @@ urtwn_attach(device_t parent, device_t s 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 @@ urtwn_attach(device_t parent, device_t s 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 @@ urtwn_detach(device_t self, int flags) 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 @@ static int 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 @@ urtwn_open_pipes(struct urtwn_softc *sc) 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 @@ urtwn_open_pipes(struct urtwn_softc *sc) "%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 @@ urtwn_close_pipes(struct urtwn_softc *sc 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 @@ urtwn_alloc_rx_list(struct urtwn_softc * 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 @@ urtwn_free_rx_list(struct urtwn_softc *s 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 @@ urtwn_fw_cmd(struct urtwn_softc *sc, uin 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 @@ urtwn_fw_cmd(struct urtwn_softc *sc, uin /* 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 @@ urtwn_r88e_rf_write(struct urtwn_softc * 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 @@ urtwn_read_chipid(struct urtwn_softc *sc 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 @@ urtwn_r88e_read_rom(struct urtwn_softc * /* 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 @@ urtwn_r88e_read_rom(struct urtwn_softc * 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 @@ urtwn_ra_init(struct urtwn_softc *sc) 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 @@ urtwn_ra_init(struct urtwn_softc *sc) 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 @@ urtwn_ra_init(struct urtwn_softc *sc) "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 @@ urtwn_ra_init(struct urtwn_softc *sc) /* 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 @@ urtwn_ra_init(struct urtwn_softc *sc) __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 @@ urtwn_set_led(struct urtwn_softc *sc, in 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 @@ static void 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 @@ urtwn_calib_to_cb(struct urtwn_softc *sc 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 @@ urtwn_newstate_cb(struct urtwn_softc *sc 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_newstate_cb(struct urtwn_softc *sc 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 @@ urtwn_rx_frame(struct urtwn_softc *sc, u /* 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 @@ urtwn_rxeof(struct usbd_xfer *xfer, void 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 @@ urtwn_rxeof(struct usbd_xfer *xfer, void 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 @@ urtwn_txeof(struct usbd_xfer *xfer, void 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 @@ urtwn_txeof(struct usbd_xfer *xfer, void ifp->if_opackets++; urtwn_start(ifp); - splx(s); + } static int @@ -2459,7 +2563,7 @@ urtwn_tx(struct urtwn_softc *sc, struct 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,6 +2572,10 @@ urtwn_tx(struct urtwn_softc *sc, struct 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); @@ -2502,19 +2610,25 @@ urtwn_tx(struct urtwn_softc *sc, struct 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 @@ urtwn_tx(struct urtwn_softc *sc, struct ("%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 @@ urtwn_tx(struct urtwn_softc *sc, struct 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 @@ urtwn_tx(struct urtwn_softc *sc, struct /* 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 @@ urtwn_start(struct ifnet *ifp) 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 @@ urtwn_start(struct ifnet *ifp) 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 @@ urtwn_start(struct ifnet *ifp) if ((m = ieee80211_encap(ic, m, ni)) == NULL) { ieee80211_free_node(ni); + printf("ERROR4\n"); ifp->if_oerrors++; continue; } @@ -2738,6 +2868,7 @@ urtwn_start(struct ifnet *ifp) 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 @@ urtwn_watchdog(struct ifnet *ifp) 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_r92c_power_on(struct urtwn_softc * 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 @@ urtwn_r92c_power_on(struct urtwn_softc * 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 @@ urtwn_r92c_power_on(struct urtwn_softc * } 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,16 +3200,35 @@ static int 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++) { @@ -3054,9 +3285,25 @@ urtwn_r88e_fw_reset(struct urtwn_softc * 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 @@ urtwn_load_firmware(struct urtwn_softc * /* 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 @@ urtwn_load_firmware(struct urtwn_softc * 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 @@ urtwn_load_firmware(struct urtwn_softc * } 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 @@ urtwn_load_firmware(struct urtwn_softc * /* 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 @@ urtwn_load_firmware(struct urtwn_softc * 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 @@ urtwn_mac_init(struct urtwn_softc *sc) 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 @@ urtwn_bb_init(struct urtwn_softc *sc) 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 @@ urtwn_bb_init(struct urtwn_softc *sc) 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 @@ urtwn_bb_init(struct urtwn_softc *sc) /* 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 @@ urtwn_bb_init(struct urtwn_softc *sc) /* 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 @@ urtwn_bb_init(struct urtwn_softc *sc) 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 @@ urtwn_rf_init(struct urtwn_softc *sc) /* 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 @@ urtwn_rf_init(struct urtwn_softc *sc) 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 @@ urtwn_rf_init(struct urtwn_softc *sc) * 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 @@ urtwn_cam_init(struct urtwn_softc *sc) 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 @@ urtwn_set_txpower(struct urtwn_softc *sc 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_set_chan(struct urtwn_softc *sc, s 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 @@ urtwn_set_chan(struct urtwn_softc *sc, s /* 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_lc_calib(struct urtwn_softc *sc) 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 @@ urtwn_lc_calib(struct urtwn_softc *sc) 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 @@ urtwn_temp_calib(struct urtwn_softc *sc) 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_init(struct ifnet *ifp) 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_init(struct ifnet *ifp) 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_init(struct ifnet *ifp) 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_init(struct ifnet *ifp) 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_init(struct ifnet *ifp) 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 @@ urtwn_init(struct ifnet *ifp) /* 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_init(struct ifnet *ifp) 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_init(struct ifnet *ifp) 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 @@ urtwn_stop(struct ifnet *ifp, int disabl 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 @@ urtwn_chip_stop(struct urtwn_softc *sc) 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_chip_stop(struct urtwn_softc *sc) 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); @@ -4769,6 +5073,15 @@ urtwn_chip_stop(struct urtwn_softc *sc) 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"); #ifdef _MODULE Index: src/sys/dev/usb/if_urtwn_data.h diff -u src/sys/dev/usb/if_urtwn_data.h:1.3 src/sys/dev/usb/if_urtwn_data.h:1.4 --- src/sys/dev/usb/if_urtwn_data.h:1.3 Sun Jul 20 13:25:23 2014 +++ src/sys/dev/usb/if_urtwn_data.h Wed Oct 12 03:23:29 2016 @@ -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.bergam...@free.fr> + * Copyright (c) 2016 Nathanial Sloss <nathanialsl...@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 @@ static const struct urtwn_bb_prog rtl818 }; /* + * 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[] = { @@ -755,6 +897,83 @@ static const struct urtwn_rf_prog rtl818 }; /* + * 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 + } +}; + +/* * RTL8188EU. */ static const uint8_t rtl8188eu_rf_regs[] = { Index: src/sys/dev/usb/if_urtwnreg.h diff -u src/sys/dev/usb/if_urtwnreg.h:1.9 src/sys/dev/usb/if_urtwnreg.h:1.10 --- src/sys/dev/usb/if_urtwnreg.h:1.9 Wed Oct 12 02:56:45 2016 +++ src/sys/dev/usb/if_urtwnreg.h Wed Oct 12 03:23:29 2016 @@ -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 @@ struct r92c_fw_cmd { #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,6 +975,50 @@ struct r92c_fw_cmd_macid_cfg { #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; /* @@ -1116,7 +1174,9 @@ struct r92c_tx_desc { #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 @@ struct r92c_tx_desc { 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 Index: src/sys/dev/usb/if_urtwnvar.h diff -u src/sys/dev/usb/if_urtwnvar.h:1.9 src/sys/dev/usb/if_urtwnvar.h:1.10 --- src/sys/dev/usb/if_urtwnvar.h:1.9 Sat Apr 23 10:15:32 2016 +++ src/sys/dev/usb/if_urtwnvar.h Wed Oct 12 03:23:29 2016 @@ -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_tx_radiotap_header { 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 @@ struct urtwn_softc { 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 @@ struct urtwn_softc { #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_softc { 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 @@ struct urtwn_softc { } sc_txtapu; #define sc_txtap sc_txtapu.th int sc_txtap_len; + bool sc_running; }; #endif /* _IF_URTWNVAR_H_ */