Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[patch] rtl8188eu support for urtwn(4)

60 views
Skip to first unread message

Mikhail

unread,
Apr 19, 2015, 4:29:17 AM4/19/15
to
Hello, I inline the patch for rtl8188eu chip support in urtwn driver,
origins for this patch are in r264912[1] from FreeBSD. In order to work,
correct firmware must be presented in /etc/firmware - one can be found
in FreeBSD commit itself[2] - I'm not sure what is the correct procedure
of submitting it to firmware.openbsd.org.

I've tested it with TP-LINK TL-WN725N with usual network activity.

[1] - http://svnweb.freebsd.org/base?view=revision&revision=264912
[2] - http://svnweb.freebsd.org/base/head/sys/contrib/dev/urtwn/urtwn-rtl8188eufw.fw.uu?view=markup&pathrev=264912

Index: share/man/man4/urtwn.4
===================================================================
RCS file: /cvs/src/share/man/man4/urtwn.4,v
retrieving revision 1.31
diff -u -p -u -r1.31 urtwn.4
--- share/man/man4/urtwn.4 30 Mar 2015 12:35:15 -0000 1.31
+++ share/man/man4/urtwn.4 18 Apr 2015 19:44:00 -0000
@@ -14,22 +14,22 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: March 30 2015 $
+.Dd $Mdocdate: April 19 2015 $
.Dt URTWN 4
.Os
.Sh NAME
.Nm urtwn
-.Nd Realtek RTL8188CU/RTL8192CU USB IEEE 802.11b/g/n wireless network device
+.Nd Realtek RTL8188CU/RTL8188EU/RTL8192CU 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, RTL8188RU and RTL8192CU chipsets.
+RTL8188CUS, RTL8188CE-VAU, RTL8188EUS, RTL8188RU and RTL8192CU chipsets.
.Pp
-The RTL8188CUS is a highly integrated 802.11n adapter that combines
-a MAC, a 1T1R capable baseband and an RF in a single chip.
+The RTL8188CUS and RTL8188EUS is a highly integrated 802.11n adapter
+that combines a MAC, a 1T1R capable baseband and an RF in a single chip.
It operates in the 2GHz spectrum only.
The RTL8188RU is a high-power variant of the RTL8188CUS.
The RTL8188CE-VAU is a PCI Express Mini Card adapter that attaches
@@ -83,6 +83,7 @@ which are loaded when an interface is at
.It /etc/firmware/urtwn-rtl8192cfwT
.It /etc/firmware/urtwn-rtl8192cfwU
.It /etc/firmware/urtwn-rtl8723fw
+.It /etc/firmware/urtwn-rtl8188eufw
.El
.Pp
A prepackaged version of the firmware can be installed using
@@ -119,6 +120,8 @@ The following adapters should work:
.It Solwise NET-WL-UMD-606N
.It TP-Link TL-WN821N v4
.It TRENDnet TEW-648UBM
+.It TP-LINK TL-WN723N v3
+.It TP-LINK TL-WN725N v2
.El
.Sh EXAMPLES
The following example scans for available networks:
Index: sys/dev/usb/if_urtwn.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_urtwn.c,v
retrieving revision 1.43
diff -u -p -u -r1.43 if_urtwn.c
--- sys/dev/usb/if_urtwn.c 14 Mar 2015 03:38:49 -0000 1.43
+++ sys/dev/usb/if_urtwn.c 18 Apr 2015 19:44:00 -0000
@@ -2,6 +2,7 @@

/*-
* Copyright (c) 2010 Damien Bergamini <damien.b...@free.fr>
+ * Copyright (c) 2014 Kevin Lo <ke...@FreeBSD.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -17,7 +18,7 @@
*/

/*
- * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188RU/RTL8192CU.
+ * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188EU/RTL8188RU/RTL8192CU.
*/

#include "bpfilter.h"
@@ -140,7 +141,10 @@ static const struct usb_devno urtwn_devs
{ USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192CU },
{ USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8188CU },
{ USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8192CU },
- { USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RTL8192CU }
+ { USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RTL8192CU },
+ /* URTWN_RTL8188E */
+ { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188ETV },
+ { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188EU }
};

int urtwn_match(struct device *, void *, void *);
@@ -167,14 +171,17 @@ uint8_t urtwn_read_1(struct urtwn_softc
uint16_t urtwn_read_2(struct urtwn_softc *, uint16_t);
uint32_t urtwn_read_4(struct urtwn_softc *, uint16_t);
int urtwn_fw_cmd(struct urtwn_softc *, uint8_t, const void *, int);
-void urtwn_rf_write(struct urtwn_softc *, int, uint8_t, uint32_t);
+void urtwn_r92c_rf_write(struct urtwn_softc *, int, uint8_t, uint32_t);
+void urtwn_r88e_rf_write(struct urtwn_softc *, int, uint8_t, uint32_t);
uint32_t urtwn_rf_read(struct urtwn_softc *, int, uint8_t);
void urtwn_cam_write(struct urtwn_softc *, uint32_t, uint32_t);
int urtwn_llt_write(struct urtwn_softc *, uint32_t, uint32_t);
uint8_t urtwn_efuse_read_1(struct urtwn_softc *, uint16_t);
void urtwn_efuse_read(struct urtwn_softc *);
+void urtwn_efuse_switch_power(struct urtwn_softc *);
int urtwn_read_chipid(struct urtwn_softc *);
void urtwn_read_rom(struct urtwn_softc *);
+void urtwn_r88e_read_rom(struct urtwn_softc *);
int urtwn_media_change(struct ifnet *);
int urtwn_ra_init(struct urtwn_softc *);
void urtwn_tsf_sync_enable(struct urtwn_softc *);
@@ -195,6 +202,7 @@ void urtwn_delete_key(struct ieee80211c
void urtwn_delete_key_cb(struct urtwn_softc *, void *);
void urtwn_update_avgrssi(struct urtwn_softc *, int, int8_t);
int8_t urtwn_get_rssi(struct urtwn_softc *, int, void *);
+int8_t urtwn_r88e_get_rssi(struct urtwn_softc *, int, void *);
void urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int);
void urtwn_rxeof(struct usbd_xfer *, void *,
usbd_status);
@@ -205,12 +213,15 @@ int urtwn_tx(struct urtwn_softc *, stru
void urtwn_start(struct ifnet *);
void urtwn_watchdog(struct ifnet *);
int urtwn_ioctl(struct ifnet *, u_long, caddr_t);
-int urtwn_power_on(struct urtwn_softc *);
+int urtwn_r92c_power_on(struct urtwn_softc *);
+int urtwn_r88e_power_on(struct urtwn_softc *);
int urtwn_llt_init(struct urtwn_softc *);
void urtwn_fw_reset(struct urtwn_softc *);
+void urtwn_r88e_fw_reset(struct urtwn_softc *);
int urtwn_fw_loadpage(struct urtwn_softc *, int, uint8_t *, int);
int urtwn_load_firmware(struct urtwn_softc *);
-int urtwn_dma_init(struct urtwn_softc *);
+int urtwn_r92c_dma_init(struct urtwn_softc *);
+int urtwn_r88e_dma_init(struct urtwn_softc *);
void urtwn_mac_init(struct urtwn_softc *);
void urtwn_bb_init(struct urtwn_softc *);
void urtwn_rf_init(struct urtwn_softc *);
@@ -222,6 +233,9 @@ void urtwn_write_txpower(struct urtwn_s
void urtwn_get_txpower(struct urtwn_softc *, int,
struct ieee80211_channel *, struct ieee80211_channel *,
uint16_t[]);
+void urtwn_r88e_get_txpower(struct urtwn_softc *, int,
+ struct ieee80211_channel *,
+ struct ieee80211_channel *, uint16_t[]);
void urtwn_set_txpower(struct urtwn_softc *,
struct ieee80211_channel *, struct ieee80211_channel *);
void urtwn_set_chan(struct urtwn_softc *,
@@ -287,6 +301,9 @@ urtwn_attach(struct device *parent, stru
return;
}

+ if (uaa->product == USB_PRODUCT_REALTEK_RTL8188EU)
+ sc->chip |= URTWN_CHIP_88E;
+
error = urtwn_read_chipid(sc);
if (error != 0) {
printf("%s: unsupported test chip\n", sc->sc_dev.dv_xname);
@@ -301,11 +318,16 @@ urtwn_attach(struct device *parent, stru
sc->ntxchains = 1;
sc->nrxchains = 1;
}
- urtwn_read_rom(sc);
+
+ if (sc->chip & URTWN_CHIP_88E)
+ urtwn_r88e_read_rom(sc);
+ else
+ urtwn_read_rom(sc);

printf("%s: MAC/BB RTL%s, RF 6052 %dT%dR, address %s\n",
sc->sc_dev.dv_xname,
(sc->chip & URTWN_CHIP_92C) ? "8192CU" :
+ (sc->chip & URTWN_CHIP_88E) ? "8188EU" :
(sc->board_type == R92C_BOARD_TYPE_HIGHPA) ? "8188RU" :
(sc->board_type == R92C_BOARD_TYPE_MINICARD) ? "8188CE-VAU" :
"8188CUS", sc->ntxchains, sc->nrxchains,
@@ -752,14 +774,31 @@ urtwn_fw_cmd(struct urtwn_softc *sc, uin
return (0);
}

-void
+__inline void
urtwn_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr, uint32_t val)
{
+
+ sc->sc_rf_write(sc, chain, addr, val);
+}
+
+void
+urtwn_r92c_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr,
+ uint32_t val)
+{
urtwn_bb_write(sc, R92C_LSSI_PARAM(chain),
SM(R92C_LSSI_PARAM_ADDR, addr) |
SM(R92C_LSSI_PARAM_DATA, val));
}

+void
+urtwn_r88e_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));
+}
+
uint32_t
urtwn_rf_read(struct urtwn_softc *sc, int chain, uint8_t addr)
{
@@ -848,22 +887,8 @@ urtwn_efuse_read(struct urtwn_softc *sc)
uint8_t off, msk;
int i;

- reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL);
- if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) {
- urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
- reg | R92C_SYS_ISO_CTRL_PWC_EV12V);
- }
- reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
- if (!(reg & R92C_SYS_FUNC_EN_ELDR)) {
- urtwn_write_2(sc, R92C_SYS_FUNC_EN,
- reg | R92C_SYS_FUNC_EN_ELDR);
- }
- reg = urtwn_read_2(sc, R92C_SYS_CLKR);
- if ((reg & (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) !=
- (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) {
- urtwn_write_2(sc, R92C_SYS_CLKR,
- reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M);
- }
+ urtwn_efuse_switch_power(sc);
+
memset(&sc->rom, 0xff, sizeof(sc->rom));
while (addr < 512) {
reg = urtwn_efuse_read_1(sc, addr);
@@ -894,11 +919,37 @@ urtwn_efuse_read(struct urtwn_softc *sc)
#endif
}

+void
+urtwn_efuse_switch_power(struct urtwn_softc *sc)
+{
+ uint32_t reg;
+
+ reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL);
+ if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) {
+ urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
+ reg | R92C_SYS_ISO_CTRL_PWC_EV12V);
+ }
+ reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
+ if (!(reg & R92C_SYS_FUNC_EN_ELDR)) {
+ urtwn_write_2(sc, R92C_SYS_FUNC_EN,
+ reg | R92C_SYS_FUNC_EN_ELDR);
+ }
+ reg = urtwn_read_2(sc, R92C_SYS_CLKR);
+ if ((reg & (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) !=
+ (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) {
+ urtwn_write_2(sc, R92C_SYS_CLKR,
+ reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M);
+ }
+}
+
int
urtwn_read_chipid(struct urtwn_softc *sc)
{
uint32_t reg;

+ if (sc->chip & URTWN_CHIP_88E)
+ return (0);
+
reg = urtwn_read_4(sc, R92C_SYS_CFG);
if (reg & R92C_SYS_CFG_TRP_VAUX_EN)
return (EIO);
@@ -936,8 +987,71 @@ urtwn_read_rom(struct urtwn_softc *sc)

sc->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY);
DPRINTF(("regulatory type=%d\n", sc->regulatory));
-
IEEE80211_ADDR_COPY(ic->ic_myaddr, rom->macaddr);
+
+ sc->sc_rf_write = urtwn_r92c_rf_write;
+ sc->sc_power_on = urtwn_r92c_power_on;
+ sc->sc_dma_init = urtwn_r92c_dma_init;
+}
+
+void
+urtwn_r88e_read_rom(struct urtwn_softc *sc)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint8_t *rom = sc->r88e_rom;
+ uint16_t addr = 0;
+ uint32_t reg;
+ uint8_t off, msk, tmp;
+ int i;
+
+ off = 0;
+ urtwn_efuse_switch_power(sc);
+
+ /* Read full ROM image. */
+ memset(&sc->r88e_rom, 0xff, sizeof(sc->r88e_rom));
+ while (addr < 1024) {
+ reg = urtwn_efuse_read_1(sc, addr);
+ if (reg == 0xff)
+ break;
+ addr++;
+ if ((reg & 0x1f) == 0x0f) {
+ tmp = (reg & 0xe0) >> 5;
+ reg = urtwn_efuse_read_1(sc, addr);
+ if ((reg & 0x0f) != 0x0f)
+ off = ((reg & 0xf0) >> 1) | tmp;
+ addr++;
+ } else
+ off = reg >> 4;
+ msk = reg & 0xf;
+ for (i = 0; i < 4; i++) {
+ if (msk & (1 << i))
+ continue;
+ rom[off * 8 + i * 2 + 0] =
+ urtwn_efuse_read_1(sc, addr);
+ addr++;
+ rom[off * 8 + i * 2 + 1] =
+ urtwn_efuse_read_1(sc, addr);
+ addr++;
+ }
+ }
+
+ addr = 0x10;
+ for (i = 0; i < 6; i++)
+ sc->cck_tx_pwr[i] = sc->r88e_rom[addr++];
+ for (i = 0; i < 5; i++)
+ sc->ht40_tx_pwr[i] = sc->r88e_rom[addr++];
+ sc->bw20_tx_pwr_diff = (sc->r88e_rom[addr] & 0xf0) >> 4;
+ if (sc->bw20_tx_pwr_diff & 0x08)
+ sc->bw20_tx_pwr_diff |= 0xf0;
+ sc->ofdm_tx_pwr_diff = (sc->r88e_rom[addr] & 0xf);
+ if (sc->ofdm_tx_pwr_diff & 0x08)
+ sc->ofdm_tx_pwr_diff |= 0xf0;
+ sc->regulatory = MS(sc->r88e_rom[0xc1], R92C_ROM_RF1_REGULATORY);
+ 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;
+ sc->sc_dma_init = urtwn_r88e_dma_init;
}

int
@@ -1063,11 +1177,24 @@ urtwn_set_led(struct urtwn_softc *sc, in
uint8_t reg;

if (led == URTWN_LED_LINK) {
- reg = urtwn_read_1(sc, R92C_LEDCFG0) & 0x70;
- if (!on)
- reg |= R92C_LEDCFG0_DIS;
- urtwn_write_1(sc, R92C_LEDCFG0, reg);
- sc->ledlink = on; /* Save LED state. */
+ if (sc->chip & URTWN_CHIP_88E) {
+ reg = urtwn_read_1(sc, R92C_LEDCFG2) & 0xf0;
+ urtwn_write_1(sc, R92C_LEDCFG2, reg | 0x60);
+ if (!on) {
+ reg = urtwn_read_1(sc, R92C_LEDCFG2) & 0x90;
+ urtwn_write_1(sc, R92C_LEDCFG2,
+ reg | R92C_LEDCFG0_DIS);
+ urtwn_write_1(sc, R92C_MAC_PINMUX_CFG,
+ urtwn_read_1(sc, R92C_MAC_PINMUX_CFG) &
+ 0xfe);
+ }
+ } else {
+ reg = urtwn_read_1(sc, R92C_LEDCFG0) & 0x70;
+ if (!on)
+ reg |= R92C_LEDCFG0_DIS;
+ urtwn_write_1(sc, R92C_LEDCFG0, reg);
+ }
+ sc->ledlink = on; /* Save LED state. */
}
}

@@ -1202,9 +1329,11 @@ urtwn_newstate_cb(struct urtwn_softc *sc
reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);

- reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
- reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
- urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
+ reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
+ urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
+ }
}

/* Make link LED blink during scan. */
@@ -1225,9 +1354,11 @@ urtwn_newstate_cb(struct urtwn_softc *sc
reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);

- reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
- reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
- urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
+ reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
+ urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
+ }

urtwn_set_chan(sc, ic->ic_bss->ni_chan, NULL);
break;
@@ -1285,7 +1416,10 @@ urtwn_newstate_cb(struct urtwn_softc *sc
urtwn_write_1(sc, R92C_T2T_SIFS + 1, 10);

/* Intialize rate adaptation. */
- urtwn_ra_init(sc);
+ if (sc->chip & URTWN_CHIP_88E)
+ ni->ni_txrate = ni->ni_rates.rs_nrates-1;
+ else
+ urtwn_ra_init(sc);
/* Turn link LED on. */
urtwn_set_led(sc, URTWN_LED_LINK, 1);

@@ -1456,19 +1590,21 @@ urtwn_update_avgrssi(struct urtwn_softc
pwdb = 100;
else
pwdb = 100 + rssi;
- if (rate <= 3) {
- /* CCK gain is smaller than OFDM/MCS gain. */
- pwdb += 6;
- if (pwdb > 100)
- pwdb = 100;
- if (pwdb <= 14)
- pwdb -= 4;
- else if (pwdb <= 26)
- pwdb -= 8;
- else if (pwdb <= 34)
- pwdb -= 6;
- else if (pwdb <= 42)
- pwdb -= 2;
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ if (rate <= 3) {
+ /* CCK gain is smaller than OFDM/MCS gain. */
+ pwdb += 6;
+ if (pwdb > 100)
+ pwdb = 100;
+ if (pwdb <= 14)
+ pwdb -= 4;
+ else if (pwdb <= 26)
+ pwdb -= 8;
+ else if (pwdb <= 34)
+ pwdb -= 6;
+ else if (pwdb <= 42)
+ pwdb -= 2;
+ }
}
if (sc->avg_pwdb == -1) /* Init. */
sc->avg_pwdb = pwdb;
@@ -1505,6 +1641,57 @@ urtwn_get_rssi(struct urtwn_softc *sc, i
return (rssi);
}

+int8_t
+urtwn_r88e_get_rssi(struct urtwn_softc *sc, int rate, void *physt)
+{
+ struct r92c_rx_phystat *phy;
+ struct r88e_rx_cck *cck;
+ uint8_t cck_agc_rpt, lna_idx, vga_idx;
+ int8_t rssi;
+
+ rssi = 0;
+ if (rate <= 3) {
+ cck = (struct r88e_rx_cck *)physt;
+ cck_agc_rpt = cck->agc_rpt;
+ lna_idx = (cck_agc_rpt & 0xe0) >> 5;
+ vga_idx = cck_agc_rpt & 0x1f;
+ switch (lna_idx) {
+ case 7:
+ if (vga_idx <= 27)
+ rssi = -100 + 2* (27 - vga_idx);
+ else
+ rssi = -100;
+ break;
+ case 6:
+ rssi = -48 + 2 * (2 - vga_idx);
+ break;
+ case 5:
+ rssi = -42 + 2 * (7 - vga_idx);
+ break;
+ case 4:
+ rssi = -36 + 2 * (7 - vga_idx);
+ break;
+ case 3:
+ rssi = -24 + 2 * (7 - vga_idx);
+ break;
+ case 2:
+ rssi = -12 + 2 * (5 - vga_idx);
+ break;
+ case 1:
+ rssi = 8 - (2 * vga_idx);
+ break;
+ case 0:
+ rssi = 14 - (2 * vga_idx);
+ break;
+ }
+ rssi += 6;
+ } else { /* OFDM/HT. */
+ phy = (struct r92c_rx_phystat *)physt;
+ rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 110;
+ }
+ return (rssi);
+}
+
void
urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen)
{
@@ -1542,7 +1729,10 @@ urtwn_rx_frame(struct urtwn_softc *sc, u

/* Get RSSI from PHY status descriptor if present. */
if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
- rssi = urtwn_get_rssi(sc, rate, &stat[1]);
+ if (sc->chip & URTWN_CHIP_88E)
+ rssi = urtwn_r88e_get_rssi(sc, rate, &stat[1]);
+ else
+ rssi = urtwn_get_rssi(sc, rate, &stat[1]);
/* Update our average RSSI. */
urtwn_update_avgrssi(sc, rate, rssi);
}
@@ -1794,11 +1984,18 @@ urtwn_tx(struct urtwn_softc *sc, struct
raid = R92C_RAID_11B;
else
raid = R92C_RAID_11BG;
- txd->txdw1 |= htole32(
- SM(R92C_TXDW1_MACID, URTWN_MACID_BSS) |
- SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
- SM(R92C_TXDW1_RAID, raid) |
- R92C_TXDW1_AGGBK);
+ if (sc->chip & URTWN_CHIP_88E) {
+ txd->txdw1 |= htole32(
+ SM(R88E_TXDW1_MACID, URTWN_MACID_BSS) |
+ SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
+ SM(R92C_TXDW1_RAID, raid));
+ txd->txdw2 |= htole32(R88E_TXDW2_AGGBK);
+ } else {
+ txd->txdw1 |= htole32(
+ SM(R92C_TXDW1_MACID, URTWN_MACID_BSS) |
+ SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
+ SM(R92C_TXDW1_RAID, raid) | R92C_TXDW1_AGGBK);
+ }

if (ic->ic_flags & IEEE80211_F_USEPROT) {
if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
@@ -1813,7 +2010,10 @@ urtwn_tx(struct urtwn_softc *sc, struct
txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8));
txd->txdw5 |= htole32(0x0001ff00);
/* Send data at OFDM54. */
- txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));
+ if (sc->chip & URTWN_CHIP_88E)
+ txd->txdw5 |= htole32(0x13 & 0x3f);
+ else
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));

} else {
txd->txdw1 |= htole32(
@@ -2018,9 +2218,16 @@ urtwn_ioctl(struct ifnet *ifp, u_long cm
return (error);
}

-int
+__inline int
urtwn_power_on(struct urtwn_softc *sc)
{
+
+ return sc->sc_power_on(sc);
+}
+
+int
+urtwn_r92c_power_on(struct urtwn_softc *sc)
+{
uint32_t reg;
int ntries;

@@ -2104,12 +2311,73 @@ urtwn_power_on(struct urtwn_softc *sc)
}

int
+urtwn_r88e_power_on(struct urtwn_softc *sc)
+{
+ uint8_t val;
+ uint32_t reg;
+ int ntries;
+
+ /* Wait for power ready bit. */
+ for (ntries = 0; ntries < 5000; ntries++) {
+ val = urtwn_read_1(sc, 0x6) & 0x2;
+ if (val == 0x2)
+ break;
+ DELAY(10);
+ }
+ if (ntries == 5000) {
+ printf("%s: timeout waiting for chip power up\n",
+ sc->sc_dev.dv_xname);
+ return (ETIMEDOUT);
+ }
+
+ /* 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, 0x26, urtwn_read_1(sc, 0x26) | 0x80);
+
+ /* Disable HWPDN. */
+ urtwn_write_1(sc, 0x5, urtwn_read_1(sc, 0x5) & ~0x80);
+
+ /* Disable WL suspend. */
+ urtwn_write_1(sc, 0x5, urtwn_read_1(sc, 0x5) & ~0x18);
+
+ urtwn_write_1(sc, 0x5, urtwn_read_1(sc, 0x5) | 0x1);
+ for (ntries = 0; ntries < 5000; ntries++) {
+ if (!(urtwn_read_1(sc, 0x5) & 0x1))
+ break;
+ DELAY(10);
+ }
+ if (ntries == 5000)
+ return (ETIMEDOUT);
+
+ /* Enable LDO normal mode. */
+ urtwn_write_1(sc, 0x23, urtwn_read_1(sc, 0x23) & ~0x10);
+
+ /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
+ urtwn_write_2(sc, R92C_CR, 0);
+ 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 | R92C_CR_CALTMR_EN;
+ urtwn_write_2(sc, R92C_CR, reg);
+
+ return (0);
+}
+
+int
urtwn_llt_init(struct urtwn_softc *sc)
{
- int i, error;
+ int i, error, page_count, pktbuf_count;
+
+ 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;

- /* Reserve pages [0; R92C_TX_PAGE_COUNT]. */
- for (i = 0; i < R92C_TX_PAGE_COUNT; i++) {
+ /* Reserve pages [0; page_count]. */
+ for (i = 0; i < page_count; i++) {
if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
return (error);
}
@@ -2117,15 +2385,15 @@ urtwn_llt_init(struct urtwn_softc *sc)
if ((error = urtwn_llt_write(sc, i, 0xff)) != 0)
return (error);
/*
- * Use pages [R92C_TX_PAGE_COUNT + 1; R92C_TXPKTBUF_COUNT - 1]
+ * Use pages [page_count + 1; pktbuf_count - 1]
* as ring buffer.
*/
- for (++i; i < R92C_TXPKTBUF_COUNT - 1; i++) {
+ for (++i; i < pktbuf_count - 1; i++) {
if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
return (error);
}
/* Make the last page point to the beginning of the ring buffer. */
- error = urtwn_llt_write(sc, i, R92C_TX_PAGE_COUNT + 1);
+ error = urtwn_llt_write(sc, i, page_count + 1);
return (error);
}

@@ -2147,6 +2415,20 @@ urtwn_fw_reset(struct urtwn_softc *sc)
}
/* Force 8051 reset. */
urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
+ urtwn_write_2(sc, R92C_SYS_FUNC_EN,
+ urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
+ R92C_SYS_FUNC_EN_CPUEN);
+}
+
+
+void
+urtwn_r88e_fw_reset(struct urtwn_softc *sc)
+{
+ uint16_t reg;
+
+ reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
+ urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
+ urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg | R92C_SYS_FUNC_EN_CPUEN);
}

int
@@ -2188,8 +2470,10 @@ urtwn_load_firmware(struct urtwn_softc *
int mlen, ntries, page, error;

/* Read firmware image from the filesystem. */
- if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
- URTWN_CHIP_UMC_A_CUT)
+ if (sc->chip & URTWN_CHIP_88E)
+ name = "urtwn-rtl8188eufw";
+ else if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
+ URTWN_CHIP_UMC_A_CUT)
name = "urtwn-rtl8192cfwU";
else
name = "urtwn-rtl8192cfwT";
@@ -2207,6 +2491,7 @@ urtwn_load_firmware(struct urtwn_softc *
hdr = (const struct r92c_fw_hdr *)ptr;
/* Check if there is a valid FW header and skip it. */
if ((letoh16(hdr->signature) >> 4) == 0x88c ||
+ (le16toh(hdr->signature) >> 4) == 0x88e ||
(letoh16(hdr->signature) >> 4) == 0x92c) {
DPRINTF(("FW V%d.%d %02d-%02d %02d:%02d\n",
letoh16(hdr->version), letoh16(hdr->subversion),
@@ -2215,13 +2500,14 @@ urtwn_load_firmware(struct urtwn_softc *
len -= sizeof(*hdr);
}

- if (urtwn_read_1(sc, R92C_MCUFWDL) & 0x80) {
- urtwn_fw_reset(sc);
+ if (urtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL) {
+ if (sc->chip & URTWN_CHIP_88E)
+ urtwn_r88e_fw_reset(sc);
+ else
+ urtwn_fw_reset(sc);
urtwn_write_1(sc, R92C_MCUFWDL, 0);
}
- urtwn_write_2(sc, R92C_SYS_FUNC_EN,
- urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
- R92C_SYS_FUNC_EN_CPUEN);
+
urtwn_write_1(sc, R92C_MCUFWDL,
urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_EN);
urtwn_write_1(sc, R92C_MCUFWDL + 2,
@@ -2262,6 +2548,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 (sc->chip & URTWN_CHIP_88E)
+ urtwn_r88e_fw_reset(sc);
/* Wait for firmware readiness. */
for (ntries = 0; ntries < 1000; ntries++) {
if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_WINTINI_RDY)
@@ -2279,9 +2567,16 @@ urtwn_load_firmware(struct urtwn_softc *
return (error);
}

-int
+__inline int
urtwn_dma_init(struct urtwn_softc *sc)
{
+
+ return sc->sc_dma_init(sc);
+}
+
+int
+urtwn_r92c_dma_init(struct urtwn_softc *sc)
+{
int hashq, hasnq, haslq, nqueues, nqpages, nrempages;
uint32_t reg;
int error;
@@ -2359,14 +2654,78 @@ urtwn_dma_init(struct urtwn_softc *sc)
return (0);
}

+int
+urtwn_r88e_dma_init(struct urtwn_softc *sc)
+{
+ usb_interface_descriptor_t *id;
+ uint32_t reg;
+ int nrempages, nqpages, nqueues = 1;
+ int error;
+
+ /* Initialize LLT table. */
+ error = urtwn_llt_init(sc);
+ if (error != 0)
+ return (error);
+
+ /* Get Tx queues to USB endpoints mapping. */
+ id = usbd_get_interface_descriptor(sc->sc_iface);
+ nqueues = id->bNumEndpoints - 1;
+
+ /* Get the number of pages for each queue. */
+ nqpages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) / nqueues;
+ /* The remaining pages are assigned to the high priority queue. */
+ nrempages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) % nqueues;
+
+ /* Set number of pages for normal priority queue. */
+ urtwn_write_2(sc, R92C_RQPN_NPQ, 0);
+ urtwn_write_2(sc, R92C_RQPN_NPQ, 0x000d);
+ urtwn_write_4(sc, R92C_RQPN, 0x808e000d);
+
+ urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R88E_TX_PAGE_BOUNDARY);
+ urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R88E_TX_PAGE_BOUNDARY);
+ urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R88E_TX_PAGE_BOUNDARY);
+ urtwn_write_1(sc, R92C_TRXFF_BNDY, R88E_TX_PAGE_BOUNDARY);
+ urtwn_write_1(sc, R92C_TDECTRL + 1, R88E_TX_PAGE_BOUNDARY);
+
+ /* Set queue to USB pipe mapping. */
+ reg = urtwn_read_2(sc, R92C_TRXDMA_CTRL);
+ reg &= ~R92C_TRXDMA_CTRL_QMAP_M;
+ if (nqueues == 1)
+ reg |= R92C_TRXDMA_CTRL_QMAP_LQ;
+ else if (nqueues == 2)
+ reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ;
+ else
+ reg |= R92C_TRXDMA_CTRL_QMAP_3EP;
+ urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
+
+ /* Set Tx/Rx transfer page boundary. */
+ urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x23ff);
+
+ /* Set Tx/Rx transfer page size. */
+ urtwn_write_1(sc, R92C_PBP,
+ SM(R92C_PBP_PSRX, R92C_PBP_128) |
+ SM(R92C_PBP_PSTX, R92C_PBP_128));
+
+ return (0);
+}
+
void
urtwn_mac_init(struct urtwn_softc *sc)
{
int i;

/* Write MAC initialization values. */
- for (i = 0; i < nitems(rtl8192cu_mac); i++)
- urtwn_write_1(sc, rtl8192cu_mac[i].reg, rtl8192cu_mac[i].val);
+ if (sc->chip & URTWN_CHIP_88E) {
+ for (i = 0; i < nitems(rtl8188eu_mac); i++) {
+ urtwn_write_1(sc, rtl8188eu_mac[i].reg,
+ rtl8188eu_mac[i].val);
+ }
+ urtwn_write_1(sc, R92C_MAX_AGGR_NUM, 0x07);
+ } else {
+ for (i = 0; i < nitems(rtl8192cu_mac); i++)
+ urtwn_write_1(sc, rtl8192cu_mac[i].reg,
+ rtl8192cu_mac[i].val);
+ }
}

void
@@ -2374,6 +2733,7 @@ urtwn_bb_init(struct urtwn_softc *sc)
{
const struct urtwn_bb_prog *prog;
uint32_t reg;
+ uint8_t crystalcap;
int i;

/* Enable BB and RF. */
@@ -2382,7 +2742,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);

- urtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
+ if (!(sc->chip & URTWN_CHIP_88E))
+ urtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);

urtwn_write_1(sc, R92C_RF_CTRL,
R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
@@ -2390,12 +2751,16 @@ 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);

- urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
- urtwn_write_1(sc, 0x15, 0xe9);
- urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
+ urtwn_write_1(sc, 0x15, 0xe9);
+ urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
+ }

/* Select BB programming based on board type. */
- if (!(sc->chip & URTWN_CHIP_92C)) {
+ if (sc->chip & URTWN_CHIP_88E)
+ prog = &rtl8188eu_bb_prog;
+ else if (!(sc->chip & URTWN_CHIP_92C)) {
if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
prog = &rtl8188ce_bb_prog;
else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
@@ -2460,9 +2825,25 @@ urtwn_bb_init(struct urtwn_softc *sc)
DELAY(1);
}

- if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) &
- R92C_HSSI_PARAM2_CCK_HIPWR)
- sc->sc_flags |= URTWN_FLAG_CCK_HIPWR;
+ if (sc->chip & URTWN_CHIP_88E) {
+ urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553422);
+ DELAY(1);
+ urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553420);
+ DELAY(1);
+
+ crystalcap = sc->r88e_rom[0xb9];
+ if (crystalcap == 0xff)
+ crystalcap = 0x20;
+ crystalcap &= 0x3f;
+ reg = urtwn_bb_read(sc, R92C_AFE_XTAL_CTRL);
+ urtwn_bb_write(sc, R92C_AFE_XTAL_CTRL,
+ RW(reg, R92C_AFE_XTAL_CTRL_ADDR,
+ crystalcap | crystalcap << 6));
+ } else {
+ if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) &
+ R92C_HSSI_PARAM2_CCK_HIPWR)
+ sc->sc_flags |= URTWN_FLAG_CCK_HIPWR;
+ }
}

void
@@ -2473,7 +2854,9 @@ urtwn_rf_init(struct urtwn_softc *sc)
int i, j, idx, off;

/* Select RF programming based on board type. */
- if (!(sc->chip & URTWN_CHIP_92C)) {
+ if (sc->chip & URTWN_CHIP_88E)
+ prog = rtl8188eu_rf_prog;
+ else if (!(sc->chip & URTWN_CHIP_92C)) {
if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
prog = rtl8188ce_rf_prog;
else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
@@ -2764,6 +3147,75 @@ urtwn_get_txpower(struct urtwn_softc *sc
}

void
+urtwn_r88e_get_txpower(struct urtwn_softc *sc, int chain,
+ struct ieee80211_channel *c, struct ieee80211_channel *extc,
+ uint16_t power[URTWN_RIDX_COUNT])
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint16_t cckpow, ofdmpow, bw20pow, htpow;
+ const struct urtwn_r88e_txpwr *base;
+ int ridx, chan, group;
+
+ /* Determine channel group. */
+ chan = ieee80211_chan2ieee(ic, c); /* XXX center freq! */
+ if (chan <= 2)
+ group = 0;
+ else if (chan <= 5)
+ group = 1;
+ else if (chan <= 8)
+ group = 2;
+ else if (chan <= 11)
+ group = 3;
+ else if (chan <= 13)
+ group = 4;
+ else
+ group = 5;
+
+ /* Get original Tx power based on board type and RF chain. */
+ base = &rtl8188eu_txagc[chain];
+
+ memset(power, 0, URTWN_RIDX_COUNT * sizeof(power[0]));
+ if (sc->regulatory == 0) {
+ for (ridx = 0; ridx <= 3; ridx++)
+ power[ridx] = base->pwr[0][ridx];
+ }
+ for (ridx = 4; ridx < URTWN_RIDX_COUNT; ridx++) {
+ if (sc->regulatory == 3)
+ power[ridx] = base->pwr[0][ridx];
+ else if (sc->regulatory == 1) {
+ if (extc == NULL)
+ power[ridx] = base->pwr[group][ridx];
+ } else if (sc->regulatory != 2)
+ power[ridx] = base->pwr[0][ridx];
+ }
+
+ /* Compute per-CCK rate Tx power. */
+ cckpow = sc->cck_tx_pwr[group];
+ for (ridx = 0; ridx <= 3; ridx++) {
+ power[ridx] += cckpow;
+ if (power[ridx] > R92C_MAX_TX_PWR)
+ power[ridx] = R92C_MAX_TX_PWR;
+ }
+
+ htpow = sc->ht40_tx_pwr[group];
+
+ /* Compute per-OFDM rate Tx power. */
+ ofdmpow = htpow + sc->ofdm_tx_pwr_diff;
+ for (ridx = 4; ridx <= 11; ridx++) {
+ power[ridx] += ofdmpow;
+ if (power[ridx] > R92C_MAX_TX_PWR)
+ power[ridx] = R92C_MAX_TX_PWR;
+ }
+
+ bw20pow = htpow + sc->bw20_tx_pwr_diff;
+ for (ridx = 12; ridx <= 27; ridx++) {
+ power[ridx] += bw20pow;
+ if (power[ridx] > R92C_MAX_TX_PWR)
+ power[ridx] = R92C_MAX_TX_PWR;
+ }
+}
+
+void
urtwn_set_txpower(struct urtwn_softc *sc, struct ieee80211_channel *c,
struct ieee80211_channel *extc)
{
@@ -2772,7 +3224,10 @@ urtwn_set_txpower(struct urtwn_softc *sc

for (i = 0; i < sc->ntxchains; i++) {
/* Compute per-rate Tx power values. */
- urtwn_get_txpower(sc, i, c, extc, power);
+ if (sc->chip & URTWN_CHIP_88E)
+ urtwn_r88e_get_txpower(sc, i, c, extc, power);
+ else
+ urtwn_get_txpower(sc, i, c, extc, power);
/* Write per-rate Tx power values to hardware. */
urtwn_write_txpower(sc, i, power);
}
@@ -2845,13 +3300,17 @@ 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);

- urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
- urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) |
- R92C_FPGA0_ANAPARAM2_CBW20);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
+ urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) |
+ R92C_FPGA0_ANAPARAM2_CBW20);
+ }

/* Select 20MHz bandwidth. */
urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
- (sc->rf_chnlbw[0] & ~0xfff) | R92C_RF_CHNLBW_BW20 | chan);
+ (sc->rf_chnlbw[0] & ~0xfff) | chan |
+ ((sc->chip & URTWN_CHIP_88E) ? R88E_RF_CHNLBW_BW20 :
+ R92C_RF_CHNLBW_BW20));
}
}

@@ -3026,6 +3485,7 @@ urtwn_init(struct ifnet *ifp)
sc->sc_dev.dv_xname);
goto fail;
}
+
/* Power on adapter. */
error = urtwn_power_on(sc);
if (error != 0)
@@ -3040,8 +3500,19 @@ urtwn_init(struct ifnet *ifp)
urtwn_write_1(sc, R92C_RX_DRVINFO_SZ, 4);

/* Init interrupts. */
- urtwn_write_4(sc, R92C_HISR, 0xffffffff);
- urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
+ if (sc->chip & URTWN_CHIP_88E) {
+ 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);
+ } else {
+ urtwn_write_4(sc, R92C_HISR, 0xffffffff);
+ urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
+ }

/* Set MAC address. */
IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
@@ -3067,10 +3538,12 @@ urtwn_init(struct ifnet *ifp)
urtwn_edca_init(sc);

/* Setup rate fallback. */
- urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000);
- urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404);
- urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201);
- urtwn_write_4(sc, R92C_RARFRC + 4, 0x08070605);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000);
+ urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404);
+ urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201);
+ urtwn_write_4(sc, R92C_RARFRC + 4, 0x08070605);
+ }

urtwn_write_1(sc, R92C_FWHW_TXQ_CTRL,
urtwn_read_1(sc, R92C_FWHW_TXQ_CTRL) |
@@ -3089,23 +3562,28 @@ 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);
- urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
+ if (sc->chip & URTWN_CHIP_88E)
+ urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH + 1, 4);
+ else
+ urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
urtwn_write_1(sc, R92C_USB_AGG_TH, 8);
urtwn_write_1(sc, R92C_USB_AGG_TO, 6);

/* Initialize beacon parameters. */
+ urtwn_write_2(sc, R92C_BCN_CTRL, 0x1010);
urtwn_write_2(sc, R92C_TBTT_PROHIBIT, 0x6404);
urtwn_write_1(sc, R92C_DRVERLYINT, 0x05);
urtwn_write_1(sc, R92C_BCNDMATIM, 0x02);
urtwn_write_2(sc, R92C_BCNTCFG, 0x660f);

- /* Setup AMPDU aggregation. */
- urtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */
- urtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
- urtwn_write_2(sc, 0x4ca, 0x0708);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ /* Setup AMPDU aggregation. */
+ urtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */
+ urtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
+ urtwn_write_2(sc, R92C_MAX_AGGR_NUM, 0x0708);

- urtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff);
- urtwn_write_1(sc, R92C_BCN_CTRL, R92C_BCN_CTRL_DIS_TSF_UDT0);
+ urtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff);
+ }

/* Load 8051 microcode. */
error = urtwn_load_firmware(sc);
@@ -3117,6 +3595,12 @@ urtwn_init(struct ifnet *ifp)
urtwn_bb_init(sc);
urtwn_rf_init(sc);

+ if (sc->chip & URTWN_CHIP_88E) {
+ urtwn_write_2(sc, R92C_CR,
+ urtwn_read_2(sc, R92C_CR) | R92C_CR_MACTXEN |
+ R92C_CR_MACRXEN);
+ }
+
/* Turn CCK and OFDM blocks on. */
reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
reg |= R92C_RFMOD_CCK_EN;
@@ -3137,18 +3621,21 @@ urtwn_init(struct ifnet *ifp)
urtwn_lc_calib(sc);

/* Fix USB interference issue. */
- urtwn_write_1(sc, 0xfe40, 0xe0);
- urtwn_write_1(sc, 0xfe41, 0x8d);
- urtwn_write_1(sc, 0xfe42, 0x80);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ urtwn_write_1(sc, 0xfe40, 0xe0);
+ urtwn_write_1(sc, 0xfe41, 0x8d);
+ urtwn_write_1(sc, 0xfe42, 0x80);

- urtwn_pa_bias_init(sc);
+ urtwn_pa_bias_init(sc);
+ }

/* Initialize GPIO setting. */
urtwn_write_1(sc, R92C_GPIO_MUXCFG,
urtwn_read_1(sc, R92C_GPIO_MUXCFG) & ~R92C_GPIO_MUXCFG_ENBT);

/* Fix for lower temperature. */
- urtwn_write_1(sc, 0x15, 0xe9);
+ if (!(sc->chip & URTWN_CHIP_88E))
+ urtwn_write_1(sc, 0x15, 0xe9);

/* Set default channel. */
ic->ic_bss->ni_chan = ic->ic_ibss_chan;
Index: sys/dev/usb/if_urtwnreg.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_urtwnreg.h,v
retrieving revision 1.4
diff -u -p -u -r1.4 if_urtwnreg.h
--- sys/dev/usb/if_urtwnreg.h 15 Apr 2013 09:23:01 -0000 1.4
+++ sys/dev/usb/if_urtwnreg.h 18 Apr 2015 19:44:00 -0000
@@ -27,6 +27,9 @@
#define R92C_TXPKTBUF_COUNT 256
#define R92C_TX_PAGE_COUNT 248
#define R92C_TX_PAGE_BOUNDARY (R92C_TX_PAGE_COUNT + 1)
+#define R88E_TXPKTBUF_COUNT 177
+#define R88E_TX_PAGE_COUNT 169
+#define R88E_TX_PAGE_BOUNDARY (R88E_TX_PAGE_COUNT + 1)

#define R92C_H2C_NBOX 4

@@ -72,6 +75,11 @@
#define R92C_HSISR 0x05c
#define R92C_MCUFWDL 0x080
#define R92C_HMEBOX_EXT(idx) (0x088 + (idx) * 2)
+#define R88E_HIMR 0x0b0
+#define R88E_HISR 0x0b4
+#define R88E_HIMRE 0x0b8
+#define R88E_HISRE 0x0bc
+#define R92C_EFUSE_ACCESS 0x0cf
#define R92C_BIST_SCAN 0x0d0
#define R92C_BIST_RPT 0x0d4
#define R92C_BIST_ROM_RPT 0x0d8
@@ -112,6 +120,7 @@
#define R92C_LLT_INIT 0x1e0
#define R92C_BB_ACCESS_CTRL 0x1e8
#define R92C_BB_ACCESS_DATA 0x1ec
+#define R88E_HMEBOX_EXT(idx) (0x1f0 + (idx) * 4)
/* Tx DMA Configuration. */
#define R92C_RQPN 0x200
#define R92C_FIFOPAGE 0x204
@@ -141,6 +150,7 @@
#define R92C_RD_RESP_PKT_TH 0x463
#define R92C_INIRTS_RATE_SEL 0x480
#define R92C_INIDATA_RATE_SEL(macid) (0x484 + (macid))
+#define R92C_MAX_AGGR_NUM 0x4ca
/* EDCA Configuration. */
#define R92C_EDCA_VO_PARAM 0x500
#define R92C_EDCA_VI_PARAM 0x504
@@ -286,6 +296,10 @@
/* Bits for R92C_LDOV12D_CTRL. */
#define R92C_LDOV12D_CTRL_LDV12_EN 0x01

+/* Bits for R92C_AFE_XTAL_CTRL. */
+#define R92C_AFE_XTAL_CTRL_ADDR_M 0x007ff800
+#define R92C_AFE_XTAL_CTRL_ADDR_S 11
+
/* Bits for R92C_EFUSE_CTRL. */
#define R92C_EFUSE_CTRL_DATA_M 0x000000ff
#define R92C_EFUSE_CTRL_DATA_S 0
@@ -307,10 +321,27 @@
#define R92C_MCUFWDL_BBINI_RDY 0x00000010
#define R92C_MCUFWDL_RFINI_RDY 0x00000020
#define R92C_MCUFWDL_WINTINI_RDY 0x00000040
+#define R92C_MCUFWDL_RAM_DL_SEL 0x00000080
#define R92C_MCUFWDL_PAGE_M 0x00070000
#define R92C_MCUFWDL_PAGE_S 16
#define R92C_MCUFWDL_CPRST 0x00800000

+/* Bits for R88E_HIMR. */
+#define R88E_HIMR_CPWM 0x00000100
+#define R88E_HIMR_CPWM2 0x00000200
+#define R88E_HIMR_TBDER 0x04000000
+#define R88E_HIMR_PSTIMEOUT 0x20000000
+
+/* Bits for R88E_HIMRE.*/
+#define R88E_HIMRE_RXFOVW 0x00000100
+#define R88E_HIMRE_TXFOVW 0x00000200
+#define R88E_HIMRE_RXERR 0x00000400
+#define R88E_HIMRE_TXERR 0x00000800
+
+/* Bits for R92C_EFUSE_ACCESS. */
+#define R92C_EFUSE_ACCESS_OFF 0x00
+#define R92C_EFUSE_ACCESS_ON 0x69
+
/* Bits for R92C_HPON_FSM. */
#define R92C_HPON_FSM_CHIP_BONDING_ID_S 22
#define R92C_HPON_FSM_CHIP_BONDING_ID_M 0x00c00000
@@ -349,6 +380,7 @@
#define R92C_CR_MACTXEN 0x00000040
#define R92C_CR_MACRXEN 0x00000080
#define R92C_CR_ENSEC 0x00000200
+#define R92C_CR_CALTMR_EN 0x00000400
#define R92C_CR_NETTYPE_S 16
#define R92C_CR_NETTYPE_M 0x00030000
#define R92C_CR_NETTYPE_NOLINK 0
@@ -635,6 +667,8 @@
#define R92C_LSSI_PARAM_DATA_S 0
#define R92C_LSSI_PARAM_ADDR_M 0x03f00000
#define R92C_LSSI_PARAM_ADDR_S 20
+#define R88E_LSSI_PARAM_ADDR_M 0x0ff00000
+#define R88E_LSSI_PARAM_ADDR_S 20

/* Bits for R92C_FPGA0_ANAPARAM2. */
#define R92C_FPGA0_ANAPARAM2_CBW20 0x00000400
@@ -667,7 +701,8 @@
#define R92C_USB_STRING 0xfe80

/* Bits for R92C_USB_SPECIAL_OPTION. */
-#define R92C_USB_SPECIAL_OPTION_AGG_EN 0x08
+#define R92C_USB_SPECIAL_OPTION_AGG_EN 0x08
+#define R92C_USB_SPECIAL_OPTION_INT_BULK_SEL 0x10

/* Bits for R92C_USB_EP. */
#define R92C_USB_EP_HQ_M 0x000f
@@ -725,6 +760,7 @@
#define R92C_RF_CHNLBW_CHNL_M 0x003ff
#define R92C_RF_CHNLBW_CHNL_S 0
#define R92C_RF_CHNLBW_BW20 0x00400
+#define R88E_RF_CHNLBW_BW20 0x00c00
#define R92C_RF_CHNLBW_LCSTART 0x08000


@@ -935,6 +971,26 @@ struct r92c_rx_cck {
uint8_t agc_rpt;
} __packed;

+struct r88e_rx_cck {
+ uint8_t path_agc[2];
+ uint8_t sig_qual;
+ uint8_t agc_rpt;
+ uint8_t rpt_b;
+ uint8_t reserved1;
+ uint8_t noise_power;
+ uint8_t path_cfotail[2];
+ uint8_t pcts_mask[2];
+ uint8_t stream_rxevm[2];
+ uint8_t path_rxsnr[2];
+ uint8_t noise_power_db_lsb;
+ uint8_t reserved2[3];
+ uint8_t stream_csi[2];
+ uint8_t stream_target_csi[2];
+ uint8_t sig_evm;
+ uint8_t reserved3;
+ uint8_t reserved4;
+} __packed;
+
/* Tx MAC descriptor. */
struct r92c_tx_desc {
uint32_t txdw0;
@@ -950,6 +1006,8 @@ struct r92c_tx_desc {
uint32_t txdw1;
#define R92C_TXDW1_MACID_M 0x0000001f
#define R92C_TXDW1_MACID_S 0
+#define R88E_TXDW1_MACID_M 0x0000003f
+#define R88E_TXDW1_MACID_S 0
#define R92C_TXDW1_AGGEN 0x00000020
#define R92C_TXDW1_AGGBK 0x00000040
#define R92C_TXDW1_QSEL_M 0x00001f00
@@ -967,6 +1025,8 @@ struct r92c_tx_desc {
#define R92C_TXDW1_PKTOFF_S 26

uint32_t txdw2;
+#define R88E_TXDW2_AGGBK 0x00010000
+
uint16_t txdw3;
uint16_t txdseq;

@@ -1096,10 +1156,16 @@ struct urtwn_softc {
#define URTWN_FLAG_CCK_HIPWR 0x01

u_int chip;
-#define URTWN_CHIP_92C 0x01
-#define URTWN_CHIP_92C_1T2R 0x02
-#define URTWN_CHIP_UMC 0x04
-#define URTWN_CHIP_UMC_A_CUT 0x08
+#define URTWN_CHIP_92C 0x01
+#define URTWN_CHIP_92C_1T2R 0x02
+#define URTWN_CHIP_UMC 0x04
+#define URTWN_CHIP_UMC_A_CUT 0x08
+#define URTWN_CHIP_88E 0x10
+
+ void (*sc_rf_write)(struct urtwn_softc *,
+ int, uint8_t, uint32_t);
+ int (*sc_power_on)(struct urtwn_softc *);
+ int (*sc_dma_init)(struct urtwn_softc *);

uint8_t board_type;
uint8_t regulatory;
@@ -1118,6 +1184,11 @@ struct urtwn_softc {
struct urtwn_tx_data tx_data[URTWN_TX_LIST_COUNT];
TAILQ_HEAD(, urtwn_tx_data) tx_free_list;
struct r92c_rom rom;
+ uint8_t r88e_rom[512];
+ uint8_t cck_tx_pwr[6];
+ uint8_t ht40_tx_pwr[5];
+ int8_t bw20_tx_pwr_diff;
+ int8_t ofdm_tx_pwr_diff;

uint32_t rf_chnlbw[R92C_MAX_CHAINS];
#if NBPFILTER > 0
@@ -1145,7 +1216,31 @@ struct urtwn_softc {
static const struct {
uint16_t reg;
uint8_t val;
-} rtl8192cu_mac[] = {
+} rtl8188eu_mac[] = {
+ { 0x026, 0x41 }, { 0x027, 0x35 }, { 0x040, 0x00 }, { 0x428, 0x0a },
+ { 0x429, 0x10 }, { 0x430, 0x00 }, { 0x431, 0x01 }, { 0x432, 0x02 },
+ { 0x433, 0x04 }, { 0x434, 0x05 }, { 0x435, 0x06 }, { 0x436, 0x07 },
+ { 0x437, 0x08 }, { 0x438, 0x00 }, { 0x439, 0x00 }, { 0x43a, 0x01 },
+ { 0x43b, 0x02 }, { 0x43c, 0x04 }, { 0x43d, 0x05 }, { 0x43e, 0x06 },
+ { 0x43f, 0x07 }, { 0x440, 0x5d }, { 0x441, 0x01 }, { 0x442, 0x00 },
+ { 0x444, 0x15 }, { 0x445, 0xf0 }, { 0x446, 0x0f }, { 0x447, 0x00 },
+ { 0x458, 0x41 }, { 0x459, 0xa8 }, { 0x45a, 0x72 }, { 0x45b, 0xb9 },
+ { 0x460, 0x66 }, { 0x461, 0x66 }, { 0x480, 0x08 }, { 0x4c8, 0xff },
+ { 0x4c9, 0x08 }, { 0x4cc, 0xff }, { 0x4cd, 0xff }, { 0x4ce, 0x01 },
+ { 0x4d3, 0x01 }, { 0x500, 0x26 }, { 0x501, 0xa2 }, { 0x502, 0x2f },
+ { 0x503, 0x00 }, { 0x504, 0x28 }, { 0x505, 0xa3 }, { 0x506, 0x5e },
+ { 0x507, 0x00 }, { 0x508, 0x2b }, { 0x509, 0xa4 }, { 0x50a, 0x5e },
+ { 0x50b, 0x00 }, { 0x50c, 0x4f }, { 0x50d, 0xa4 }, { 0x50e, 0x00 },
+ { 0x50f, 0x00 }, { 0x512, 0x1c }, { 0x514, 0x0a }, { 0x516, 0x0a },
+ { 0x525, 0x4f }, { 0x550, 0x10 }, { 0x551, 0x10 }, { 0x559, 0x02 },
+ { 0x55d, 0xff }, { 0x605, 0x30 }, { 0x608, 0x0e }, { 0x609, 0x2a },
+ { 0x620, 0xff }, { 0x621, 0xff }, { 0x622, 0xff }, { 0x623, 0xff },
+ { 0x624, 0xff }, { 0x625, 0xff }, { 0x626, 0xff }, { 0x627, 0xff },
+ { 0x652, 0x20 }, { 0x63c, 0x0a }, { 0x63d, 0x0a }, { 0x63e, 0x0e },
+ { 0x63f, 0x0e }, { 0x640, 0x40 }, { 0x66e, 0x05 }, { 0x700, 0x21 },
+ { 0x701, 0x43 }, { 0x702, 0x65 }, { 0x703, 0x87 }, { 0x708, 0x21 },
+ { 0x709, 0x43 }, { 0x70a, 0x65 }, { 0x70b, 0x87 }
+}, rtl8192cu_mac[] = {
{ 0x420, 0x80 }, { 0x423, 0x00 }, { 0x430, 0x00 }, { 0x431, 0x00 },
{ 0x432, 0x00 }, { 0x433, 0x01 }, { 0x434, 0x04 }, { 0x435, 0x05 },
{ 0x436, 0x06 }, { 0x437, 0x07 }, { 0x438, 0x00 }, { 0x439, 0x00 },
@@ -1481,6 +1576,115 @@ static const struct urtwn_bb_prog rtl818
};

/*
+ * RTL8188EU.
+ */
+static const uint16_t rtl8188eu_bb_regs[] = {
+ 0x800, 0x804, 0x808, 0x80c, 0x810, 0x814, 0x818, 0x81c,
+ 0x820, 0x824, 0x828, 0x82c, 0x830, 0x834, 0x838, 0x83c,
+ 0x840, 0x844, 0x848, 0x84c, 0x850, 0x854, 0x858, 0x85c,
+ 0x860, 0x864, 0x868, 0x86c, 0x870, 0x874, 0x878, 0x87c,
+ 0x880, 0x884, 0x888, 0x88c, 0x890, 0x894, 0x898, 0x89c,
+ 0x900, 0x904, 0x908, 0x90c, 0x910, 0x914, 0xa00, 0xa04,
+ 0xa08, 0xa0c, 0xa10, 0xa14, 0xa18, 0xa1c, 0xa20, 0xa24,
+ 0xa28, 0xa2c, 0xa70, 0xa74, 0xa78, 0xa7c, 0xa80, 0xb2c,
+ 0xc00, 0xc04, 0xc08, 0xc0c, 0xc10, 0xc14, 0xc18, 0xc1c,
+ 0xc20, 0xc24, 0xc28, 0xc2c, 0xc30, 0xc34, 0xc38, 0xc3c,
+ 0xc40, 0xc44, 0xc48, 0xc4c, 0xc50, 0xc54, 0xc58, 0xc5c,
+ 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74, 0xc78, 0xc7c,
+ 0xc80, 0xc84, 0xc88, 0xc8c, 0xc90, 0xc94, 0xc98, 0xc9c,
+ 0xca0, 0xca4, 0xca8, 0xcac, 0xcb0, 0xcb4, 0xcb8, 0xcbc,
+ 0xcc0, 0xcc4, 0xcc8, 0xccc, 0xcd0, 0xcd4, 0xcd8, 0xcdc,
+ 0xce0, 0xce4, 0xce8, 0xcec, 0xd00, 0xd04, 0xd08, 0xd0c,
+ 0xd10, 0xd14, 0xd18, 0xd2c, 0xd30, 0xd34, 0xd38, 0xd3c,
+ 0xd40, 0xd44, 0xd48, 0xd4c, 0xd50, 0xd54, 0xd58, 0xd5c,
+ 0xd60, 0xd64, 0xd68, 0xd6c, 0xd70, 0xd74, 0xd78, 0xe00,
+ 0xe04, 0xe08, 0xe10, 0xe14, 0xe18, 0xe1c, 0xe28, 0xe30,
+ 0xe34, 0xe38, 0xe3c, 0xe40, 0xe44, 0xe48, 0xe4c, 0xe50,
+ 0xe54, 0xe58, 0xe5c, 0xe60, 0xe68, 0xe6c, 0xe70, 0xe74,
+ 0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, 0xed0, 0xed4,
+ 0xed8, 0xedc, 0xee0, 0xee8, 0xeec, 0xf14, 0xf4c, 0xf00
+};
+
+static const uint32_t rtl8188eu_bb_vals[] = {
+ 0x80040000, 0x00000003, 0x0000fc00, 0x0000000a, 0x10001331,
+ 0x020c3d10, 0x02200385, 0x00000000, 0x01000100, 0x00390204,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x569a11a9, 0x01000014, 0x66f60110,
+ 0x061f0649, 0x00000000, 0x27272700, 0x07000760, 0x25004000,
+ 0x00000808, 0x00000000, 0xb0000c1c, 0x00000001, 0x00000000,
+ 0xccc000c0, 0x00000800, 0xfffffffe, 0x40302010, 0x00706050,
+ 0x00000000, 0x00000023, 0x00000000, 0x81121111, 0x00000002,
+ 0x00000201, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e7f120f,
+ 0x9500bb78, 0x1114d028, 0x00881117, 0x89140f00, 0x1a1b0000,
+ 0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
+ 0x00000900, 0x225b0606, 0x218075b1, 0x80000000, 0x48071d40,
+ 0x03a05611, 0x000000e4, 0x6c6c6c6c, 0x08800000, 0x40000100,
+ 0x08800000, 0x40000100, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x69e9ac47, 0x469652af, 0x49795994, 0x0a97971c,
+ 0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f, 0x69553420,
+ 0x43bc0094, 0x00013169, 0x00250492, 0x00000000, 0x7112848b,
+ 0x47c00bff, 0x00000036, 0x2c7f000d, 0x020610db, 0x0000001f,
+ 0x00b91612, 0x390000e4, 0x20f60000, 0x40000100, 0x20200000,
+ 0x00091521, 0x00000000, 0x00121820, 0x00007f7f, 0x00000000,
+ 0x000300a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x28000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x64b22427, 0x00766932,
+ 0x00222222, 0x00000000, 0x37644302, 0x2f97d40c, 0x00000740,
+ 0x00020401, 0x0000907f, 0x20010201, 0xa0633333, 0x3333bc43,
+ 0x7a8f5b6f, 0xcc979975, 0x00000000, 0x80608000, 0x00000000,
+ 0x00127353, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x6437140a, 0x00000000, 0x00000282, 0x30032064, 0x4653de68,
+ 0x04518a3c, 0x00002101, 0x2a201c16, 0x1812362e, 0x322c2220,
+ 0x000e3c24, 0x2d2d2d2d, 0x2d2d2d2d, 0x0390272d, 0x2d2d2d2d,
+ 0x2d2d2d2d, 0x2d2d2d2d, 0x2d2d2d2d, 0x00000000, 0x1000dc1f,
+ 0x10008c1f, 0x02140102, 0x681604c2, 0x01007c00, 0x01004800,
+ 0xfb000000, 0x000028d1, 0x1000dc1f, 0x10008c1f, 0x02140102,
+ 0x28160d05, 0x00000008, 0x001b25a4, 0x00c00014, 0x00c00014,
+ 0x01000014, 0x01000014, 0x01000014, 0x01000014, 0x00c00014,
+ 0x01000014, 0x00c00014, 0x00c00014, 0x00c00014, 0x00c00014,
+ 0x00000014, 0x00000014, 0x21555448, 0x01c00014, 0x00000003,
+ 0x00000000, 0x00000300
+};
+
+static const uint32_t rtl8188eu_agc_vals[] = {
+ 0xfb000001, 0xfb010001, 0xfb020001, 0xfb030001, 0xfb040001,
+ 0xfb050001, 0xfa060001, 0xf9070001, 0xf8080001, 0xf7090001,
+ 0xf60a0001, 0xf50b0001, 0xf40c0001, 0xf30d0001, 0xf20e0001,
+ 0xf10f0001, 0xf0100001, 0xef110001, 0xee120001, 0xed130001,
+ 0xec140001, 0xeb150001, 0xea160001, 0xe9170001, 0xe8180001,
+ 0xe7190001, 0xe61a0001, 0xe51b0001, 0xe41c0001, 0xe31d0001,
+ 0xe21e0001, 0xe11f0001, 0x8a200001, 0x89210001, 0x88220001,
+ 0x87230001, 0x86240001, 0x85250001, 0x84260001, 0x83270001,
+ 0x82280001, 0x6b290001, 0x6a2a0001, 0x692b0001, 0x682c0001,
+ 0x672d0001, 0x662e0001, 0x652f0001, 0x64300001, 0x63310001,
+ 0x62320001, 0x61330001, 0x46340001, 0x45350001, 0x44360001,
+ 0x43370001, 0x42380001, 0x41390001, 0x403a0001, 0x403b0001,
+ 0x403c0001, 0x403d0001, 0x403e0001, 0x403f0001, 0xfb400001,
+ 0xfb410001, 0xfb420001, 0xfb430001, 0xfb440001, 0xfb450001,
+ 0xfb460001, 0xfb470001, 0xfb480001, 0xfa490001, 0xf94a0001,
+ 0xf84B0001, 0xf74c0001, 0xf64d0001, 0xf54e0001, 0xf44f0001,
+ 0xf3500001, 0xf2510001, 0xf1520001, 0xf0530001, 0xef540001,
+ 0xee550001, 0xed560001, 0xec570001, 0xeb580001, 0xea590001,
+ 0xe95a0001, 0xe85b0001, 0xe75c0001, 0xe65d0001, 0xe55e0001,
+ 0xe45f0001, 0xe3600001, 0xe2610001, 0xc3620001, 0xc2630001,
+ 0xc1640001, 0x8b650001, 0x8a660001, 0x89670001, 0x88680001,
+ 0x87690001, 0x866a0001, 0x856b0001, 0x846c0001, 0x676d0001,
+ 0x666e0001, 0x656f0001, 0x64700001, 0x63710001, 0x62720001,
+ 0x61730001, 0x60740001, 0x46750001, 0x45760001, 0x44770001,
+ 0x43780001, 0x42790001, 0x417a0001, 0x407b0001, 0x407c0001,
+ 0x407d0001, 0x407e0001, 0x407f0001
+};
+
+static const struct urtwn_bb_prog rtl8188eu_bb_prog = {
+ nitems(rtl8188eu_bb_regs),
+ rtl8188eu_bb_regs,
+ rtl8188eu_bb_vals,
+ nitems(rtl8188eu_agc_vals),
+ rtl8188eu_agc_vals
+};
+
+/*
* RTL8188RU.
*/
static const uint16_t rtl8188ru_bb_regs[] = {
@@ -1744,6 +1948,47 @@ static const struct urtwn_rf_prog rtl818
};

/*
+ * RTL8188EU.
+ */
+static const uint8_t rtl8188eu_rf_regs[] = {
+ 0x00, 0x08, 0x18, 0x19, 0x1e, 0x1f, 0x2f, 0x3f, 0x42, 0x57,
+ 0x58, 0x67, 0x83, 0xb0, 0xb1, 0xb2, 0xb4, 0xb6, 0xb7, 0xb8,
+ 0xb9, 0xba, 0xbb, 0xbf, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xdf, 0xef, 0x51, 0x52, 0x53, 0x56,
+ 0x35, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0xb6, 0x18, 0x5a,
+ 0x19, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
+ 0x34, 0x34, 0x00, 0x84, 0x86, 0x87, 0x8e, 0x8f, 0xef, 0x3b,
+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xef, 0x00, 0x18, 0xfe, 0xfe,
+ 0x1f, 0xfe, 0xfe, 0x1e, 0x1f, 0x00
+};
+
+static const uint32_t rtl8188eu_rf_vals[] = {
+ 0x30000, 0x84000, 0x00407, 0x00012, 0x80009, 0x00880, 0x1a060,
+ 0x00000, 0x060c0, 0xd0000, 0xbe180, 0x01552, 0x00000, 0xff8fc,
+ 0x54400, 0xccc19, 0x43003, 0x4953e, 0x1c718, 0x060ff, 0x80001,
+ 0x40000, 0x00400, 0xc0000, 0x02400, 0x00009, 0x40c91, 0x99999,
+ 0x000a3, 0x88820, 0x76c06, 0x00000, 0x80000, 0x00180, 0x001a0,
+ 0x6b27d, 0x7e49d, 0x00073, 0x51ff3, 0x00086, 0x00186,
+ 0x00286, 0x01c25, 0x09c25, 0x11c25, 0x19c25, 0x48538, 0x00c07,
+ 0x4bd00, 0x739d0, 0x0adf3, 0x09df0, 0x08ded, 0x07dea, 0x06de7,
+ 0x054ee, 0x044eb, 0x034e8, 0x0246b, 0x01468, 0x0006d, 0x30159,
+ 0x68200, 0x000ce, 0x48a00, 0x65540, 0x88000, 0x020a0, 0xf02b0,
+ 0xef7b0, 0xd4fb0, 0xcf060, 0xb0090, 0xa0080, 0x90080, 0x8f780,
+ 0x722b0, 0x6f7b0, 0x54fb0, 0x4f060, 0x30090, 0x20080, 0x10080,
+ 0x0f780, 0x000a0, 0x10159, 0x0f407, 0x00000, 0x00000, 0x80003,
+ 0x00000, 0x00000, 0x00001, 0x80000, 0x33e60
+};
+
+static const struct urtwn_rf_prog rtl8188eu_rf_prog[] = {
+ {
+ nitems(rtl8188eu_rf_regs),
+ rtl8188eu_rf_regs,
+ rtl8188eu_rf_vals
+ }
+};
+
+/*
* RTL8188RU.
*/
static const uint32_t rtl8188ru_rf_vals[] = {
@@ -1782,6 +2027,10 @@ struct urtwn_txpwr {
uint8_t pwr[3][28];
};

+struct urtwn_r88e_txpwr {
+ uint8_t pwr[6][28];
+};
+
/*
* Per RF chain/group/rate Tx gain values.
*/
@@ -1843,6 +2092,47 @@ static const struct urtwn_txpwr rtl8188r
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
},
{ /* Group 2. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ }
+ } }
+};
+
+static const struct urtwn_r88e_txpwr rtl8188eu_txagc[] = {
+ { { /* Chain 0. */
+ { /* Group 0. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ },
+ { /* Group 1. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ },
+ { /* Group 2. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ },
+ { /* Group 3. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ },
+ { /* Group 4. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ },
+ { /* Group 5. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
Index: sys/dev/usb/usbdevs
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs,v
retrieving revision 1.646
diff -u -p -u -r1.646 usbdevs
--- sys/dev/usb/usbdevs 2 Apr 2015 14:24:02 -0000 1.646
+++ sys/dev/usb/usbdevs 18 Apr 2015 19:44:00 -0000
@@ -3486,6 +3486,7 @@ product RATOC REXUSB60F 0xb020 REX-USB6

/* Realtek products */
product REALTEK RTL8188CTV 0x018a RTL8188CTV
+product REALTEK RTL8188ETV 0x0179 RTL8188ETV
product REALTEK RTL8188RU_2 0x317f RTL8188RU
product REALTEK RTL8150 0x8150 RTL8150
product REALTEK RTL8151 0x8151 RTL8151 PNA
@@ -3499,6 +3500,7 @@ product REALTEK RTL8174 0x8174 RTL8174
product REALTEK RTL8188CU_0 0x8176 RTL8188CU
product REALTEK RTL8191CU 0x8177 RTL8191CU
product REALTEK RTL8192CU 0x8178 RTL8192CU
+product REALTEK RTL8188EU 0x8179 RTL8188EU
product REALTEK RTL8188CU_1 0x817a RTL8188CU
product REALTEK RTL8188CU_2 0x817b RTL8188CU
product REALTEK RTL8192CE 0x817c RTL8192CE

Stefan Sperling

unread,
Apr 19, 2015, 9:58:34 AM4/19/15
to
On Sun, Apr 19, 2015 at 11:27:52AM +0300, Mikhail wrote:
> I'm not sure what is the correct procedure
> of submitting it to firmware.openbsd.org.

Please prepare a patch for /usr/ports/sysutils/firmware/urtwn.

> I've tested it with TP-LINK TL-WN725N with usual network activity.

Thanks! I will take a detailed look at your patch ASAP.

Stuart Henderson

unread,
Apr 19, 2015, 3:21:49 PM4/19/15
to
On 2015/04/19 11:27, Mikhail wrote:
> -.Dd $Mdocdate: March 30 2015 $
> +.Dd $Mdocdate: April 19 2015 $

No need to change this, it happens at commit.

> -The RTL8188CUS is a highly integrated 802.11n adapter that combines
> -a MAC, a 1T1R capable baseband and an RF in a single chip.
> +The RTL8188CUS and RTL8188EUS is a highly integrated 802.11n adapter
> +that combines a MAC, a 1T1R capable baseband and an RF in a single chip.

This is now plural - "The ... are highly integrated .. adapters .."

> +.It /etc/firmware/urtwn-rtl8188eufw

I can take care of the firmware package, can you confirm if this is correct?

SHA256 (urtwn-rtl8188eufw) = 1241ddbfc87f0495e0bf09d8b94c94680b60a3d8eeab89462b3c4d8d3e8a1ee0

Mikhail

unread,
Apr 19, 2015, 4:49:45 PM4/19/15
to
On 22:20 19-Apr 2015 Stuart Henderson wrote:
> On 2015/04/19 11:27, Mikhail wrote:
> > -.Dd $Mdocdate: March 30 2015 $
> > +.Dd $Mdocdate: April 19 2015 $
>
> No need to change this, it happens at commit.
>
> > -The RTL8188CUS is a highly integrated 802.11n adapter that combines
> > -a MAC, a 1T1R capable baseband and an RF in a single chip.
> > +The RTL8188CUS and RTL8188EUS is a highly integrated 802.11n adapter
> > +that combines a MAC, a 1T1R capable baseband and an RF in a single chip.
>
> This is now plural - "The ... are highly integrated .. adapters .."

Thank you and Stefan for taking time for review.

> > +.It /etc/firmware/urtwn-rtl8188eufw
>
> I can take care of the firmware package, can you confirm if this is correct?
>
> SHA256 (urtwn-rtl8188eufw) = 1241ddbfc87f0495e0bf09d8b94c94680b60a3d8eeab89462b3c4d8d3e8a1ee0

Yes, that's correct.

Bellow new version of the patch with above things fixed, also I've fixed
detection of ETV chip in urtwn_attach(), nothing else is changed.

Index: share/man/man4/urtwn.4
===================================================================
RCS file: /cvs/src/share/man/man4/urtwn.4,v
retrieving revision 1.31
diff -u -p -u -r1.31 urtwn.4
--- share/man/man4/urtwn.4 30 Mar 2015 12:35:15 -0000 1.31
+++ share/man/man4/urtwn.4 19 Apr 2015 20:27:41 -0000
@@ -19,17 +19,17 @@
.Os
.Sh NAME
.Nm urtwn
-.Nd Realtek RTL8188CU/RTL8192CU USB IEEE 802.11b/g/n wireless network device
+.Nd Realtek RTL8188CU/RTL8188EU/RTL8192CU 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, RTL8188RU and RTL8192CU chipsets.
+RTL8188CUS, RTL8188CE-VAU, RTL8188EUS, RTL8188RU and RTL8192CU chipsets.
.Pp
-The RTL8188CUS is a highly integrated 802.11n adapter that combines
-a MAC, a 1T1R capable baseband and an RF in a single chip.
+The RTL8188CUS and RTL8188EUS are a highly integrated 802.11n adapters
+that combines a MAC, a 1T1R capable baseband and an RF in a single chip.
+++ sys/dev/usb/if_urtwn.c 19 Apr 2015 20:27:41 -0000
@@ -287,6 +301,10 @@ urtwn_attach(struct device *parent, stru
return;
}

+ if (uaa->product == USB_PRODUCT_REALTEK_RTL8188EU ||
+ uaa->product == USB_PRODUCT_REALTEK_RTL8188ETV)
+ sc->chip |= URTWN_CHIP_88E;
+
error = urtwn_read_chipid(sc);
if (error != 0) {
printf("%s: unsupported test chip\n", sc->sc_dev.dv_xname);
@@ -301,11 +319,16 @@ urtwn_attach(struct device *parent, stru
sc->ntxchains = 1;
sc->nrxchains = 1;
}
- urtwn_read_rom(sc);
+
+ if (sc->chip & URTWN_CHIP_88E)
+ urtwn_r88e_read_rom(sc);
+ else
+ urtwn_read_rom(sc);

printf("%s: MAC/BB RTL%s, RF 6052 %dT%dR, address %s\n",
sc->sc_dev.dv_xname,
(sc->chip & URTWN_CHIP_92C) ? "8192CU" :
+ (sc->chip & URTWN_CHIP_88E) ? "8188EU" :
(sc->board_type == R92C_BOARD_TYPE_HIGHPA) ? "8188RU" :
(sc->board_type == R92C_BOARD_TYPE_MINICARD) ? "8188CE-VAU" :
"8188CUS", sc->ntxchains, sc->nrxchains,
@@ -752,14 +775,31 @@ urtwn_fw_cmd(struct urtwn_softc *sc, uin
@@ -848,22 +888,8 @@ urtwn_efuse_read(struct urtwn_softc *sc)
uint8_t off, msk;
int i;

- reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL);
- if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) {
- urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
- reg | R92C_SYS_ISO_CTRL_PWC_EV12V);
- }
- reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
- if (!(reg & R92C_SYS_FUNC_EN_ELDR)) {
- urtwn_write_2(sc, R92C_SYS_FUNC_EN,
- reg | R92C_SYS_FUNC_EN_ELDR);
- }
- reg = urtwn_read_2(sc, R92C_SYS_CLKR);
- if ((reg & (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) !=
- (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) {
- urtwn_write_2(sc, R92C_SYS_CLKR,
- reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M);
- }
+ urtwn_efuse_switch_power(sc);
+
memset(&sc->rom, 0xff, sizeof(sc->rom));
while (addr < 512) {
reg = urtwn_efuse_read_1(sc, addr);
@@ -894,11 +920,37 @@ urtwn_efuse_read(struct urtwn_softc *sc)
@@ -936,8 +988,71 @@ urtwn_read_rom(struct urtwn_softc *sc)
@@ -1063,11 +1178,24 @@ urtwn_set_led(struct urtwn_softc *sc, in
@@ -1202,9 +1330,11 @@ urtwn_newstate_cb(struct urtwn_softc *sc
reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);

- reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
- reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
- urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
+ reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
+ urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
+ }
}

/* Make link LED blink during scan. */
@@ -1225,9 +1355,11 @@ urtwn_newstate_cb(struct urtwn_softc *sc
reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);

- reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
- reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
- urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
+ reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
+ urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
+ }

urtwn_set_chan(sc, ic->ic_bss->ni_chan, NULL);
break;
@@ -1285,7 +1417,10 @@ urtwn_newstate_cb(struct urtwn_softc *sc
urtwn_write_1(sc, R92C_T2T_SIFS + 1, 10);

/* Intialize rate adaptation. */
- urtwn_ra_init(sc);
+ if (sc->chip & URTWN_CHIP_88E)
+ ni->ni_txrate = ni->ni_rates.rs_nrates-1;
+ else
+ urtwn_ra_init(sc);
/* Turn link LED on. */
urtwn_set_led(sc, URTWN_LED_LINK, 1);

@@ -1456,19 +1591,21 @@ urtwn_update_avgrssi(struct urtwn_softc
@@ -1505,6 +1642,57 @@ urtwn_get_rssi(struct urtwn_softc *sc, i
@@ -1542,7 +1730,10 @@ urtwn_rx_frame(struct urtwn_softc *sc, u

/* Get RSSI from PHY status descriptor if present. */
if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
- rssi = urtwn_get_rssi(sc, rate, &stat[1]);
+ if (sc->chip & URTWN_CHIP_88E)
+ rssi = urtwn_r88e_get_rssi(sc, rate, &stat[1]);
+ else
+ rssi = urtwn_get_rssi(sc, rate, &stat[1]);
/* Update our average RSSI. */
urtwn_update_avgrssi(sc, rate, rssi);
}
@@ -1794,11 +1985,18 @@ urtwn_tx(struct urtwn_softc *sc, struct
raid = R92C_RAID_11B;
else
raid = R92C_RAID_11BG;
- txd->txdw1 |= htole32(
- SM(R92C_TXDW1_MACID, URTWN_MACID_BSS) |
- SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
- SM(R92C_TXDW1_RAID, raid) |
- R92C_TXDW1_AGGBK);
+ if (sc->chip & URTWN_CHIP_88E) {
+ txd->txdw1 |= htole32(
+ SM(R88E_TXDW1_MACID, URTWN_MACID_BSS) |
+ SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
+ SM(R92C_TXDW1_RAID, raid));
+ txd->txdw2 |= htole32(R88E_TXDW2_AGGBK);
+ } else {
+ txd->txdw1 |= htole32(
+ SM(R92C_TXDW1_MACID, URTWN_MACID_BSS) |
+ SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
+ SM(R92C_TXDW1_RAID, raid) | R92C_TXDW1_AGGBK);
+ }

if (ic->ic_flags & IEEE80211_F_USEPROT) {
if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
@@ -1813,7 +2011,10 @@ urtwn_tx(struct urtwn_softc *sc, struct
txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8));
txd->txdw5 |= htole32(0x0001ff00);
/* Send data at OFDM54. */
- txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));
+ if (sc->chip & URTWN_CHIP_88E)
+ txd->txdw5 |= htole32(0x13 & 0x3f);
+ else
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));

} else {
txd->txdw1 |= htole32(
@@ -2018,9 +2219,16 @@ urtwn_ioctl(struct ifnet *ifp, u_long cm
return (error);
}

-int
+__inline int
urtwn_power_on(struct urtwn_softc *sc)
{
+
+ return sc->sc_power_on(sc);
+}
+
+int
+urtwn_r92c_power_on(struct urtwn_softc *sc)
+{
uint32_t reg;
int ntries;

@@ -2104,12 +2312,73 @@ urtwn_power_on(struct urtwn_softc *sc)
@@ -2117,15 +2386,15 @@ urtwn_llt_init(struct urtwn_softc *sc)
if ((error = urtwn_llt_write(sc, i, 0xff)) != 0)
return (error);
/*
- * Use pages [R92C_TX_PAGE_COUNT + 1; R92C_TXPKTBUF_COUNT - 1]
+ * Use pages [page_count + 1; pktbuf_count - 1]
* as ring buffer.
*/
- for (++i; i < R92C_TXPKTBUF_COUNT - 1; i++) {
+ for (++i; i < pktbuf_count - 1; i++) {
if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
return (error);
}
/* Make the last page point to the beginning of the ring buffer. */
- error = urtwn_llt_write(sc, i, R92C_TX_PAGE_COUNT + 1);
+ error = urtwn_llt_write(sc, i, page_count + 1);
return (error);
}

@@ -2147,6 +2416,20 @@ urtwn_fw_reset(struct urtwn_softc *sc)
}
/* Force 8051 reset. */
urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
+ urtwn_write_2(sc, R92C_SYS_FUNC_EN,
+ urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
+ R92C_SYS_FUNC_EN_CPUEN);
+}
+
+
+void
+urtwn_r88e_fw_reset(struct urtwn_softc *sc)
+{
+ uint16_t reg;
+
+ reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
+ urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
+ urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg | R92C_SYS_FUNC_EN_CPUEN);
}

int
@@ -2188,8 +2471,10 @@ urtwn_load_firmware(struct urtwn_softc *
int mlen, ntries, page, error;

/* Read firmware image from the filesystem. */
- if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
- URTWN_CHIP_UMC_A_CUT)
+ if (sc->chip & URTWN_CHIP_88E)
+ name = "urtwn-rtl8188eufw";
+ else if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
+ URTWN_CHIP_UMC_A_CUT)
name = "urtwn-rtl8192cfwU";
else
name = "urtwn-rtl8192cfwT";
@@ -2207,6 +2492,7 @@ urtwn_load_firmware(struct urtwn_softc *
hdr = (const struct r92c_fw_hdr *)ptr;
/* Check if there is a valid FW header and skip it. */
if ((letoh16(hdr->signature) >> 4) == 0x88c ||
+ (le16toh(hdr->signature) >> 4) == 0x88e ||
(letoh16(hdr->signature) >> 4) == 0x92c) {
DPRINTF(("FW V%d.%d %02d-%02d %02d:%02d\n",
letoh16(hdr->version), letoh16(hdr->subversion),
@@ -2215,13 +2501,14 @@ urtwn_load_firmware(struct urtwn_softc *
len -= sizeof(*hdr);
}

- if (urtwn_read_1(sc, R92C_MCUFWDL) & 0x80) {
- urtwn_fw_reset(sc);
+ if (urtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL) {
+ if (sc->chip & URTWN_CHIP_88E)
+ urtwn_r88e_fw_reset(sc);
+ else
+ urtwn_fw_reset(sc);
urtwn_write_1(sc, R92C_MCUFWDL, 0);
}
- urtwn_write_2(sc, R92C_SYS_FUNC_EN,
- urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
- R92C_SYS_FUNC_EN_CPUEN);
+
urtwn_write_1(sc, R92C_MCUFWDL,
urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_EN);
urtwn_write_1(sc, R92C_MCUFWDL + 2,
@@ -2262,6 +2549,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 (sc->chip & URTWN_CHIP_88E)
+ urtwn_r88e_fw_reset(sc);
/* Wait for firmware readiness. */
for (ntries = 0; ntries < 1000; ntries++) {
if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_WINTINI_RDY)
@@ -2279,9 +2568,16 @@ urtwn_load_firmware(struct urtwn_softc *
return (error);
}

-int
+__inline int
urtwn_dma_init(struct urtwn_softc *sc)
{
+
+ return sc->sc_dma_init(sc);
+}
+
+int
+urtwn_r92c_dma_init(struct urtwn_softc *sc)
+{
int hashq, hasnq, haslq, nqueues, nqpages, nrempages;
uint32_t reg;
int error;
@@ -2359,14 +2655,78 @@ urtwn_dma_init(struct urtwn_softc *sc)
@@ -2374,6 +2734,7 @@ urtwn_bb_init(struct urtwn_softc *sc)
{
const struct urtwn_bb_prog *prog;
uint32_t reg;
+ uint8_t crystalcap;
int i;

/* Enable BB and RF. */
@@ -2382,7 +2743,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);

- urtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
+ if (!(sc->chip & URTWN_CHIP_88E))
+ urtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);

urtwn_write_1(sc, R92C_RF_CTRL,
R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
@@ -2390,12 +2752,16 @@ 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);

- urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
- urtwn_write_1(sc, 0x15, 0xe9);
- urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
+ urtwn_write_1(sc, 0x15, 0xe9);
+ urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
+ }

/* Select BB programming based on board type. */
- if (!(sc->chip & URTWN_CHIP_92C)) {
+ if (sc->chip & URTWN_CHIP_88E)
+ prog = &rtl8188eu_bb_prog;
+ else if (!(sc->chip & URTWN_CHIP_92C)) {
if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
prog = &rtl8188ce_bb_prog;
else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
@@ -2460,9 +2826,25 @@ urtwn_bb_init(struct urtwn_softc *sc)
DELAY(1);
}

- if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) &
- R92C_HSSI_PARAM2_CCK_HIPWR)
- sc->sc_flags |= URTWN_FLAG_CCK_HIPWR;
+ if (sc->chip & URTWN_CHIP_88E) {
+ urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553422);
+ DELAY(1);
+ urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553420);
+ DELAY(1);
+
+ crystalcap = sc->r88e_rom[0xb9];
+ if (crystalcap == 0xff)
+ crystalcap = 0x20;
+ crystalcap &= 0x3f;
+ reg = urtwn_bb_read(sc, R92C_AFE_XTAL_CTRL);
+ urtwn_bb_write(sc, R92C_AFE_XTAL_CTRL,
+ RW(reg, R92C_AFE_XTAL_CTRL_ADDR,
+ crystalcap | crystalcap << 6));
+ } else {
+ if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) &
+ R92C_HSSI_PARAM2_CCK_HIPWR)
+ sc->sc_flags |= URTWN_FLAG_CCK_HIPWR;
+ }
}

void
@@ -2473,7 +2855,9 @@ urtwn_rf_init(struct urtwn_softc *sc)
int i, j, idx, off;

/* Select RF programming based on board type. */
- if (!(sc->chip & URTWN_CHIP_92C)) {
+ if (sc->chip & URTWN_CHIP_88E)
+ prog = rtl8188eu_rf_prog;
+ else if (!(sc->chip & URTWN_CHIP_92C)) {
if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
prog = rtl8188ce_rf_prog;
else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
@@ -2764,6 +3148,75 @@ urtwn_get_txpower(struct urtwn_softc *sc
@@ -2772,7 +3225,10 @@ urtwn_set_txpower(struct urtwn_softc *sc

for (i = 0; i < sc->ntxchains; i++) {
/* Compute per-rate Tx power values. */
- urtwn_get_txpower(sc, i, c, extc, power);
+ if (sc->chip & URTWN_CHIP_88E)
+ urtwn_r88e_get_txpower(sc, i, c, extc, power);
+ else
+ urtwn_get_txpower(sc, i, c, extc, power);
/* Write per-rate Tx power values to hardware. */
urtwn_write_txpower(sc, i, power);
}
@@ -2845,13 +3301,17 @@ 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);

- urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
- urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) |
- R92C_FPGA0_ANAPARAM2_CBW20);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
+ urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) |
+ R92C_FPGA0_ANAPARAM2_CBW20);
+ }

/* Select 20MHz bandwidth. */
urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
- (sc->rf_chnlbw[0] & ~0xfff) | R92C_RF_CHNLBW_BW20 | chan);
+ (sc->rf_chnlbw[0] & ~0xfff) | chan |
+ ((sc->chip & URTWN_CHIP_88E) ? R88E_RF_CHNLBW_BW20 :
+ R92C_RF_CHNLBW_BW20));
}
}

@@ -3026,6 +3486,7 @@ urtwn_init(struct ifnet *ifp)
sc->sc_dev.dv_xname);
goto fail;
}
+
/* Power on adapter. */
error = urtwn_power_on(sc);
if (error != 0)
@@ -3040,8 +3501,19 @@ urtwn_init(struct ifnet *ifp)
urtwn_write_1(sc, R92C_RX_DRVINFO_SZ, 4);

/* Init interrupts. */
- urtwn_write_4(sc, R92C_HISR, 0xffffffff);
- urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
+ if (sc->chip & URTWN_CHIP_88E) {
+ 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);
+ } else {
+ urtwn_write_4(sc, R92C_HISR, 0xffffffff);
+ urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
+ }

/* Set MAC address. */
IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
@@ -3067,10 +3539,12 @@ urtwn_init(struct ifnet *ifp)
urtwn_edca_init(sc);

/* Setup rate fallback. */
- urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000);
- urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404);
- urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201);
- urtwn_write_4(sc, R92C_RARFRC + 4, 0x08070605);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000);
+ urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404);
+ urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201);
+ urtwn_write_4(sc, R92C_RARFRC + 4, 0x08070605);
+ }

urtwn_write_1(sc, R92C_FWHW_TXQ_CTRL,
urtwn_read_1(sc, R92C_FWHW_TXQ_CTRL) |
@@ -3089,23 +3563,28 @@ urtwn_init(struct ifnet *ifp)
@@ -3117,6 +3596,12 @@ urtwn_init(struct ifnet *ifp)
urtwn_bb_init(sc);
urtwn_rf_init(sc);

+ if (sc->chip & URTWN_CHIP_88E) {
+ urtwn_write_2(sc, R92C_CR,
+ urtwn_read_2(sc, R92C_CR) | R92C_CR_MACTXEN |
+ R92C_CR_MACRXEN);
+ }
+
/* Turn CCK and OFDM blocks on. */
reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
reg |= R92C_RFMOD_CCK_EN;
@@ -3137,18 +3622,21 @@ urtwn_init(struct ifnet *ifp)
+++ sys/dev/usb/if_urtwnreg.h 19 Apr 2015 20:27:41 -0000
+++ sys/dev/usb/usbdevs 19 Apr 2015 20:27:41 -0000

Stuart Henderson

unread,
Apr 20, 2015, 7:17:08 AM4/20/15
to
On 2015/04/19 23:48, Mikhail wrote:
> > I can take care of the firmware package, can you confirm if this is correct?
> >
> > SHA256 (urtwn-rtl8188eufw) = 1241ddbfc87f0495e0bf09d8b94c94680b60a3d8eeab89462b3c4d8d3e8a1ee0
>
> Yes, that's correct.

Thanks. I've committed it to ports/sysutils/firmware/urtwn, I'll build some
packages when I can find the power supply for the signing machine ;-)

Stefan Sperling

unread,
Apr 26, 2015, 7:32:01 AM4/26/15
to
On Sun, Apr 19, 2015 at 11:48:32PM +0300, Mikhail wrote:
> Bellow new version of the patch with above things fixed, also I've fixed
> detection of ETV chip in urtwn_attach(), nothing else is changed.

I'm seeing very low data transmission rates with your patch and a
TP-Link TL-WN725N device. In both 11b and 11g mode, the data rate
remains very low (less than 100Kbit/s). A different urtwn(4) device
(with 8188CUS chip) has much better throughput.

Are you seeing this, too?

Stefan Sperling

unread,
Apr 26, 2015, 7:49:57 AM4/26/15
to
On Sun, Apr 19, 2015 at 11:48:32PM +0300, Mikhail wrote:
> Bellow new version of the patch with above things fixed, also I've fixed
> detection of ETV chip in urtwn_attach(), nothing else is changed.

I've committed the part below already.
I put the ID 0x0179 before 0x018a though, not after.

Stefan Sperling

unread,
Apr 26, 2015, 1:21:20 PM4/26/15
to
On Sun, Apr 26, 2015 at 01:31:17PM +0200, Stefan Sperling wrote:
> On Sun, Apr 19, 2015 at 11:48:32PM +0300, Mikhail wrote:
> > Bellow new version of the patch with above things fixed, also I've fixed
> > detection of ETV chip in urtwn_attach(), nothing else is changed.
>
> I'm seeing very low data transmission rates with your patch and a
> TP-Link TL-WN725N device. In both 11b and 11g mode, the data rate
> remains very low (less than 100Kbit/s). A different urtwn(4) device
> (with 8188CUS chip) has much better throughput.
>
> Are you seeing this, too?

The chunk below is wrong for OpenBSD since it sets the intitial transmit
rate to an 11n rate. 0x13 corresponds to the "MCS7" 11n rate,
see linux/drivers/net/wireless/rtlwifi/rtl8188ee/def.h enum rtl_desc92c_rate.
The value 11 corresponds to OFDM 54Mbit which is fine for OpenBSD.
We only support 11a/b/g at present.

--- sys/dev/usb/if_urtwn.c 14 Mar 2015 03:38:49 -0000 1.43
+++ sys/dev/usb/if_urtwn.c 19 Apr 2015 20:27:41 -0000
@@ -1813,7 +2011,10 @@ urtwn_tx(struct urtwn_softc *sc, struct
txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8));
txd->txdw5 |= htole32(0x0001ff00);
/* Send data at OFDM54. */
- txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));
+ if (sc->chip & URTWN_CHIP_88E)
+ txd->txdw5 |= htole32(0x13 & 0x3f);
+ else
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));

} else {
txd->txdw1 |= htole32(

Reverting this change doesn't fix the transmit speed problem, unfortunately.

I wonder if we're making some mistake while setting up the TX descriptor?
There are several differences in the TX descriptors of 88E vs 92C.
For example, 88E has third antenna C available.

Mikhail

unread,
Apr 26, 2015, 2:23:17 PM4/26/15
to
Hello, in urtwn_init(), in part:

if (sc->chip & URTWN_CHIP_88E)
urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH + 1, 4);
else
urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);

comment first 3 lines. It fixes speed problem for me, but I need to
understand the issue further, before proposing any solution.

Mikhail

unread,
Apr 26, 2015, 3:47:28 PM4/26/15
to
The issue isn't in those lines, but a little bit higher - the driver
enables usb and dma aggregations, but native linux implementation
enables only dma and disables usb one.

I've submitted bug report to FreeBSD[1] with a patch, which I see as a
proper solution:

urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
- R92C_USB_SPECIAL_OPTION_AGG_EN);
+ (sc->chip & URTWN_CHIP_88E ?
+ ~R92C_USB_SPECIAL_OPTION_AGG_EN :
+ R92C_USB_SPECIAL_OPTION_AGG_EN));

I'd suggest to wait some time for feedback. Testing is welcome, of
course. Thank you for pointing this out and review in general.

[1] - https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=199718

patrick keshishian

unread,
Apr 26, 2015, 4:27:55 PM4/26/15
to
umm... maybe 0, as it is being ORed with what read returns.
But maybe the check should be against URTWN_CHIP_92C since
the option is specific to it (or at least implied to be so).

--patrick

Brendan MacDonell

unread,
May 2, 2015, 8:44:04 PM5/2/15
to
Just wanted to report that this works with my TL-WN723N v3.0. With both
patches applied the adapter is able to saturate my DSL connection.

Brendan MacDonell

Mikhail

unread,
May 4, 2015, 6:42:52 AM5/4/15
to
On 20:20 26-Apr 2015 Stefan Sperling wrote:
> The chunk below is wrong for OpenBSD since it sets the intitial transmit
> rate to an 11n rate. 0x13 corresponds to the "MCS7" 11n rate,
> see linux/drivers/net/wireless/rtlwifi/rtl8188ee/def.h enum rtl_desc92c_rate.
> The value 11 corresponds to OFDM 54Mbit which is fine for OpenBSD.
> We only support 11a/b/g at present.
>
> --- sys/dev/usb/if_urtwn.c 14 Mar 2015 03:38:49 -0000 1.43
> +++ sys/dev/usb/if_urtwn.c 19 Apr 2015 20:27:41 -0000
> @@ -1813,7 +2011,10 @@ urtwn_tx(struct urtwn_softc *sc, struct
> txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8));
> txd->txdw5 |= htole32(0x0001ff00);
> /* Send data at OFDM54. */
> - txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));
> + if (sc->chip & URTWN_CHIP_88E)
> + txd->txdw5 |= htole32(0x13 & 0x3f);
> + else
> + txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));
>
> } else {
> txd->txdw1 |= htole32(

Hello, yes, this change, maybe harmless, but not accurate. I inline new
patch against head with this change incorporated and with fix for USB
aggregation mode, which Kevin has pushed into FreeBSD[1] to fix
performance issues.

[1] - https://svnweb.freebsd.org/base?view=revision&revision=282266

Index: share/man/man4/urtwn.4
===================================================================
RCS file: /cvs/src/share/man/man4/urtwn.4,v
retrieving revision 1.31
diff -u -p -r1.31 urtwn.4
--- share/man/man4/urtwn.4 30 Mar 2015 12:35:15 -0000 1.31
+++ share/man/man4/urtwn.4 4 May 2015 10:09:59 -0000
@@ -19,17 +19,17 @@
.Os
.Sh NAME
.Nm urtwn
-.Nd Realtek RTL8188CU/RTL8192CU USB IEEE 802.11b/g/n wireless network device
+.Nd Realtek RTL8188CU/RTL8188EU/RTL8192CU 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, RTL8188RU and RTL8192CU chipsets.
+RTL8188CUS, RTL8188CE-VAU, RTL8188EUS, RTL8188RU and RTL8192CU chipsets.
.Pp
-The RTL8188CUS is a highly integrated 802.11n adapter that combines
-a MAC, a 1T1R capable baseband and an RF in a single chip.
+The RTL8188CUS and RTL8188EUS are a highly integrated 802.11n adapter
+that combines a MAC, a 1T1R capable baseband and an RF in a single chip.
It operates in the 2GHz spectrum only.
The RTL8188RU is a high-power variant of the RTL8188CUS.
The RTL8188CE-VAU is a PCI Express Mini Card adapter that attaches
@@ -83,6 +83,7 @@ which are loaded when an interface is at
.It /etc/firmware/urtwn-rtl8192cfwT
.It /etc/firmware/urtwn-rtl8192cfwU
.It /etc/firmware/urtwn-rtl8723fw
+.It /etc/firmware/urtwn-rtl8188eufw
.El
.Pp
A prepackaged version of the firmware can be installed using
@@ -119,6 +120,8 @@ The following adapters should work:
.It Solwise NET-WL-UMD-606N
.It TP-Link TL-WN821N v4
.It TRENDnet TEW-648UBM
+.It TP-LINK TL-WN723N v3
+.It TP-LINK TL-WN725N v2
.El
.Sh EXAMPLES
The following example scans for available networks:
Index: sys/dev/usb/if_urtwn.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_urtwn.c,v
retrieving revision 1.43
diff -u -p -r1.43 if_urtwn.c
--- sys/dev/usb/if_urtwn.c 14 Mar 2015 03:38:49 -0000 1.43
+++ sys/dev/usb/if_urtwn.c 4 May 2015 10:10:00 -0000
+ if (sc->chip & URTWN_CHIP_88E)
+ if (sc->chip & URTWN_CHIP_88E)
+ if (sc->chip & URTWN_CHIP_88E) {
+ if (sc->chip & URTWN_CHIP_88E)
+ if (sc->chip & URTWN_CHIP_88E)
+ rssi = urtwn_r88e_get_rssi(sc, rate, &stat[1]);
+ else
+ rssi = urtwn_get_rssi(sc, rate, &stat[1]);
/* Update our average RSSI. */
urtwn_update_avgrssi(sc, rate, rssi);
}
@@ -1794,11 +1985,18 @@ urtwn_tx(struct urtwn_softc *sc, struct
raid = R92C_RAID_11B;
else
raid = R92C_RAID_11BG;
- txd->txdw1 |= htole32(
- SM(R92C_TXDW1_MACID, URTWN_MACID_BSS) |
- SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
- SM(R92C_TXDW1_RAID, raid) |
- R92C_TXDW1_AGGBK);
+ if (sc->chip & URTWN_CHIP_88E) {
+ txd->txdw1 |= htole32(
+ SM(R88E_TXDW1_MACID, URTWN_MACID_BSS) |
+ SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
+ SM(R92C_TXDW1_RAID, raid));
+ txd->txdw2 |= htole32(R88E_TXDW2_AGGBK);
+ } else {
+ txd->txdw1 |= htole32(
+ SM(R92C_TXDW1_MACID, URTWN_MACID_BSS) |
+ SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
+ SM(R92C_TXDW1_RAID, raid) | R92C_TXDW1_AGGBK);
+ }

if (ic->ic_flags & IEEE80211_F_USEPROT) {
if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
@@ -2018,9 +2216,16 @@ urtwn_ioctl(struct ifnet *ifp, u_long cm
return (error);
}

-int
+__inline int
urtwn_power_on(struct urtwn_softc *sc)
{
+
+ return sc->sc_power_on(sc);
+}
+
+int
+urtwn_r92c_power_on(struct urtwn_softc *sc)
+{
uint32_t reg;
int ntries;

@@ -2104,12 +2309,73 @@ urtwn_power_on(struct urtwn_softc *sc)
- /* Reserve pages [0; R92C_TX_PAGE_COUNT]. */
- for (i = 0; i < R92C_TX_PAGE_COUNT; i++) {
+ 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;
+
+ /* Reserve pages [0; page_count]. */
+ for (i = 0; i < page_count; i++) {
if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
return (error);
}
@@ -2117,15 +2383,15 @@ urtwn_llt_init(struct urtwn_softc *sc)
if ((error = urtwn_llt_write(sc, i, 0xff)) != 0)
return (error);
/*
- * Use pages [R92C_TX_PAGE_COUNT + 1; R92C_TXPKTBUF_COUNT - 1]
+ * Use pages [page_count + 1; pktbuf_count - 1]
* as ring buffer.
*/
- for (++i; i < R92C_TXPKTBUF_COUNT - 1; i++) {
+ for (++i; i < pktbuf_count - 1; i++) {
if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
return (error);
}
/* Make the last page point to the beginning of the ring buffer. */
- error = urtwn_llt_write(sc, i, R92C_TX_PAGE_COUNT + 1);
+ error = urtwn_llt_write(sc, i, page_count + 1);
return (error);
}

@@ -2147,6 +2413,20 @@ urtwn_fw_reset(struct urtwn_softc *sc)
}
/* Force 8051 reset. */
urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
+ urtwn_write_2(sc, R92C_SYS_FUNC_EN,
+ urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
+ R92C_SYS_FUNC_EN_CPUEN);
+}
+
+
+void
+urtwn_r88e_fw_reset(struct urtwn_softc *sc)
+{
+ uint16_t reg;
+
+ reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
+ urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
+ urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg | R92C_SYS_FUNC_EN_CPUEN);
}

int
@@ -2188,8 +2468,10 @@ urtwn_load_firmware(struct urtwn_softc *
int mlen, ntries, page, error;

/* Read firmware image from the filesystem. */
- if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
- URTWN_CHIP_UMC_A_CUT)
+ if (sc->chip & URTWN_CHIP_88E)
+ name = "urtwn-rtl8188eufw";
+ else if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
+ URTWN_CHIP_UMC_A_CUT)
name = "urtwn-rtl8192cfwU";
else
name = "urtwn-rtl8192cfwT";
@@ -2207,6 +2489,7 @@ urtwn_load_firmware(struct urtwn_softc *
hdr = (const struct r92c_fw_hdr *)ptr;
/* Check if there is a valid FW header and skip it. */
if ((letoh16(hdr->signature) >> 4) == 0x88c ||
+ (le16toh(hdr->signature) >> 4) == 0x88e ||
(letoh16(hdr->signature) >> 4) == 0x92c) {
DPRINTF(("FW V%d.%d %02d-%02d %02d:%02d\n",
letoh16(hdr->version), letoh16(hdr->subversion),
@@ -2215,13 +2498,14 @@ urtwn_load_firmware(struct urtwn_softc *
len -= sizeof(*hdr);
}

- if (urtwn_read_1(sc, R92C_MCUFWDL) & 0x80) {
- urtwn_fw_reset(sc);
+ if (urtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL) {
+ if (sc->chip & URTWN_CHIP_88E)
+ urtwn_r88e_fw_reset(sc);
+ else
+ urtwn_fw_reset(sc);
urtwn_write_1(sc, R92C_MCUFWDL, 0);
}
- urtwn_write_2(sc, R92C_SYS_FUNC_EN,
- urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
- R92C_SYS_FUNC_EN_CPUEN);
+
urtwn_write_1(sc, R92C_MCUFWDL,
urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_EN);
urtwn_write_1(sc, R92C_MCUFWDL + 2,
@@ -2262,6 +2546,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 (sc->chip & URTWN_CHIP_88E)
+ urtwn_r88e_fw_reset(sc);
/* Wait for firmware readiness. */
for (ntries = 0; ntries < 1000; ntries++) {
if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_WINTINI_RDY)
@@ -2279,9 +2565,16 @@ urtwn_load_firmware(struct urtwn_softc *
return (error);
}

-int
+__inline int
urtwn_dma_init(struct urtwn_softc *sc)
{
+
+ return sc->sc_dma_init(sc);
+}
+
+int
+urtwn_r92c_dma_init(struct urtwn_softc *sc)
+{
int hashq, hasnq, haslq, nqueues, nqpages, nrempages;
uint32_t reg;
int error;
@@ -2359,14 +2652,77 @@ urtwn_dma_init(struct urtwn_softc *sc)
return (0);
}

+int
+urtwn_r88e_dma_init(struct urtwn_softc *sc)
+{
+ usb_interface_descriptor_t *id;
+ uint32_t reg;
+ int nrempages, nqpages, nqueues = 1;
+ int error;
+
+ /* Initialize LLT table. */
+ error = urtwn_llt_init(sc);
+ if (error != 0)
+ return (error);
+
+ /* Get Tx queues to USB endpoints mapping. */
+ id = usbd_get_interface_descriptor(sc->sc_iface);
+ nqueues = id->bNumEndpoints - 1;
+
+ /* Get the number of pages for each queue. */
+ nqpages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) / nqueues;
+ /* The remaining pages are assigned to the high priority queue. */
+ nrempages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) % nqueues;
+
+ /* Set number of pages for normal priority queue. */
+ if (sc->chip & URTWN_CHIP_88E) {
+ for (i = 0; i < nitems(rtl8188eu_mac); i++) {
+ urtwn_write_1(sc, rtl8188eu_mac[i].reg,
+ rtl8188eu_mac[i].val);
+ }
+ urtwn_write_1(sc, R92C_MAX_AGGR_NUM, 0x07);
+ } else {
+ for (i = 0; i < nitems(rtl8192cu_mac); i++)
+ urtwn_write_1(sc, rtl8192cu_mac[i].reg,
+ rtl8192cu_mac[i].val);
+ }
}

void
@@ -2374,6 +2730,7 @@ urtwn_bb_init(struct urtwn_softc *sc)
{
const struct urtwn_bb_prog *prog;
uint32_t reg;
+ uint8_t crystalcap;
int i;

/* Enable BB and RF. */
@@ -2382,7 +2739,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);

- urtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
+ if (!(sc->chip & URTWN_CHIP_88E))
+ urtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);

urtwn_write_1(sc, R92C_RF_CTRL,
R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
@@ -2390,12 +2748,16 @@ 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);

- urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
- urtwn_write_1(sc, 0x15, 0xe9);
- urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
+ urtwn_write_1(sc, 0x15, 0xe9);
+ urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
+ }

/* Select BB programming based on board type. */
- if (!(sc->chip & URTWN_CHIP_92C)) {
+ if (sc->chip & URTWN_CHIP_88E)
+ prog = &rtl8188eu_bb_prog;
+ else if (!(sc->chip & URTWN_CHIP_92C)) {
if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
prog = &rtl8188ce_bb_prog;
else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
@@ -2460,9 +2822,25 @@ urtwn_bb_init(struct urtwn_softc *sc)
DELAY(1);
}

- if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) &
- R92C_HSSI_PARAM2_CCK_HIPWR)
- sc->sc_flags |= URTWN_FLAG_CCK_HIPWR;
+ if (sc->chip & URTWN_CHIP_88E) {
+ urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553422);
+ DELAY(1);
+ urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553420);
+ DELAY(1);
+
+ crystalcap = sc->r88e_rom[0xb9];
+ if (crystalcap == 0xff)
+ crystalcap = 0x20;
+ crystalcap &= 0x3f;
+ reg = urtwn_bb_read(sc, R92C_AFE_XTAL_CTRL);
+ urtwn_bb_write(sc, R92C_AFE_XTAL_CTRL,
+ RW(reg, R92C_AFE_XTAL_CTRL_ADDR,
+ crystalcap | crystalcap << 6));
+ } else {
+ if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) &
+ R92C_HSSI_PARAM2_CCK_HIPWR)
+ sc->sc_flags |= URTWN_FLAG_CCK_HIPWR;
+ }
}

void
@@ -2473,7 +2851,9 @@ urtwn_rf_init(struct urtwn_softc *sc)
int i, j, idx, off;

/* Select RF programming based on board type. */
- if (!(sc->chip & URTWN_CHIP_92C)) {
+ if (sc->chip & URTWN_CHIP_88E)
+ prog = rtl8188eu_rf_prog;
+ else if (!(sc->chip & URTWN_CHIP_92C)) {
if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
prog = rtl8188ce_rf_prog;
else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
@@ -2764,6 +3144,75 @@ urtwn_get_txpower(struct urtwn_softc *sc
@@ -2772,7 +3221,10 @@ urtwn_set_txpower(struct urtwn_softc *sc

for (i = 0; i < sc->ntxchains; i++) {
/* Compute per-rate Tx power values. */
- urtwn_get_txpower(sc, i, c, extc, power);
+ if (sc->chip & URTWN_CHIP_88E)
+ urtwn_r88e_get_txpower(sc, i, c, extc, power);
+ else
+ urtwn_get_txpower(sc, i, c, extc, power);
/* Write per-rate Tx power values to hardware. */
urtwn_write_txpower(sc, i, power);
}
@@ -2845,13 +3297,17 @@ 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);

- urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
- urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) |
- R92C_FPGA0_ANAPARAM2_CBW20);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
+ urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) |
+ R92C_FPGA0_ANAPARAM2_CBW20);
+ }

/* Select 20MHz bandwidth. */
urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
- (sc->rf_chnlbw[0] & ~0xfff) | R92C_RF_CHNLBW_BW20 | chan);
+ (sc->rf_chnlbw[0] & ~0xfff) | chan |
+ ((sc->chip & URTWN_CHIP_88E) ? R88E_RF_CHNLBW_BW20 :
+ R92C_RF_CHNLBW_BW20));
}
}

@@ -3026,6 +3482,7 @@ urtwn_init(struct ifnet *ifp)
sc->sc_dev.dv_xname);
goto fail;
}
+
/* Power on adapter. */
error = urtwn_power_on(sc);
if (error != 0)
@@ -3040,8 +3497,19 @@ urtwn_init(struct ifnet *ifp)
urtwn_write_1(sc, R92C_RX_DRVINFO_SZ, 4);

/* Init interrupts. */
- urtwn_write_4(sc, R92C_HISR, 0xffffffff);
- urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
+ if (sc->chip & URTWN_CHIP_88E) {
+ 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);
+ } else {
+ urtwn_write_4(sc, R92C_HISR, 0xffffffff);
+ urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
+ }

/* Set MAC address. */
IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
@@ -3067,10 +3535,12 @@ urtwn_init(struct ifnet *ifp)
urtwn_edca_init(sc);

/* Setup rate fallback. */
- urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000);
- urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404);
- urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201);
- urtwn_write_4(sc, R92C_RARFRC + 4, 0x08070605);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000);
+ urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404);
+ urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201);
+ urtwn_write_4(sc, R92C_RARFRC + 4, 0x08070605);
+ }

urtwn_write_1(sc, R92C_FWHW_TXQ_CTRL,
urtwn_read_1(sc, R92C_FWHW_TXQ_CTRL) |
@@ -3085,27 +3555,33 @@ urtwn_init(struct ifnet *ifp)
urtwn_write_1(sc, R92C_TRXDMA_CTRL,
urtwn_read_1(sc, R92C_TRXDMA_CTRL) |
R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
- urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
- urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
- R92C_USB_SPECIAL_OPTION_AGG_EN);
urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
- urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
- urtwn_write_1(sc, R92C_USB_AGG_TH, 8);
- urtwn_write_1(sc, R92C_USB_AGG_TO, 6);
+ if (sc->chip & URTWN_CHIP_88E)
+ urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH + 1, 4);
+ else {
+ urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
+ urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
+ urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
+ R92C_USB_SPECIAL_OPTION_AGG_EN);
+ urtwn_write_1(sc, R92C_USB_AGG_TH, 8);
+ urtwn_write_1(sc, R92C_USB_AGG_TO, 6);
+ }

/* Initialize beacon parameters. */
+ urtwn_write_2(sc, R92C_BCN_CTRL, 0x1010);
urtwn_write_2(sc, R92C_TBTT_PROHIBIT, 0x6404);
urtwn_write_1(sc, R92C_DRVERLYINT, 0x05);
urtwn_write_1(sc, R92C_BCNDMATIM, 0x02);
urtwn_write_2(sc, R92C_BCNTCFG, 0x660f);

- /* Setup AMPDU aggregation. */
- urtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */
- urtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
- urtwn_write_2(sc, 0x4ca, 0x0708);
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ /* Setup AMPDU aggregation. */
+ urtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */
+ urtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
+ urtwn_write_2(sc, R92C_MAX_AGGR_NUM, 0x0708);

- urtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff);
- urtwn_write_1(sc, R92C_BCN_CTRL, R92C_BCN_CTRL_DIS_TSF_UDT0);
+ urtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff);
+ }

/* Load 8051 microcode. */
error = urtwn_load_firmware(sc);
@@ -3117,6 +3593,12 @@ urtwn_init(struct ifnet *ifp)
urtwn_bb_init(sc);
urtwn_rf_init(sc);

+ if (sc->chip & URTWN_CHIP_88E) {
+ urtwn_write_2(sc, R92C_CR,
+ urtwn_read_2(sc, R92C_CR) | R92C_CR_MACTXEN |
+ R92C_CR_MACRXEN);
+ }
+
/* Turn CCK and OFDM blocks on. */
reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
reg |= R92C_RFMOD_CCK_EN;
@@ -3137,18 +3619,21 @@ urtwn_init(struct ifnet *ifp)
diff -u -p -r1.4 if_urtwnreg.h
--- sys/dev/usb/if_urtwnreg.h 15 Apr 2013 09:23:01 -0000 1.4
+++ sys/dev/usb/if_urtwnreg.h 4 May 2015 10:10:00 -0000
0 new messages