summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Matthew <jmatthew@cvs.openbsd.org>2018-09-21 01:45:54 +0000
committerJonathan Matthew <jmatthew@cvs.openbsd.org>2018-09-21 01:45:54 +0000
commit84b9575109bad934f45fdafeac6b98b2fbc1faff (patch)
treee6b8b3a642788aa7a131605a60a66ff8a4437a86
parent34e0fdd2259803fff4a8402b7ed5f2c3c7592f36 (diff)
Add support for RTL8188EE.
This needs a new firmware image, which should be added to the rtwn firmware package shortly. testing and lots of help from kevlo@ ok kevlo@ stsp@
-rw-r--r--sys/dev/ic/r92creg.h54
-rw-r--r--sys/dev/ic/rtwn.c54
-rw-r--r--sys/dev/ic/rtwnvar.h20
-rw-r--r--sys/dev/pci/if_rtwn.c462
4 files changed, 529 insertions, 61 deletions
diff --git a/sys/dev/ic/r92creg.h b/sys/dev/ic/r92creg.h
index c2be8db4696..8dbf64c72c6 100644
--- a/sys/dev/ic/r92creg.h
+++ b/sys/dev/ic/r92creg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: r92creg.h,v 1.17 2018/09/13 09:28:07 kevlo Exp $ */
+/* $OpenBSD: r92creg.h,v 1.18 2018/09/21 01:45:53 jmatthew Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -58,6 +58,8 @@
#define R92C_FSISR 0x054
#define R92C_HSIMR 0x058
#define R92C_HSISR 0x05c
+#define R92C_AFE_XTAL_CTRL_EXT 0x078
+#define R88E_XCK_OUT_CTRL 0x07c
#define R92C_MCUFWDL 0x080
#define R92C_HMEBOX_EXT(idx) (0x088 + (idx) * 2)
#define R88E_HIMR 0x0b0
@@ -96,6 +98,7 @@
#define R92C_MBIST_START 0x174
#define R92C_MBIST_DONE 0x178
#define R92C_MBIST_FAIL 0x17c
+#define R88E_32K_CTRL 0x194
#define R92C_C2HEVT_MSG 0x1a0
#define R92C_C2HEVT_CLEAR 0x1af
#define R92C_C2HEVT_MSG_TEST 0x1b8
@@ -117,6 +120,7 @@
/* Rx DMA Configuration. */
#define R92C_RXDMA_AGG_PG_TH 0x280
#define R92C_RXPKT_NUM 0x284
+#define R88E_RXDMA_CTRL 0x286
#define R92C_RXDMA_STATUS 0x288
#define R92C_PCIE_CTRL_REG 0x300
@@ -165,8 +169,9 @@
#define R92C_RD_RESP_PKT_TH 0x463
#define R92C_INIRTS_RATE_SEL 0x480
#define R92C_INIDATA_RATE_SEL(macid) (0x484 + (macid))
-#define R88E_TX_RPT_CTRL 0x4ec
#define R92C_MAX_AGGR_NUM 0x4ca
+#define R88E_TX_RPT_CTRL 0x4ec
+#define R88E_TX_RPT_TIME 0x4f0
/* EDCA Configuration. */
#define R92C_EDCA_VO_PARAM 0x500
#define R92C_EDCA_VI_PARAM 0x504
@@ -329,6 +334,9 @@
#define R92C_AFE_XTAL_CTRL_ADDR_M 0x007ff800
#define R92C_AFE_XTAL_CTRL_ADDR_S 11
+/* Bits for R88E_XCK_OUT_CTRL. */
+#define R88E_XCK_OUT_CTRL_EN 1
+
/* Bits for R92C_EFUSE_CTRL. */
#define R92C_EFUSE_CTRL_DATA_M 0x000000ff
#define R92C_EFUSE_CTRL_DATA_S 0
@@ -339,6 +347,7 @@
/* Bits for R92C_GPIO_MUXCFG. */
#define R92C_GPIO_MUXCFG_RFKILL 0x0008
#define R92C_GPIO_MUXCFG_ENBT 0x0020
+#define R92C_GPIO_MUXCFG_ENSIC 0x1000
/* Bits for R92C_GPIO_IO_SEL. */
#define R92C_GPIO_IO_SEL_RFKILL 0x0008
@@ -365,10 +374,30 @@
#define R92C_MCUFWDL_CPRST 0x00800000
/* Bits for R88E_HIMR. */
+#define R88E_HIMR_ROK 0x00000001
+#define R88E_HIMR_RDU 0x00000002
+#define R88E_HIMR_VODOK 0x00000004
+#define R88E_HIMR_VIDOK 0x00000008
+#define R88E_HIMR_BEDOK 0x00000010
+#define R88E_HIMR_BKDOK 0x00000020
+#define R88E_HIMR_MGNTDOK 0x00000040
+#define R88E_HIMR_HIGHDOK 0x00000080
#define R88E_HIMR_CPWM 0x00000100
#define R88E_HIMR_CPWM2 0x00000200
+#define R88E_HIMR_C2HCMD 0x00000400
+#define R88E_HIMR_HISR1_IND_INT 0x00000800
+#define R88E_HIMR_ATIMEND 0x00001000
+#define R88E_HIMR_BCNDMAINT_E 0x00004000
+#define R88E_HIMR_HSISR_IND_ON_INT 0x00008000
+#define R88E_HIMR_BCNDOK0 0x00010000
+#define R88E_HIMR_BCNDMAINT0 0x00100000
+#define R88E_HIMR_TSF_BIT32_TOGGLE 0x01000000
+#define R88E_HIMR_TBDOK 0x02000000
#define R88E_HIMR_TBDER 0x04000000
+#define R88E_HIMR_GTINT3 0x08000000
+#define R88E_HIMR_GTINT4 0x10000000
#define R88E_HIMR_PSTIMEOUT 0x20000000
+#define R88E_HIMR_TXCCK 0x40000000
/* Bits for R88E_HIMRE.*/
#define R88E_HIMRE_RXFOVW 0x00000100
@@ -376,6 +405,13 @@
#define R88E_HIMRE_RXERR 0x00000400
#define R88E_HIMRE_TXERR 0x00000800
+/* Bits for R88E_HSIMR */
+#define R88E_HSIMR_GPIO12_0_INT_EN 0x00000001
+#define R88E_HSIMR_SPS_OCP_INT_EN 0x00000020
+#define R88E_HSIMR_RON_INT_EN 0x00000040
+#define R88E_HSIMR_PDN_INT_EN 0x00000080
+#define R88E_HSIMR_GPIO9_INT_EN 0x02000000
+
/* Bits for R92C_EFUSE_ACCESS. */
#define R92C_EFUSE_ACCESS_OFF 0x00
#define R92C_EFUSE_ACCESS_ON 0x69
@@ -1100,7 +1136,7 @@ struct r88e_tx_pwr {
} __packed;
/*
- * RTL8188EU ROM image.
+ * RTL8188E ROM images.
*/
struct r88e_rom {
uint16_t id;
@@ -1119,6 +1155,18 @@ struct r88e_rom {
uint8_t reserved4[3];
uint8_t rf_ant_opt;
uint8_t reserved5[6];
+} __packed;
+
+struct r88e_pci_rom {
+ uint8_t macaddr[IEEE80211_ADDR_LEN];
+ uint16_t vid;
+ uint16_t did;
+ uint16_t svid;
+ uint16_t smid;
+ uint8_t reserved[290];
+} __packed;
+
+struct r88e_usb_rom {
uint16_t vid;
uint16_t pid;
uint8_t usb_opt;
diff --git a/sys/dev/ic/rtwn.c b/sys/dev/ic/rtwn.c
index 01aca68667f..8ede63992db 100644
--- a/sys/dev/ic/rtwn.c
+++ b/sys/dev/ic/rtwn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtwn.c,v 1.37 2018/09/13 09:28:07 kevlo Exp $ */
+/* $OpenBSD: rtwn.c,v 1.38 2018/09/21 01:45:53 jmatthew Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -637,18 +637,29 @@ rtwn_r88e_read_rom(struct rtwn_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
struct r88e_rom *rom = &sc->sc_r88e_rom;
+ struct r88e_pci_rom *pcirom = &sc->sc_r88e_pci_rom;
+ struct r88e_usb_rom *usbrom = &sc->sc_r88e_usb_rom;
+ int romsize;
+
+ if (sc->chip & RTWN_CHIP_PCI)
+ romsize = sizeof(struct r88e_pci_rom);
+ else
+ romsize = sizeof(struct r88e_usb_rom);
/* Read full ROM image. */
rtwn_efuse_read(sc, (uint8_t *)&sc->sc_r88e_rom,
- sizeof(sc->sc_r88e_rom));
+ sizeof(sc->sc_r88e_rom) + romsize);
- sc->crystal_cap = rom->xtal;
+ sc->crystal_cap = (sc->chip & RTWN_CHIP_PCI) ? 0x20 : rom->xtal;
DPRINTF(("Crystal cap=0x%x\n", sc->crystal_cap));
sc->regulatory = MS(rom->rf_board_opt, R92C_ROM_RF1_REGULATORY);
DPRINTF(("regulatory type=%d\n", sc->regulatory));
- IEEE80211_ADDR_COPY(ic->ic_myaddr, rom->macaddr);
+ if (sc->chip & RTWN_CHIP_PCI)
+ IEEE80211_ADDR_COPY(ic->ic_myaddr, pcirom->macaddr);
+ else
+ IEEE80211_ADDR_COPY(ic->ic_myaddr, usbrom->macaddr);
}
int
@@ -1729,6 +1740,13 @@ rtwn_rf_init(struct rtwn_softc *sc)
sc->rf_chnlbw[i] = rtwn_rf_read(sc, i, R92C_RF_CHNLBW);
}
+ /* magic value for HP 8188EEs */
+ if (sc->chip == (RTWN_CHIP_88E | RTWN_CHIP_PCI)) {
+ struct r88e_pci_rom *pcirom = &sc->sc_r88e_pci_rom;
+ if ((pcirom->svid == 0x103c) && (pcirom->smid == 0x197d))
+ rtwn_rf_write(sc, 0, 0x52, 0x7e4bd);
+ }
+
if ((sc->chip & (RTWN_CHIP_UMC_A_CUT | RTWN_CHIP_92C)) ==
RTWN_CHIP_UMC_A_CUT) {
rtwn_rf_write(sc, 0, R92C_RF_RX_G1, 0x30255);
@@ -2186,6 +2204,9 @@ rtwn_set_chan(struct rtwn_softc *sc, struct ieee80211_channel *c,
((sc->chip & RTWN_CHIP_88E) ? R88E_RF_CHNLBW_BW20 :
R92C_RF_CHNLBW_BW20));
}
+
+ if (sc->chip == (RTWN_CHIP_88E | RTWN_CHIP_PCI))
+ DELAY(25000);
}
int
@@ -2609,12 +2630,23 @@ rtwn_enable_intr(struct rtwn_softc *sc)
{
if (sc->chip & RTWN_CHIP_88E) {
rtwn_write_4(sc, R88E_HISR, 0xffffffff);
- rtwn_write_4(sc, R88E_HIMR, R88E_HIMR_CPWM |
- R88E_HIMR_CPWM2 | R88E_HIMR_TBDER |
- R88E_HIMR_PSTIMEOUT);
- rtwn_write_4(sc, R88E_HIMRE, R88E_HIMRE_RXFOVW |
- R88E_HIMRE_TXFOVW | R88E_HIMRE_RXERR |
- R88E_HIMRE_TXERR);
+ if (sc->chip & RTWN_CHIP_USB) {
+ rtwn_write_4(sc, R88E_HIMR, R88E_HIMR_CPWM |
+ R88E_HIMR_CPWM2 | R88E_HIMR_TBDER |
+ R88E_HIMR_PSTIMEOUT);
+ rtwn_write_4(sc, R88E_HIMRE, R88E_HIMRE_RXFOVW |
+ R88E_HIMRE_TXFOVW | R88E_HIMRE_RXERR |
+ R88E_HIMRE_TXERR);
+ } else {
+ rtwn_write_4(sc, R88E_HIMR,
+ RTWN_88E_INT_ENABLE);
+ rtwn_write_4(sc, R88E_HIMRE,
+ R88E_HIMRE_RXFOVW);
+ rtwn_write_1(sc, R92C_C2HEVT_CLEAR, 0);
+ rtwn_write_4(sc, R92C_HSIMR,
+ R88E_HSIMR_PDN_INT_EN | R88E_HSIMR_RON_INT_EN);
+ }
+
if (sc->chip & RTWN_CHIP_USB) {
rtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
rtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
@@ -2626,7 +2658,7 @@ rtwn_enable_intr(struct rtwn_softc *sc)
if (sc->chip & RTWN_CHIP_USB)
imask = 0xffffffff;
else if (sc->chip & RTWN_CHIP_PCI)
- imask = RTWN_INT_ENABLE;
+ imask = RTWN_92C_INT_ENABLE;
else
panic("unknown chip type 0x%x", sc->chip);
diff --git a/sys/dev/ic/rtwnvar.h b/sys/dev/ic/rtwnvar.h
index a5a3c674c6e..698c76a2b78 100644
--- a/sys/dev/ic/rtwnvar.h
+++ b/sys/dev/ic/rtwnvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtwnvar.h,v 1.10 2017/07/08 14:26:23 kevlo Exp $ */
+/* $OpenBSD: rtwnvar.h,v 1.11 2018/09/21 01:45:53 jmatthew Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -48,10 +48,14 @@ struct rtwn_ops {
#define RTWN_LED_LINK 0
#define RTWN_LED_DATA 1
-#define RTWN_INT_ENABLE (R92C_IMR_ROK | R92C_IMR_VODOK | R92C_IMR_VIDOK | \
+#define RTWN_92C_INT_ENABLE (R92C_IMR_ROK | R92C_IMR_VODOK | R92C_IMR_VIDOK | \
R92C_IMR_BEDOK | R92C_IMR_BKDOK | R92C_IMR_MGNTDOK | \
R92C_IMR_HIGHDOK | R92C_IMR_BDOK | R92C_IMR_RDU | \
R92C_IMR_RXFOVW)
+#define RTWN_88E_INT_ENABLE (R88E_HIMR_PSTIMEOUT | R88E_HIMR_HSISR_IND_ON_INT | \
+ R88E_HIMR_C2HCMD | R88E_HIMR_ROK | R88E_HIMR_VODOK | \
+ R88E_HIMR_VIDOK | R88E_HIMR_BEDOK | R88E_HIMR_BKDOK | \
+ R88E_HIMR_MGNTDOK | R88E_HIMR_HIGHDOK | R88E_HIMR_RDU)
struct rtwn_softc {
/* sc_ops must be initialized by the attachment driver! */
@@ -95,10 +99,18 @@ struct rtwn_softc {
int fwcur;
union {
struct r92c_rom r92c_rom;
- struct r88e_rom r88e_rom;
+ struct {
+ struct r88e_rom r88e_rom;
+ union {
+ struct r88e_pci_rom pci;
+ struct r88e_usb_rom usb;
+ } u;
+ } __packed _88e;
} u;
#define sc_r92c_rom u.r92c_rom
-#define sc_r88e_rom u.r88e_rom
+#define sc_r88e_rom u._88e.r88e_rom
+#define sc_r88e_pci_rom u._88e.u.pci
+#define sc_r88e_usb_rom u._88e.u.usb
uint32_t rf_chnlbw[R92C_MAX_CHAINS];
};
diff --git a/sys/dev/pci/if_rtwn.c b/sys/dev/pci/if_rtwn.c
index c146cee5877..f9a713bb9a4 100644
--- a/sys/dev/pci/if_rtwn.c
+++ b/sys/dev/pci/if_rtwn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_rtwn.c,v 1.32 2018/09/13 09:28:07 kevlo Exp $ */
+/* $OpenBSD: if_rtwn.c,v 1.33 2018/09/21 01:45:53 jmatthew Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -19,7 +19,7 @@
*/
/*
- * PCI front-end for Realtek RTL8188CE/RTL8192CE driver.
+ * PCI front-end for Realtek RTL8188CE/RTL8188EE/RTL8192CE driver.
*/
#include "bpfilter.h"
@@ -64,6 +64,7 @@
* Driver definitions.
*/
+#define R92C_NPQ_NPAGES 0
#define R92C_PUBQ_NPAGES 176
#define R92C_HPQ_NPAGES 41
#define R92C_LPQ_NPAGES 28
@@ -71,6 +72,17 @@
#define R92C_TX_PAGE_COUNT \
(R92C_PUBQ_NPAGES + R92C_HPQ_NPAGES + R92C_LPQ_NPAGES)
#define R92C_TX_PAGE_BOUNDARY (R92C_TX_PAGE_COUNT + 1)
+#define R92C_MAX_RX_DMA_SIZE 0x2800
+
+#define R88E_NPQ_NPAGES 0
+#define R88E_PUBQ_NPAGES 116
+#define R88E_HPQ_NPAGES 41
+#define R88E_LPQ_NPAGES 13
+#define R88E_TXPKTBUF_COUNT 176
+#define R88E_TX_PAGE_COUNT \
+ (R88E_PUBQ_NPAGES + R88E_HPQ_NPAGES + R88E_LPQ_NPAGES)
+#define R88E_TX_PAGE_BOUNDARY (R88E_TX_PAGE_COUNT + 1)
+#define R88E_MAX_RX_DMA_SIZE 0x2600
#define RTWN_NTXQUEUES 9
#define RTWN_RX_LIST_COUNT 256
@@ -202,6 +214,7 @@ extern int rtwn_debug;
static const struct pci_matchid rtwn_pci_devices[] = {
{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RTL8188CE },
+ { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RTL8188EE },
{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RTL8192CE }
};
@@ -229,12 +242,15 @@ int rtwn_tx(void *, struct mbuf *, struct ieee80211_node *);
void rtwn_tx_done(struct rtwn_pci_softc *, int);
int rtwn_alloc_buffers(void *);
int rtwn_pci_init(void *);
+void rtwn_pci_88e_stop(struct rtwn_pci_softc *);
void rtwn_pci_stop(void *);
int rtwn_intr(void *);
int rtwn_is_oactive(void *);
+int rtwn_92c_power_on(struct rtwn_pci_softc *);
+int rtwn_88e_power_on(struct rtwn_pci_softc *);
int rtwn_power_on(void *);
int rtwn_llt_write(struct rtwn_pci_softc *, uint32_t, uint32_t);
-int rtwn_llt_init(struct rtwn_pci_softc *);
+int rtwn_llt_init(struct rtwn_pci_softc *, int);
int rtwn_dma_init(void *);
int rtwn_fw_loadpage(void *, int, uint8_t *, int);
int rtwn_pci_load_firmware(void *, u_char **, size_t *);
@@ -373,7 +389,16 @@ rtwn_pci_attach(struct device *parent, struct device *self, void *aux)
sc->sc_sc.sc_ops.cancel_scan = rtwn_cancel_scan;
sc->sc_sc.sc_ops.wait_async = rtwn_wait_async;
- sc->sc_sc.chip = RTWN_CHIP_88C | RTWN_CHIP_92C | RTWN_CHIP_PCI;
+ sc->sc_sc.chip = RTWN_CHIP_PCI;
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_REALTEK_RTL8188CE:
+ case PCI_PRODUCT_REALTEK_RTL8192CE:
+ sc->sc_sc.chip |= RTWN_CHIP_88C | RTWN_CHIP_92C;
+ break;
+ case PCI_PRODUCT_REALTEK_RTL8188EE:
+ sc->sc_sc.chip |= RTWN_CHIP_88E;
+ break;
+ }
error = rtwn_attach(&sc->sc_dev, &sc->sc_sc);
if (error != 0) {
@@ -790,6 +815,30 @@ rtwn_rx_frame(struct rtwn_pci_softc *sc, struct r92c_rx_desc_pci *rx_desc,
rxdw0 = letoh32(rx_desc->rxdw0);
rxdw3 = letoh32(rx_desc->rxdw3);
+ if (sc->sc_sc.chip & RTWN_CHIP_88E) {
+ int ntries, type;
+ struct r88e_tx_rpt_ccx *rxstat;
+
+ type = MS(rxdw3, R88E_RXDW3_RPT);
+ if (type == R88E_RXDW3_RPT_TX1) {
+ uint32_t rptb1, rptb2;
+
+ rxstat = mtod(rx_data->m, struct r88e_tx_rpt_ccx *);
+ rptb1 = letoh32(rxstat->rptb1);
+ rptb2 = letoh32(rxstat->rptb2);
+ ntries = MS(rptb2, R88E_RPTB2_RETRY_CNT);
+ if (rptb1 & R88E_RPTB1_PKT_OK)
+ sc->amn.amn_txcnt++;
+ if (ntries > 0)
+ sc->amn.amn_retrycnt++;
+
+ rtwn_setup_rx_desc(sc, rx_desc,
+ rx_data->map->dm_segs[0].ds_addr, MCLBYTES,
+ desc_idx);
+ return;
+ }
+ }
+
if (__predict_false(rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR))) {
/*
* This should not happen since we setup our Rx filter
@@ -996,11 +1045,20 @@ rtwn_tx(void *cookie, struct mbuf *m, struct ieee80211_node *ni)
raid = R92C_RAID_11B;
else
raid = R92C_RAID_11BG;
- txd->txdw1 |= htole32(
- SM(R92C_TXDW1_MACID, R92C_MACID_BSS) |
- SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
- SM(R92C_TXDW1_RAID, raid) |
- R92C_TXDW1_AGGBK);
+
+ if (sc->sc_sc.chip & RTWN_CHIP_88E) {
+ txd->txdw1 |= htole32(
+ SM(R88E_TXDW1_MACID, R92C_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, R92C_MACID_BSS) |
+ SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
+ SM(R92C_TXDW1_RAID, raid) |
+ R92C_TXDW1_AGGBK);
+ }
/* Request TX status report for AMRR. */
txd->txdw2 |= htole32(R92C_TXDW2_CCX_RPT);
@@ -1178,23 +1236,133 @@ rtwn_pci_init(void *cookie)
{
struct rtwn_pci_softc *sc = cookie;
ieee80211_amrr_node_init(&sc->amrr, &sc->amn);
+
+ /* Enable TX reports for AMRR */
+ if (sc->sc_sc.chip & RTWN_CHIP_88E) {
+ rtwn_pci_write_1(sc, R88E_TX_RPT_CTRL,
+ (rtwn_pci_read_1(sc, R88E_TX_RPT_CTRL) & ~0) |
+ R88E_TX_RPT_CTRL_EN);
+ rtwn_pci_write_1(sc, R88E_TX_RPT_CTRL + 1, 0x02);
+
+ rtwn_pci_write_2(sc, R88E_TX_RPT_TIME, 0xcdf0);
+ }
+
return (0);
}
void
+rtwn_pci_88e_stop(struct rtwn_pci_softc *sc)
+{
+ int i, s;
+ uint16_t reg;
+
+ s = splnet();
+
+ /* Disable interrupts. */
+ rtwn_pci_write_4(sc, R88E_HIMR, 0x00000000);
+
+ /* Stop hardware. */
+ rtwn_pci_write_1(sc, R88E_TX_RPT_CTRL,
+ rtwn_pci_read_1(sc, R88E_TX_RPT_CTRL) &
+ ~(R88E_TX_RPT_CTRL_EN));
+
+ for (i = 0; i < 100; i++) {
+ if (rtwn_pci_read_1(sc, R88E_RXDMA_CTRL) & 0x02)
+ break;
+ DELAY(10);
+ }
+ if (i == 100)
+ DPRINTF(("rxdma ctrl didn't go off, %x\n", rtwn_pci_read_1(sc, R88E_RXDMA_CTRL)));
+
+ rtwn_pci_write_1(sc, R92C_PCIE_CTRL_REG + 1, 0xff);
+
+ rtwn_pci_write_1(sc, R92C_TXPAUSE, R92C_TXPAUSE_ALL);
+
+ /* ensure transmission has stopped */
+ for (i = 0; i < 100; i++) {
+ if (rtwn_pci_read_4(sc, 0x5f8) == 0)
+ break;
+ DELAY(10);
+ }
+ if (i == 100)
+ DPRINTF(("tx didn't stop\n"));
+
+ rtwn_pci_write_1(sc, R92C_SYS_FUNC_EN,
+ rtwn_pci_read_1(sc, R92C_SYS_FUNC_EN) &
+ ~(R92C_SYS_FUNC_EN_BBRSTB));
+ DELAY(1);
+ reg = rtwn_pci_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_MACTXEN | R92C_CR_MACRXEN |
+ R92C_CR_ENSEC);
+ rtwn_pci_write_2(sc, R92C_CR, reg);
+ rtwn_pci_write_1(sc, R92C_DUAL_TSF_RST,
+ rtwn_pci_read_1(sc, R92C_DUAL_TSF_RST) | 0x20);
+
+ rtwn_pci_write_1(sc, R92C_RF_CTRL, 0x00);
+ if (rtwn_pci_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL)
+ rtwn_fw_reset(&sc->sc_sc);
+
+ rtwn_pci_write_1(sc, R92C_SYS_FUNC_EN + 1,
+ rtwn_pci_read_1(sc, R92C_SYS_FUNC_EN + 1) & ~0x02);
+ rtwn_pci_write_1(sc, R92C_MCUFWDL, 0);
+
+ rtwn_pci_write_1(sc, R88E_32K_CTRL,
+ rtwn_pci_read_1(sc, R88E_32K_CTRL) & ~(0x01));
+
+ /* transition to cardemu state */
+ rtwn_pci_write_1(sc, R92C_RF_CTRL, 0);
+ rtwn_pci_write_1(sc, R92C_LPLDO_CTRL,
+ rtwn_pci_read_1(sc, R92C_LPLDO_CTRL) | 0x10);
+ rtwn_pci_write_2(sc, R92C_APS_FSMCO,
+ rtwn_pci_read_2(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_OFF);
+ for (i = 0; i < 100; i++) {
+ if ((rtwn_pci_read_2(sc, R92C_APS_FSMCO) &
+ R92C_APS_FSMCO_APFM_OFF) == 0)
+ break;
+ DELAY(10);
+ }
+ if (i == 100)
+ DPRINTF(("apfm off didn't go off\n"));
+
+ /* transition to card disabled state */
+ rtwn_pci_write_1(sc, R92C_AFE_XTAL_CTRL + 2,
+ rtwn_pci_read_1(sc, R92C_AFE_XTAL_CTRL + 2) | 0x80);
+
+ rtwn_pci_write_1(sc, R92C_RSV_CTRL + 1,
+ rtwn_pci_read_1(sc, R92C_RSV_CTRL + 1) & ~(0x08));
+ rtwn_pci_write_1(sc, R92C_RSV_CTRL + 1,
+ rtwn_pci_read_1(sc, R92C_RSV_CTRL + 1) | 0x08);
+
+ rtwn_pci_write_1(sc, R92C_RSV_CTRL, 0x0e);
+
+ for (i = 0; i < RTWN_NTXQUEUES; i++)
+ rtwn_reset_tx_list(sc, i);
+ rtwn_reset_rx_list(sc);
+
+ splx(s);
+}
+
+void
rtwn_pci_stop(void *cookie)
{
struct rtwn_pci_softc *sc = cookie;
uint16_t reg;
int i, s;
+ if (sc->sc_sc.chip & RTWN_CHIP_88E) {
+ rtwn_pci_88e_stop(sc);
+ return;
+ }
+
s = splnet();
/* Disable interrupts. */
rtwn_pci_write_4(sc, R92C_HIMR, 0x00000000);
/* Stop hardware. */
- rtwn_pci_write_1(sc, R92C_TXPAUSE, 0xff);
+ rtwn_pci_write_1(sc, R92C_TXPAUSE, R92C_TXPAUSE_ALL);
rtwn_pci_write_1(sc, R92C_RF_CTRL, 0x00);
reg = rtwn_pci_read_1(sc, R92C_SYS_FUNC_EN);
reg |= R92C_SYS_FUNC_EN_BB_GLB_RST;
@@ -1224,12 +1392,77 @@ rtwn_pci_stop(void *cookie)
}
int
+rtwn_88e_intr(struct rtwn_pci_softc *sc)
+{
+ u_int32_t status, estatus;
+ int i;
+
+ status = rtwn_pci_read_4(sc, R88E_HISR);
+ if (status == 0 || status == 0xffffffff)
+ return (0);
+
+ estatus = rtwn_pci_read_4(sc, R88E_HISRE);
+
+ status &= RTWN_88E_INT_ENABLE;
+ estatus &= R88E_HIMRE_RXFOVW;
+
+ rtwn_pci_write_4(sc, R88E_HIMR, 0);
+ rtwn_pci_write_4(sc, R88E_HIMRE, 0);
+ rtwn_pci_write_4(sc, R88E_HISR, status);
+ rtwn_pci_write_4(sc, R88E_HISRE, estatus);
+
+ if (status & R88E_HIMR_HIGHDOK)
+ rtwn_tx_done(sc, RTWN_HIGH_QUEUE);
+ if (status & R88E_HIMR_MGNTDOK)
+ rtwn_tx_done(sc, RTWN_MGNT_QUEUE);
+ if (status & R88E_HIMR_BKDOK)
+ rtwn_tx_done(sc, RTWN_BK_QUEUE);
+ if (status & R88E_HIMR_BEDOK)
+ rtwn_tx_done(sc, RTWN_BE_QUEUE);
+ if (status & R88E_HIMR_VIDOK)
+ rtwn_tx_done(sc, RTWN_VI_QUEUE);
+ if (status & R88E_HIMR_VODOK)
+ rtwn_tx_done(sc, RTWN_VO_QUEUE);
+ if ((status & (R88E_HIMR_ROK | R88E_HIMR_RDU)) ||
+ (estatus & R88E_HIMRE_RXFOVW)) {
+ bus_dmamap_sync(sc->sc_dmat, sc->rx_ring.map, 0,
+ sizeof(struct r92c_rx_desc_pci) * RTWN_RX_LIST_COUNT,
+ BUS_DMASYNC_POSTREAD);
+
+ for (i = 0; i < RTWN_RX_LIST_COUNT; i++) {
+ struct r92c_rx_desc_pci *rx_desc = &sc->rx_ring.desc[i];
+ struct rtwn_rx_data *rx_data = &sc->rx_ring.rx_data[i];
+
+ if (letoh32(rx_desc->rxdw0) & R92C_RXDW0_OWN)
+ continue;
+
+ rtwn_rx_frame(sc, rx_desc, rx_data, i);
+ }
+ }
+
+ if (status & R88E_HIMR_HSISR_IND_ON_INT) {
+ rtwn_pci_write_1(sc, R92C_HSISR,
+ rtwn_pci_read_1(sc, R92C_HSISR) |
+ R88E_HSIMR_PDN_INT_EN | R88E_HSIMR_RON_INT_EN);
+ }
+
+ /* Enable interrupts. */
+ rtwn_pci_write_4(sc, R88E_HIMR, RTWN_88E_INT_ENABLE);
+ rtwn_pci_write_4(sc, R88E_HIMRE, R88E_HIMRE_RXFOVW);
+
+ return (1);
+}
+
+int
rtwn_intr(void *xsc)
{
struct rtwn_pci_softc *sc = xsc;
u_int32_t status;
int i;
+ if (sc->sc_sc.chip & RTWN_CHIP_88E)
+ return (rtwn_88e_intr(sc));
+
status = rtwn_pci_read_4(sc, R92C_HISR);
if (status == 0 || status == 0xffffffff)
return (0);
@@ -1273,7 +1506,7 @@ rtwn_intr(void *xsc)
rtwn_tx_done(sc, RTWN_VO_QUEUE);
/* Enable interrupts. */
- rtwn_pci_write_4(sc, R92C_HIMR, RTWN_INT_ENABLE);
+ rtwn_pci_write_4(sc, R92C_HIMR, RTWN_92C_INT_ENABLE);
return (1);
}
@@ -1306,12 +1539,15 @@ rtwn_llt_write(struct rtwn_pci_softc *sc, uint32_t addr, uint32_t data)
}
int
-rtwn_llt_init(struct rtwn_pci_softc *sc)
+rtwn_llt_init(struct rtwn_pci_softc *sc, int page_count)
{
- int i, error;
+ int i, error, pktbuf_count;
- /* Reserve pages [0; R92C_TX_PAGE_COUNT]. */
- for (i = 0; i < R92C_TX_PAGE_COUNT; i++) {
+ pktbuf_count = (sc->sc_sc.chip & RTWN_CHIP_88E) ?
+ R88E_TXPKTBUF_COUNT : R92C_TXPKTBUF_COUNT;
+
+ /* Reserve pages [0; page_count]. */
+ for (i = 0; i < page_count; i++) {
if ((error = rtwn_llt_write(sc, i, i + 1)) != 0)
return (error);
}
@@ -1319,22 +1555,21 @@ rtwn_llt_init(struct rtwn_pci_softc *sc)
if ((error = rtwn_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 = rtwn_llt_write(sc, i, i + 1)) != 0)
return (error);
}
/* Make the last page point to the beginning of the ring buffer. */
- error = rtwn_llt_write(sc, i, R92C_TX_PAGE_COUNT + 1);
+ error = rtwn_llt_write(sc, i, pktbuf_count + 1);
return (error);
}
int
-rtwn_power_on(void *cookie)
+rtwn_92c_power_on(struct rtwn_pci_softc *sc)
{
- struct rtwn_pci_softc *sc = cookie;
uint32_t reg;
int ntries;
@@ -1464,43 +1699,164 @@ rtwn_power_on(void *cookie)
}
int
+rtwn_88e_power_on(struct rtwn_pci_softc *sc)
+{
+ uint32_t reg;
+ int ntries;
+
+ /* Disable XTAL output for power saving. */
+ rtwn_pci_write_1(sc, R88E_XCK_OUT_CTRL,
+ rtwn_pci_read_1(sc, R88E_XCK_OUT_CTRL) & ~R88E_XCK_OUT_CTRL_EN);
+
+ rtwn_pci_write_2(sc, R92C_APS_FSMCO,
+ rtwn_pci_read_2(sc, R92C_APS_FSMCO) & (~R92C_APS_FSMCO_APDM_HPDN));
+ rtwn_pci_write_1(sc, R92C_RSV_CTRL, 0);
+
+ /* Wait for power ready bit. */
+ for (ntries = 0; ntries < 5000; ntries++) {
+ if (rtwn_pci_read_4(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_SUS_HOST)
+ break;
+ DELAY(10);
+ }
+ if (ntries == 5000) {
+ printf("%s: timeout waiting for chip power up\n",
+ sc->sc_dev.dv_xname);
+ return (ETIMEDOUT);
+ }
+
+ /* Reset BB. */
+ rtwn_pci_write_1(sc, R92C_SYS_FUNC_EN,
+ rtwn_pci_read_1(sc, R92C_SYS_FUNC_EN) & ~(R92C_SYS_FUNC_EN_BBRSTB |
+ R92C_SYS_FUNC_EN_BB_GLB_RST));
+
+ rtwn_pci_write_1(sc, R92C_AFE_XTAL_CTRL + 2,
+ rtwn_pci_read_1(sc, R92C_AFE_XTAL_CTRL + 2) | 0x80);
+
+ /* Disable HWPDN. */
+ rtwn_pci_write_2(sc, R92C_APS_FSMCO,
+ rtwn_pci_read_2(sc, R92C_APS_FSMCO) & ~R92C_APS_FSMCO_APDM_HPDN);
+ /* Disable WL suspend. */
+ rtwn_pci_write_2(sc, R92C_APS_FSMCO,
+ rtwn_pci_read_2(sc, R92C_APS_FSMCO) &
+ ~(R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_AFSM_PCIE));
+
+ /* Auto enable WLAN. */
+ rtwn_pci_write_2(sc, R92C_APS_FSMCO,
+ rtwn_pci_read_2(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC);
+ for (ntries = 0; ntries < 5000; ntries++) {
+ if (!(rtwn_pci_read_2(sc, R92C_APS_FSMCO) &
+ R92C_APS_FSMCO_APFM_ONMAC))
+ break;
+ DELAY(10);
+ }
+ if (ntries == 5000) {
+ printf("%s: timeout waiting for MAC auto ON\n",
+ sc->sc_dev.dv_xname);
+ return (ETIMEDOUT);
+ }
+
+ /* Enable LDO normal mode. */
+ rtwn_pci_write_1(sc, R92C_LPLDO_CTRL,
+ rtwn_pci_read_1(sc, R92C_LPLDO_CTRL) & ~0x10);
+
+ rtwn_pci_write_1(sc, R92C_APS_FSMCO,
+ rtwn_pci_read_1(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_PDN_EN);
+ rtwn_pci_write_1(sc, R92C_PCIE_CTRL_REG + 2,
+ rtwn_pci_read_1(sc, R92C_PCIE_CTRL_REG + 2) | 0x04);
+
+ rtwn_pci_write_1(sc, R92C_AFE_XTAL_CTRL_EXT + 1,
+ rtwn_pci_read_1(sc, R92C_AFE_XTAL_CTRL_EXT + 1) | 0x02);
+
+ rtwn_pci_write_1(sc, R92C_SYS_CLKR,
+ rtwn_pci_read_1(sc, R92C_SYS_CLKR) | 0x08);
+
+ rtwn_pci_write_2(sc, R92C_GPIO_MUXCFG,
+ rtwn_pci_read_2(sc, R92C_GPIO_MUXCFG) & ~R92C_GPIO_MUXCFG_ENSIC);
+
+ /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
+ rtwn_pci_write_2(sc, R92C_CR, 0);
+ reg = rtwn_pci_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_MACTXEN | R92C_CR_MACRXEN |
+ R92C_CR_ENSEC | R92C_CR_CALTMR_EN;
+ rtwn_pci_write_2(sc, R92C_CR, reg);
+
+ rtwn_pci_write_1(sc, R92C_MSR, 0);
+ return (0);
+}
+
+int
+rtwn_power_on(void *cookie)
+{
+ struct rtwn_pci_softc *sc = cookie;
+
+ if (sc->sc_sc.chip & RTWN_CHIP_88E)
+ return (rtwn_88e_power_on(sc));
+ else
+ return (rtwn_92c_power_on(sc));
+}
+
+int
rtwn_dma_init(void *cookie)
{
struct rtwn_pci_softc *sc = cookie;
uint32_t reg;
+ uint16_t dmasize;
+ int hqpages, lqpages, nqpages, pagecnt, boundary, trxdma, tcr;
int error;
+ if (sc->sc_sc.chip & RTWN_CHIP_88E) {
+ nqpages = R88E_NPQ_NPAGES;
+ hqpages = R88E_HPQ_NPAGES;
+ lqpages = R88E_LPQ_NPAGES;
+ pagecnt = R88E_TX_PAGE_COUNT;
+ boundary = R88E_TX_PAGE_BOUNDARY;
+ dmasize = R88E_MAX_RX_DMA_SIZE;
+ tcr = R92C_TCR_CFENDFORM | R92C_TCR_ERRSTEN3;
+ trxdma = 0xe771;
+ } else {
+ nqpages = R92C_NPQ_NPAGES;
+ hqpages = R92C_HPQ_NPAGES;
+ lqpages = R92C_LPQ_NPAGES;
+ pagecnt = R92C_TX_PAGE_COUNT;
+ boundary = R92C_TX_PAGE_BOUNDARY;
+ dmasize = R92C_MAX_RX_DMA_SIZE;
+ tcr = R92C_TCR_CFENDFORM | R92C_TCR_ERRSTEN0 |
+ R92C_TCR_ERRSTEN1;
+ trxdma = 0xf771;
+ }
+
/* Initialize LLT table. */
- error = rtwn_llt_init(sc);
+ error = rtwn_llt_init(sc, pagecnt);
if (error != 0)
return error;
/* Set number of pages for normal priority queue. */
- rtwn_pci_write_2(sc, R92C_RQPN_NPQ, 0);
+ rtwn_pci_write_2(sc, R92C_RQPN_NPQ, nqpages);
rtwn_pci_write_4(sc, R92C_RQPN,
/* Set number of pages for public queue. */
- SM(R92C_RQPN_PUBQ, R92C_PUBQ_NPAGES) |
+ SM(R92C_RQPN_PUBQ, pagecnt) |
/* Set number of pages for high priority queue. */
- SM(R92C_RQPN_HPQ, R92C_HPQ_NPAGES) |
+ SM(R92C_RQPN_HPQ, hqpages) |
/* Set number of pages for low priority queue. */
- SM(R92C_RQPN_LPQ, R92C_LPQ_NPAGES) |
+ SM(R92C_RQPN_LPQ, lqpages) |
/* Load values. */
R92C_RQPN_LD);
- rtwn_pci_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R92C_TX_PAGE_BOUNDARY);
- rtwn_pci_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R92C_TX_PAGE_BOUNDARY);
+ rtwn_pci_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, boundary);
+ rtwn_pci_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, boundary);
rtwn_pci_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD,
- R92C_TX_PAGE_BOUNDARY);
- rtwn_pci_write_1(sc, R92C_TRXFF_BNDY, R92C_TX_PAGE_BOUNDARY);
- rtwn_pci_write_1(sc, R92C_TDECTRL + 1, R92C_TX_PAGE_BOUNDARY);
+ boundary);
+ rtwn_pci_write_1(sc, R92C_TRXFF_BNDY, boundary);
+ rtwn_pci_write_1(sc, R92C_TDECTRL + 1, boundary);
reg = rtwn_pci_read_2(sc, R92C_TRXDMA_CTRL);
reg &= ~R92C_TRXDMA_CTRL_QMAP_M;
- reg |= 0xF771;
+ reg |= trxdma;
rtwn_pci_write_2(sc, R92C_TRXDMA_CTRL, reg);
- rtwn_pci_write_4(sc, R92C_TCR,
- R92C_TCR_CFENDFORM | R92C_TCR_ERRSTEN0 | R92C_TCR_ERRSTEN1);
+ rtwn_pci_write_4(sc, R92C_TCR, tcr);
/* Configure Tx DMA. */
rtwn_pci_write_4(sc, R92C_BKQ_DESA,
@@ -1520,9 +1876,10 @@ rtwn_dma_init(void *cookie)
/* Configure Rx DMA. */
rtwn_pci_write_4(sc, R92C_RX_DESA, sc->rx_ring.map->dm_segs[0].ds_addr);
+ rtwn_pci_write_1(sc, R92C_PCIE_CTRL_REG+1, 0);
/* Set Tx/Rx transfer page boundary. */
- rtwn_pci_write_2(sc, R92C_TRXFF_BNDY + 2, 0x27ff);
+ rtwn_pci_write_2(sc, R92C_TRXFF_BNDY + 2, dmasize - 1);
/* Set Tx/Rx transfer page size. */
rtwn_pci_write_1(sc, R92C_PBP,
@@ -1569,7 +1926,9 @@ rtwn_pci_load_firmware(void *cookie, u_char **fw, size_t *len)
const char *name;
int error;
- if ((sc->sc_sc.chip & (RTWN_CHIP_UMC_A_CUT | RTWN_CHIP_92C)) ==
+ if (sc->sc_sc.chip & RTWN_CHIP_88E)
+ name = "rtwn-rtl8188efw";
+ else if ((sc->sc_sc.chip & (RTWN_CHIP_UMC_A_CUT | RTWN_CHIP_92C)) ==
RTWN_CHIP_UMC_A_CUT)
name = "rtwn-rtl8192cfwU";
else
@@ -1589,9 +1948,19 @@ rtwn_mac_init(void *cookie)
int i;
/* Write MAC initialization values. */
- for (i = 0; i < nitems(rtl8192ce_mac); i++)
- rtwn_pci_write_1(sc, rtl8192ce_mac[i].reg,
- rtl8192ce_mac[i].val);
+ if (sc->sc_sc.chip & RTWN_CHIP_88E) {
+ for (i = 0; i < nitems(rtl8188eu_mac); i++) {
+ if (rtl8188eu_mac[i].reg == R92C_GPIO_MUXCFG)
+ continue;
+ rtwn_pci_write_1(sc, rtl8188eu_mac[i].reg,
+ rtl8188eu_mac[i].val);
+ }
+ rtwn_pci_write_1(sc, R92C_MAX_AGGR_NUM, 0x07);
+ } else {
+ for (i = 0; i < nitems(rtl8192ce_mac); i++)
+ rtwn_pci_write_1(sc, rtl8192ce_mac[i].reg,
+ rtl8192ce_mac[i].val);
+ }
}
void
@@ -1608,7 +1977,8 @@ rtwn_bb_init(void *cookie)
R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST |
R92C_SYS_FUNC_EN_DIO_RF);
- rtwn_pci_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
+ if (!(sc->sc_sc.chip & RTWN_CHIP_88E))
+ rtwn_pci_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
rtwn_pci_write_1(sc, R92C_RF_CTRL,
R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
@@ -1618,14 +1988,20 @@ rtwn_bb_init(void *cookie)
R92C_SYS_FUNC_EN_PPLL | R92C_SYS_FUNC_EN_BB_GLB_RST |
R92C_SYS_FUNC_EN_BBRSTB);
- rtwn_pci_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
+ if (!(sc->sc_sc.chip & RTWN_CHIP_88E)) {
+ rtwn_pci_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
+ }
rtwn_pci_write_4(sc, R92C_LEDCFG0,
rtwn_pci_read_4(sc, R92C_LEDCFG0) | 0x00800000);
- /* Select BB programming. */
- prog = (sc->sc_sc.chip & RTWN_CHIP_92C) ?
- &rtl8192ce_bb_prog_2t : &rtl8192ce_bb_prog_1t;
+ /* Select BB programming. */
+ if (sc->sc_sc.chip & RTWN_CHIP_88E)
+ prog = &rtl8188eu_bb_prog;
+ else if (!(sc->sc_sc.chip & RTWN_CHIP_92C))
+ prog = &rtl8192ce_bb_prog_1t;
+ else
+ prog = &rtl8192ce_bb_prog_2t;
/* Write BB initialization values. */
for (i = 0; i < prog->count; i++) {