summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/rtwn/rtl8188e
diff options
context:
space:
mode:
authorChristian Mauderer <Christian.Mauderer@embedded-brains.de>2016-11-22 10:41:47 +0100
committerChristian Mauderer <Christian.Mauderer@embedded-brains.de>2017-01-17 12:50:58 +0100
commit0cbb715adeec510cd0556d9807d95eb60b4b6db8 (patch)
tree24759593608739ad0caca52c78b6816aefde5118 /freebsd/sys/dev/rtwn/rtl8188e
parentlib80211/regdomain: Port to RTEMS. (diff)
downloadrtems-libbsd-0cbb715adeec510cd0556d9807d95eb60b4b6db8.tar.bz2
rtwn: Import from FreeBSD.
Diffstat (limited to 'freebsd/sys/dev/rtwn/rtl8188e')
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e.h94
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_beacon.c64
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_calib.c69
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c169
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_fw.c227
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_fw_cmd.h84
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_init.c160
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_led.c70
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_priv.h273
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_reg.h91
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_rf.c62
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_rom.c87
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_defs.h29
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_image.h60
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c213
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_rx_desc.h100
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_tx.c81
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_tx_desc.h38
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu.h39
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c218
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c226
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_reg.h27
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_rx.c76
23 files changed, 2557 insertions, 0 deletions
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e.h b/freebsd/sys/dev/rtwn/rtl8188e/r88e.h
new file mode 100644
index 00000000..999ab400
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e.h
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
+ * $FreeBSD$
+ */
+
+#ifndef RTL8188E_H
+#define RTL8188E_H
+
+/*
+ * Global definitions.
+ */
+#define R88E_PUBQ_NPAGES 142
+#define R88E_TXPKTBUF_COUNT 177
+#define R88E_TX_PAGE_COUNT 169
+
+#define R88E_MACID_MAX 63
+#define R88E_RX_DMA_BUFFER_SIZE 0x2400
+
+#define R88E_INTR_MSG_LEN 60
+
+#define R88E_CALIB_THRESHOLD 4
+
+
+/*
+ * Function declarations.
+ */
+/* r88e_beacon.c */
+void r88e_beacon_enable(struct rtwn_softc *, int, int);
+
+/* r88e_calib.c */
+void r88e_iq_calib(struct rtwn_softc *);
+void r88e_temp_measure(struct rtwn_softc *);
+uint8_t r88e_temp_read(struct rtwn_softc *);
+
+/* r88e_chan.c */
+void r88e_get_txpower(struct rtwn_softc *, int,
+ struct ieee80211_channel *, uint16_t[]);
+void r88e_set_bw20(struct rtwn_softc *, uint8_t);
+void r88e_set_gain(struct rtwn_softc *, uint8_t);
+
+/* r88e_fw.c */
+#ifndef RTWN_WITHOUT_UCODE
+int r88e_fw_cmd(struct rtwn_softc *, uint8_t, const void *, int);
+void r88e_fw_reset(struct rtwn_softc *, int);
+void r88e_fw_download_enable(struct rtwn_softc *, int);
+#endif
+void r88e_macid_enable_link(struct rtwn_softc *, int, int);
+void r88e_set_media_status(struct rtwn_softc *, int);
+#ifndef RTWN_WITHOUT_UCODE
+int r88e_set_rsvd_page(struct rtwn_softc *, int, int, int);
+int r88e_set_pwrmode(struct rtwn_softc *, struct ieee80211vap *, int);
+#endif
+
+/* r88e_init.c */
+void r88e_init_bb(struct rtwn_softc *);
+void r88e_init_rf(struct rtwn_softc *);
+int r88e_power_on(struct rtwn_softc *);
+
+/* r88e_led.c */
+void r88e_set_led(struct rtwn_softc *, int, int);
+
+/* r88e_rf.c */
+void r88e_rf_write(struct rtwn_softc *, int, uint8_t, uint32_t);
+
+/* r88e_rom.c */
+void r88e_parse_rom(struct rtwn_softc *, uint8_t *);
+
+/* r88e_rx.c */
+void r88e_ratectl_tx_complete(struct rtwn_softc *, uint8_t *, int);
+void r88e_handle_c2h_report(struct rtwn_softc *, uint8_t *, int);
+int8_t r88e_get_rssi_cck(struct rtwn_softc *, void *);
+int8_t r88e_get_rssi_ofdm(struct rtwn_softc *, void *);
+
+/* r88e_tx.c */
+void r88e_tx_enable_ampdu(void *, int);
+void r88e_tx_setup_hwseq(void *);
+void r88e_tx_setup_macid(void *, int);
+
+#endif /* RTL8188E_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_beacon.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_beacon.c
new file mode 100644
index 00000000..752b29dd
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_beacon.c
@@ -0,0 +1,64 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/*-
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/rtwn/if_rtwnvar.h>
+
+#include <dev/rtwn/rtl8188e/r88e.h>
+#include <dev/rtwn/rtl8188e/r88e_reg.h>
+
+
+void
+r88e_beacon_enable(struct rtwn_softc *sc, int id, int enable)
+{
+
+ if (enable) {
+ rtwn_setbits_1(sc, R92C_MBID_NUM, 0, R88E_MBID_TXBCN_RPT(id));
+ rtwn_setbits_1(sc, R92C_BCN_CTRL(id),
+ 0, R92C_BCN_CTRL_EN_BCN);
+ } else {
+ rtwn_setbits_1(sc, R92C_MBID_NUM, R88E_MBID_TXBCN_RPT(id), 0);
+ rtwn_setbits_1(sc, R92C_BCN_CTRL(id),
+ R92C_BCN_CTRL_EN_BCN, 0);
+ }
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_calib.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_calib.c
new file mode 100644
index 00000000..c996749a
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_calib.c
@@ -0,0 +1,69 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/*-
+ * Copyright (c) 2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/rtwn/if_rtwnreg.h>
+#include <dev/rtwn/if_rtwnvar.h>
+
+#include <dev/rtwn/rtl8188e/r88e.h>
+#include <dev/rtwn/rtl8188e/r88e_reg.h>
+
+
+void
+r88e_iq_calib(struct rtwn_softc *sc)
+{
+ /* XXX TODO */
+}
+
+void
+r88e_temp_measure(struct rtwn_softc *sc)
+{
+ rtwn_rf_write(sc, 0, R88E_RF_T_METER, R88E_RF_T_METER_START);
+}
+
+uint8_t
+r88e_temp_read(struct rtwn_softc *sc)
+{
+ return (MS(rtwn_rf_read(sc, 0, R88E_RF_T_METER),
+ R88E_RF_T_METER_VAL));
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c
new file mode 100644
index 00000000..405edb2b
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c
@@ -0,0 +1,169 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/rtwn/if_rtwnreg.h>
+#include <dev/rtwn/if_rtwnvar.h>
+
+#include <dev/rtwn/if_rtwn_debug.h>
+#include <dev/rtwn/if_rtwn_ridx.h>
+
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+
+#include <dev/rtwn/rtl8188e/r88e.h>
+#include <dev/rtwn/rtl8188e/r88e_priv.h>
+#include <dev/rtwn/rtl8188e/r88e_reg.h>
+
+
+static int
+r88e_get_power_group(struct rtwn_softc *sc, struct ieee80211_channel *c)
+{
+ uint8_t chan;
+ int group;
+
+ chan = rtwn_chan2centieee(c);
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ 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 if (chan <= 14) group = 5;
+ else {
+ KASSERT(0, ("wrong 2GHz channel %d!\n", chan));
+ return (-1);
+ }
+ } else {
+ KASSERT(0, ("wrong channel band (flags %08X)\n", c->ic_flags));
+ return (-1);
+ }
+
+ return (group);
+}
+
+void
+r88e_get_txpower(struct rtwn_softc *sc, int chain,
+ struct ieee80211_channel *c, uint16_t power[RTWN_RIDX_COUNT])
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ const struct rtwn_r88e_txpwr *rt = rs->rs_txpwr;
+ const struct rtwn_r88e_txagc *base = rs->rs_txagc;
+ uint16_t cckpow, ofdmpow, bw20pow, htpow;
+ int max_mcs, ridx, group;
+
+ /* Determine channel group. */
+ group = r88e_get_power_group(sc, c);
+ if (group == -1) { /* shouldn't happen */
+ device_printf(sc->sc_dev, "%s: incorrect channel\n", __func__);
+ return;
+ }
+
+ /* XXX net80211 regulatory */
+
+ max_mcs = RTWN_RIDX_MCS(sc->ntxchains * 8 - 1);
+ KASSERT(max_mcs <= RTWN_RIDX_COUNT, ("increase ridx limit\n"));
+
+ memset(power, 0, max_mcs * sizeof(power[0]));
+ if (rs->regulatory == 0) {
+ for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++)
+ power[ridx] = base->pwr[0][ridx];
+ }
+ for (ridx = RTWN_RIDX_OFDM6; ridx < RTWN_RIDX_COUNT; ridx++) {
+ if (rs->regulatory == 3)
+ power[ridx] = base->pwr[0][ridx];
+ else if (rs->regulatory == 1) {
+ if (!IEEE80211_IS_CHAN_HT40(c))
+ power[ridx] = base->pwr[group][ridx];
+ } else if (rs->regulatory != 2)
+ power[ridx] = base->pwr[0][ridx];
+ }
+
+ /* Compute per-CCK rate Tx power. */
+ cckpow = rt->cck_tx_pwr[group];
+ for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++)
+ power[ridx] += cckpow;
+
+ htpow = rt->ht40_tx_pwr[group];
+
+ /* Compute per-OFDM rate Tx power. */
+ ofdmpow = htpow + rt->ofdm_tx_pwr_diff;
+ for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++)
+ power[ridx] += ofdmpow;
+
+ bw20pow = htpow + rt->bw20_tx_pwr_diff;
+ for (ridx = RTWN_RIDX_MCS(0); ridx <= max_mcs; ridx++)
+ power[ridx] += bw20pow;
+
+ /* Apply max limit. */
+ for (ridx = RTWN_RIDX_CCK1; ridx <= max_mcs; ridx++) {
+ if (power[ridx] > R92C_MAX_TX_PWR)
+ power[ridx] = R92C_MAX_TX_PWR;
+ }
+}
+
+void
+r88e_set_bw20(struct rtwn_softc *sc, uint8_t chan)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+
+ rtwn_setbits_1(sc, R92C_BWOPMODE, 0, R92C_BWOPMODE_20MHZ);
+
+ rtwn_bb_setbits(sc, R92C_FPGA0_RFMOD, R92C_RFMOD_40MHZ, 0);
+ rtwn_bb_setbits(sc, R92C_FPGA1_RFMOD, R92C_RFMOD_40MHZ, 0);
+
+ /* Select 20MHz bandwidth. */
+ rtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
+ (rs->rf_chnlbw[0] & ~0xfff) | chan | R88E_RF_CHNLBW_BW20);
+}
+
+void
+r88e_set_gain(struct rtwn_softc *sc, uint8_t gain)
+{
+
+ rtwn_bb_setbits(sc, R92C_OFDM0_AGCCORE1(0),
+ R92C_OFDM0_AGCCORE1_GAIN_M, gain);
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_fw.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_fw.c
new file mode 100644
index 00000000..409084f6
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_fw.c
@@ -0,0 +1,227 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/rtwn/if_rtwnreg.h>
+#include <dev/rtwn/if_rtwnvar.h>
+
+#include <dev/rtwn/if_rtwn_debug.h>
+
+#include <dev/rtwn/rtl8188e/r88e.h>
+#include <dev/rtwn/rtl8188e/r88e_reg.h>
+#include <dev/rtwn/rtl8188e/r88e_fw_cmd.h>
+
+
+#ifndef RTWN_WITHOUT_UCODE
+int
+r88e_fw_cmd(struct rtwn_softc *sc, uint8_t id, const void *buf, int len)
+{
+ struct r88e_fw_cmd cmd;
+ int ntries, error;
+
+ if (!(sc->sc_flags & RTWN_FW_LOADED)) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_FIRMWARE, "%s: firmware "
+ "was not loaded; command (id %d) will be discarded\n",
+ __func__, id);
+ return (0);
+ }
+
+ /* Wait for current FW box to be empty. */
+ for (ntries = 0; ntries < 50; ntries++) {
+ if (!(rtwn_read_1(sc, R92C_HMETFR) & (1 << sc->fwcur)))
+ break;
+ rtwn_delay(sc, 2000);
+ }
+ if (ntries == 100) {
+ device_printf(sc->sc_dev,
+ "could not send firmware command\n");
+ return (ETIMEDOUT);
+ }
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.id = id;
+ KASSERT(len <= sizeof(cmd.msg),
+ ("%s: firmware command too long (%d > %zu)\n",
+ __func__, len, sizeof(cmd.msg)));
+ memcpy(cmd.msg, buf, len);
+
+ /* Write the first word last since that will trigger the FW. */
+ if (len > 3) {
+ error = rtwn_write_4(sc, R88E_HMEBOX_EXT(sc->fwcur),
+ *(uint32_t *)((uint8_t *)&cmd + 4));
+ if (error != 0)
+ return (error);
+ }
+ error = rtwn_write_4(sc, R92C_HMEBOX(sc->fwcur), *(uint32_t *)&cmd);
+ if (error != 0)
+ return (error);
+
+ sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX;
+
+ return (0);
+}
+
+void
+r88e_fw_reset(struct rtwn_softc *sc, int reason)
+{
+ uint16_t reg;
+
+ reg = rtwn_read_2(sc, R92C_SYS_FUNC_EN);
+ rtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
+ rtwn_write_2(sc, R92C_SYS_FUNC_EN, reg | R92C_SYS_FUNC_EN_CPUEN);
+}
+
+void
+r88e_fw_download_enable(struct rtwn_softc *sc, int enable)
+{
+ if (enable) {
+ /* MCU firmware download enable. */
+ rtwn_setbits_1(sc, R92C_MCUFWDL, 0, R92C_MCUFWDL_EN);
+ /* 8051 reset. */
+ rtwn_setbits_1_shift(sc, R92C_MCUFWDL, R92C_MCUFWDL_ROM_DLEN,
+ 0, 2);
+ } else {
+ /* MCU download disable. */
+ rtwn_setbits_1(sc, R92C_MCUFWDL, R92C_MCUFWDL_EN, 0);
+ /* Reserved for f/w extension. */
+ rtwn_write_1(sc, R92C_MCUFWDL + 1, 0);
+ }
+}
+#endif
+
+void
+r88e_macid_enable_link(struct rtwn_softc *sc, int id, int enable)
+{
+ uint32_t reg;
+
+ reg = R88E_MACID_NO_LINK;
+ if (id > 32)
+ reg += 4;
+
+ if (enable)
+ rtwn_setbits_4(sc, reg, 1 << (id % 32), 0);
+ else
+ rtwn_setbits_4(sc, reg, 0, 1 << (id % 32));
+
+ /* XXX max macid for tx reports */
+}
+
+void
+r88e_set_media_status(struct rtwn_softc *sc, int macid)
+{
+ struct r88e_fw_cmd_msrrpt status;
+
+ if (macid & RTWN_MACID_VALID)
+ status.msrb0 = R88E_MSRRPT_B0_ASSOC;
+ else
+ status.msrb0 = R88E_MSRRPT_B0_DISASSOC;
+ status.macid = (macid & ~RTWN_MACID_VALID);
+
+ r88e_macid_enable_link(sc, status.macid,
+ (macid & RTWN_MACID_VALID) != 0);
+
+#ifndef RTWN_WITHOUT_UCODE
+ if (r88e_fw_cmd(sc, R88E_CMD_MSR_RPT, &status, sizeof(status)) != 0) {
+ device_printf(sc->sc_dev, "%s: cannot change media status!\n",
+ __func__);
+ }
+#endif
+}
+
+#ifndef RTWN_WITHOUT_UCODE
+int
+r88e_set_rsvd_page(struct rtwn_softc *sc, int probe_resp, int null,
+ int qos_null)
+{
+ struct r88e_fw_cmd_rsvdpage rsvd;
+
+ rsvd.probe_resp = probe_resp;
+ rsvd.ps_poll = 0;
+ rsvd.null_data = null;
+ rsvd.null_data_qos = qos_null;
+ rsvd.null_data_qos_bt = 0;
+ return (r88e_fw_cmd(sc, R88E_CMD_RSVD_PAGE, &rsvd, sizeof(rsvd)));
+}
+
+int
+r88e_set_pwrmode(struct rtwn_softc *sc, struct ieee80211vap *vap,
+ int off)
+{
+ struct r88e_fw_cmd_pwrmode mode;
+ int error;
+
+ if (off && vap->iv_state == IEEE80211_S_RUN &&
+ (vap->iv_flags & IEEE80211_F_PMGTON)) {
+ mode.mode = R88E_PWRMODE_LEG;
+ /*
+ * TODO: switch to RFOFF state
+ * (something is missing here - Rx stops with it).
+ */
+#ifdef RTWN_TODO
+ mode.pwr_state = R88E_PWRMODE_STATE_RFOFF;
+#else
+ mode.pwr_state = R88E_PWRMODE_STATE_RFON;
+#endif
+ } else {
+ mode.mode = R88E_PWRMODE_CAM;
+ mode.pwr_state = R88E_PWRMODE_STATE_ALLON;
+ }
+ mode.pwrb1 =
+ SM(R88E_PWRMODE_B1_SMART_PS, R88E_PWRMODE_B1_LEG_NULLDATA) |
+ SM(R88E_PWRMODE_B1_RLBM, R88E_PWRMODE_B1_MODE_MIN);
+ /* XXX ignored */
+ mode.bcn_pass = 0;
+ mode.queue_uapsd = 0;
+ error = r88e_fw_cmd(sc, R88E_CMD_SET_PWRMODE, &mode, sizeof(mode));
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "%s: CMD_SET_PWRMODE was not sent, error %d\n",
+ __func__, error);
+ }
+
+ return (error);
+}
+#endif
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_fw_cmd.h b/freebsd/sys/dev/rtwn/rtl8188e/r88e_fw_cmd.h
new file mode 100644
index 00000000..c152729c
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_fw_cmd.h
@@ -0,0 +1,84 @@
+/*-
+ * Copyright (c) 2015 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
+ * $FreeBSD$
+ */
+
+#ifndef R88E_FW_CMD_H
+#define R88E_FW_CMD_H
+
+/*
+ * Host to firmware commands.
+ */
+struct r88e_fw_cmd {
+ uint8_t id;
+#define R88E_CMD_RSVD_PAGE 0x00
+#define R88E_CMD_MSR_RPT 0x01
+#define R88E_CMD_SET_PWRMODE 0x20
+
+ uint8_t msg[7];
+} __packed __attribute__((aligned(4)));
+
+/* Structure for R88E_CMD_RSVD_PAGE. */
+struct r88e_fw_cmd_rsvdpage {
+ uint8_t probe_resp;
+ uint8_t ps_poll;
+ uint8_t null_data;
+ uint8_t null_data_qos;
+ uint8_t null_data_qos_bt;
+} __packed;
+
+/* Structure for R88E_CMD_MSR_RPT. */
+struct r88e_fw_cmd_msrrpt {
+ uint8_t msrb0;
+#define R88E_MSRRPT_B0_DISASSOC 0x00
+#define R88E_MSRRPT_B0_ASSOC 0x01
+
+ uint8_t macid;
+} __packed;
+
+/* Structure for R88E_CMD_SET_PWRMODE. */
+struct r88e_fw_cmd_pwrmode {
+ uint8_t mode;
+#define R88E_PWRMODE_CAM 0
+#define R88E_PWRMODE_LEG 1
+#define R88E_PWRMODE_UAPSD 2
+
+ uint8_t pwrb1;
+#define R88E_PWRMODE_B1_RLBM_M 0x0f
+#define R88E_PWRMODE_B1_RLBM_S 0
+#define R88E_PWRMODE_B1_MODE_MIN 0
+#define R88E_PWRMODE_B1_MODE_MAX 1
+#define R88E_PWRMODE_B1_MODE_DTIM 2
+
+#define R88E_PWRMODE_B1_SMART_PS_M 0xf0
+#define R88E_PWRMODE_B1_SMART_PS_S 4
+#define R88E_PWRMODE_B1_LEG_PSPOLL0 0
+#define R88E_PWRMODE_B1_LEG_PSPOLL1 1
+#define R88E_PWRMODE_B1_LEG_NULLDATA 2
+#define R88E_PWRMODE_B1_WMM_PSPOLL 0
+#define R88E_PWRMODE_B1_WMM_NULLDATA 1
+
+ uint8_t bcn_pass;
+ uint8_t queue_uapsd;
+ uint8_t pwr_state;
+#define R88E_PWRMODE_STATE_RFOFF 0x00
+#define R88E_PWRMODE_STATE_RFON 0x04
+#define R88E_PWRMODE_STATE_ALLON 0x0c
+} __packed;
+
+#endif /* R88E_FW_CMD_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_init.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_init.c
new file mode 100644
index 00000000..62e5463b
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_init.c
@@ -0,0 +1,160 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/rtwn/if_rtwnreg.h>
+#include <dev/rtwn/if_rtwnvar.h>
+
+#include <dev/rtwn/if_rtwn_debug.h>
+
+#include <dev/rtwn/rtl8192c/r92c.h>
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+
+#include <dev/rtwn/rtl8188e/r88e.h>
+#include <dev/rtwn/rtl8188e/r88e_reg.h>
+
+
+static void
+r88e_crystalcap_write(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ uint32_t reg;
+ uint8_t val;
+
+ val = rs->crystalcap & 0x3f;
+ reg = rtwn_bb_read(sc, R92C_AFE_XTAL_CTRL);
+ rtwn_bb_write(sc, R92C_AFE_XTAL_CTRL,
+ RW(reg, R92C_AFE_XTAL_CTRL_ADDR, val | val << 6));
+}
+
+void
+r88e_init_bb(struct rtwn_softc *sc)
+{
+
+ /* Enable BB and RF. */
+ rtwn_setbits_2(sc, R92C_SYS_FUNC_EN, 0,
+ R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST |
+ R92C_SYS_FUNC_EN_DIO_RF);
+
+ rtwn_write_1(sc, R92C_RF_CTRL,
+ R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
+ rtwn_write_1(sc, R92C_SYS_FUNC_EN,
+ R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD |
+ R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB);
+
+ r92c_init_bb_common(sc);
+
+ rtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553422);
+ rtwn_delay(sc, 1);
+ rtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553420);
+ rtwn_delay(sc, 1);
+
+ r88e_crystalcap_write(sc);
+}
+
+int
+r88e_power_on(struct rtwn_softc *sc)
+{
+#define RTWN_CHK(res) do { \
+ if (res != 0) \
+ return (EIO); \
+} while(0)
+ int ntries;
+
+ /* Wait for power ready bit. */
+ for (ntries = 0; ntries < 5000; ntries++) {
+ if (rtwn_read_4(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_SUS_HOST)
+ break;
+ rtwn_delay(sc, 10);
+ }
+ if (ntries == 5000) {
+ device_printf(sc->sc_dev,
+ "timeout waiting for chip power up\n");
+ return (ETIMEDOUT);
+ }
+
+ /* Reset BB. */
+ RTWN_CHK(rtwn_setbits_1(sc, R92C_SYS_FUNC_EN,
+ R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST, 0));
+
+ RTWN_CHK(rtwn_setbits_1(sc, R92C_AFE_XTAL_CTRL + 2, 0, 0x80));
+
+ /* Disable HWPDN. */
+ RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
+ R92C_APS_FSMCO_APDM_HPDN, 0, 1));
+
+ /* Disable WL suspend. */
+ RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
+ R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_AFSM_PCIE, 0, 1));
+
+ RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
+ 0, R92C_APS_FSMCO_APFM_ONMAC, 1));
+ for (ntries = 0; ntries < 5000; ntries++) {
+ if (!(rtwn_read_2(sc, R92C_APS_FSMCO) &
+ R92C_APS_FSMCO_APFM_ONMAC))
+ break;
+ rtwn_delay(sc, 10);
+ }
+ if (ntries == 5000)
+ return (ETIMEDOUT);
+
+ /* Enable LDO normal mode. */
+ RTWN_CHK(rtwn_setbits_1(sc, R92C_LPLDO_CTRL,
+ R92C_LPLDO_CTRL_SLEEP, 0));
+
+ /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
+ RTWN_CHK(rtwn_write_2(sc, R92C_CR, 0));
+ RTWN_CHK(rtwn_setbits_2(sc, R92C_CR, 0,
+ R92C_CR_HCI_TXDMA_EN | R92C_CR_TXDMA_EN |
+ R92C_CR_HCI_RXDMA_EN | R92C_CR_RXDMA_EN |
+ R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_EN |
+ ((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0) |
+ R92C_CR_CALTMR_EN));
+
+ return (0);
+#undef RTWN_CHK
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_led.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_led.c
new file mode 100644
index 00000000..02ec644a
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_led.c
@@ -0,0 +1,70 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/rtwn/if_rtwnvar.h>
+
+#include <dev/rtwn/rtl8188e/r88e.h>
+#include <dev/rtwn/rtl8188e/r88e_reg.h>
+
+
+void
+r88e_set_led(struct rtwn_softc *sc, int led, int on)
+{
+
+ if (led == RTWN_LED_LINK) {
+ if (!on) {
+ rtwn_setbits_1(sc, R92C_LEDCFG2, 0x6f,
+ R92C_LEDCFG0_DIS);
+ rtwn_setbits_1(sc, R92C_MAC_PINMUX_CFG, 0x01, 0);
+ } else
+ rtwn_setbits_1(sc, R92C_LEDCFG2, 0x0f, 0x60);
+ sc->ledlink = on; /* Save LED state. */
+ }
+
+ /* XXX led #1? */
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_priv.h b/freebsd/sys/dev/rtwn/rtl8188e/r88e_priv.h
new file mode 100644
index 00000000..cb4f7edb
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_priv.h
@@ -0,0 +1,273 @@
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
+ * $FreeBSD$
+ */
+
+#ifndef R88E_PRIV_H
+#define R88E_PRIV_H
+
+#include <dev/rtwn/rtl8188e/r88e_rom_defs.h>
+
+/*
+ * Parsed Tx power (diff) values.
+ */
+struct rtwn_r88e_txpwr {
+ uint8_t cck_tx_pwr[R88E_GROUP_2G];
+ uint8_t ht40_tx_pwr[R88E_GROUP_2G - 1];
+ int8_t ofdm_tx_pwr_diff;
+ int8_t bw20_tx_pwr_diff;
+};
+
+
+/*
+ * MAC initialization values.
+ */
+static const struct rtwn_mac_prog 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 }
+};
+
+/*
+ * Baseband initialization values.
+ */
+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 struct rtwn_bb_prog rtl8188eu_bb[] = {
+ {
+ nitems(rtl8188eu_bb_regs),
+ rtl8188eu_bb_regs,
+ rtl8188eu_bb_vals,
+ { 0 },
+ NULL
+ }
+};
+
+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 rtwn_agc_prog rtl8188eu_agc[] = {
+ {
+ nitems(rtl8188eu_agc_vals),
+ rtl8188eu_agc_vals,
+ { 0 },
+ NULL
+ }
+};
+
+/*
+ * RF initialization values.
+ */
+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, 0x0c350, 0x0c350, 0x80003,
+ 0x0c350, 0x0c350, 0x00001, 0x80000, 0x33e60
+};
+
+static const struct rtwn_rf_prog rtl8188eu_rf[] = {
+ {
+ nitems(rtl8188eu_rf_regs),
+ rtl8188eu_rf_regs,
+ rtl8188eu_rf_vals,
+ { 0 },
+ NULL
+ },
+ { 0, NULL, NULL, { 0 }, NULL }
+};
+
+
+struct rtwn_r88e_txagc {
+ uint8_t pwr[R88E_GROUP_2G][20]; /* RTWN_RIDX_MCS(7) + 1 */
+};
+
+/*
+ * Per RF chain/group/rate Tx gain values.
+ */
+static const struct rtwn_r88e_txagc r88e_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. */
+ },
+ { /* 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. */
+ },
+ { /* 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. */
+ },
+ { /* 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. */
+ },
+ { /* 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. */
+ },
+ { /* 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. */
+ }
+ } }
+};
+
+#endif /* R88E_PRIV_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_reg.h b/freebsd/sys/dev/rtwn/rtl8188e/r88e_reg.h
new file mode 100644
index 00000000..f6f26fa4
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_reg.h
@@ -0,0 +1,91 @@
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
+ * $FreeBSD$
+ */
+
+#ifndef R88E_REG_H
+#define R88E_REG_H
+
+#include <dev/rtwn/rtl8192c/r92c_reg.h>
+
+/*
+ * MAC registers.
+ */
+/* System Configuration. */
+#define R88E_BB_PAD_CTRL 0x064
+#define R88E_HIMR 0x0b0
+#define R88E_HISR 0x0b4
+#define R88E_HIMRE 0x0b8
+#define R88E_HISRE 0x0bc
+/* MAC General Configuration. */
+#define R88E_32K_CTRL 0x194
+#define R88E_HMEBOX_EXT(idx) (0x1f0 + (idx) * 4)
+/* Protocol Configuration. */
+#define R88E_TXPKTBUF_BCNQ1_BDNY 0x457
+#define R88E_MACID_NO_LINK 0x484
+#define R88E_TX_RPT_CTRL 0x4ec
+#define R88E_TX_RPT_MACID_MAX 0x4ed
+#define R88E_TX_RPT_TIME 0x4f0
+#define R88E_SCH_TXCMD 0x5f8
+
+
+/* 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 R88E_TX_RPT_CTRL. */
+#define R88E_TX_RPT1_ENA 0x01
+#define R88E_TX_RPT2_ENA 0x02
+
+/* Bits for R92C_MBID_NUM. */
+#define R88E_MBID_TXBCN_RPT(id) (0x08 << (id))
+
+/* Bits for R92C_SECCFG. */
+#define R88E_SECCFG_CHK_KEYID 0x0100
+
+
+/*
+ * Baseband registers.
+ */
+/* Bits for R92C_LSSI_PARAM(i). */
+#define R88E_LSSI_PARAM_ADDR_M 0x0ff00000
+#define R88E_LSSI_PARAM_ADDR_S 20
+
+
+/*
+ * RF (6052) registers.
+ */
+#define R88E_RF_T_METER 0x42
+
+/* Bits for R92C_RF_CHNLBW. */
+#define R88E_RF_CHNLBW_BW20 0x00c00
+
+/* Bits for R88E_RF_T_METER. */
+#define R88E_RF_T_METER_VAL_M 0x0fc00
+#define R88E_RF_T_METER_VAL_S 10
+#define R88E_RF_T_METER_START 0x30000
+
+#endif /* R88E_REG_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_rf.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rf.c
new file mode 100644
index 00000000..18991ba8
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rf.c
@@ -0,0 +1,62 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/rtwn/if_rtwnreg.h>
+#include <dev/rtwn/if_rtwnvar.h>
+
+#include <dev/rtwn/rtl8188e/r88e.h>
+#include <dev/rtwn/rtl8188e/r88e_reg.h>
+
+
+void
+r88e_rf_write(struct rtwn_softc *sc, int chain, uint8_t addr, uint32_t val)
+{
+ rtwn_bb_write(sc, R92C_LSSI_PARAM(chain),
+ SM(R88E_LSSI_PARAM_ADDR, addr) |
+ SM(R92C_LSSI_PARAM_DATA, val));
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom.c
new file mode 100644
index 00000000..9fc7c4c4
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom.c
@@ -0,0 +1,87 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/rtwn/if_rtwnreg.h>
+#include <dev/rtwn/if_rtwnvar.h>
+
+#include <dev/rtwn/if_rtwn_debug.h>
+
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+
+#include <dev/rtwn/rtl8188e/r88e.h>
+#include <dev/rtwn/rtl8188e/r88e_priv.h>
+#include <dev/rtwn/rtl8188e/r88e_rom_image.h>
+
+
+void
+r88e_parse_rom(struct rtwn_softc *sc, uint8_t *buf)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ struct rtwn_r88e_txpwr *rt = rs->rs_txpwr;
+ struct r88e_rom *rom = (struct r88e_rom *)buf;
+ int i;
+
+ rt->bw20_tx_pwr_diff = RTWN_SIGN4TO8(MS(rom->tx_pwr_diff, HIGH_PART));
+ rt->ofdm_tx_pwr_diff = RTWN_SIGN4TO8(MS(rom->tx_pwr_diff, LOW_PART));
+ for (i = 0; i < nitems(rom->cck_tx_pwr); i++)
+ rt->cck_tx_pwr[i] = rom->cck_tx_pwr[i];
+ for (i = 0; i < nitems(rom->ht40_tx_pwr); i++)
+ rt->ht40_tx_pwr[i] = rom->ht40_tx_pwr[i];
+
+ rs->crystalcap = RTWN_GET_ROM_VAR(rom->crystalcap,
+ R88E_ROM_CRYSTALCAP_DEF);
+ rs->regulatory = MS(rom->rf_board_opt, R92C_ROM_RF1_REGULATORY);
+ rs->board_type =
+ MS(RTWN_GET_ROM_VAR(rom->rf_board_opt, R92C_BOARD_TYPE_DONGLE),
+ R92C_ROM_RF1_BOARD_TYPE);
+ RTWN_DPRINTF(sc, RTWN_DEBUG_ROM, "%s: regulatory type %d\n",
+ __func__,rs->regulatory);
+
+ sc->thermal_meter = rom->thermal_meter;
+ IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr);
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_defs.h b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_defs.h
new file mode 100644
index 00000000..5734246f
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_defs.h
@@ -0,0 +1,29 @@
+/*-
+ * Copyright (c) 2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef R88E_ROM_DEFS_H
+#define R88E_ROM_DEFS_H
+
+#include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
+
+#define R88E_GROUP_2G 6
+
+#define R88E_EFUSE_MAX_LEN 512
+#define R88E_EFUSE_MAP_LEN 512
+
+#endif /* R88E_ROM_DEFS_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_image.h b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_image.h
new file mode 100644
index 00000000..c80028e0
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_image.h
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef R88E_ROM_IMAGE_H
+#define R88E_ROM_IMAGE_H
+
+#include <dev/rtwn/rtl8188e/r88e_rom_defs.h>
+
+/*
+ * RTL8188EU ROM image.
+ */
+struct r88e_rom {
+ uint8_t reserved1[16];
+ uint8_t cck_tx_pwr[R88E_GROUP_2G];
+ uint8_t ht40_tx_pwr[R88E_GROUP_2G - 1];
+ uint8_t tx_pwr_diff;
+ uint8_t reserved2[156];
+ uint8_t channel_plan;
+ uint8_t crystalcap;
+#define R88E_ROM_CRYSTALCAP_DEF 0x20
+
+ uint8_t thermal_meter;
+ uint8_t reserved3[6];
+ uint8_t rf_board_opt;
+ uint8_t rf_feature_opt;
+ uint8_t rf_bt_opt;
+ uint8_t version;
+ uint8_t customer_id;
+ uint8_t reserved4[3];
+ uint8_t rf_ant_opt;
+ uint8_t reserved5[6];
+ uint16_t vid;
+ uint16_t pid;
+ uint8_t usb_opt;
+ uint8_t reserved6[2];
+ uint8_t macaddr[IEEE80211_ADDR_LEN];
+ uint8_t reserved7[2];
+ uint8_t string[33]; /* "realtek 802.11n NIC" */
+ uint8_t reserved8[256];
+} __packed;
+
+_Static_assert(sizeof(struct r88e_rom) == R88E_EFUSE_MAP_LEN,
+ "R88E_EFUSE_MAP_LEN must be equal to sizeof(struct r88e_rom)!");
+
+#endif /* R88E_ROM_IMAGE_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c
new file mode 100644
index 00000000..464542b4
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c
@@ -0,0 +1,213 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <net80211/ieee80211_ratectl.h>
+
+#include <dev/rtwn/if_rtwnreg.h>
+#include <dev/rtwn/if_rtwnvar.h>
+
+#include <dev/rtwn/if_rtwn_debug.h>
+#include <dev/rtwn/if_rtwn_ridx.h>
+
+#include <dev/rtwn/rtl8188e/r88e.h>
+#include <dev/rtwn/rtl8188e/r88e_rx_desc.h>
+
+
+void
+r88e_ratectl_tx_complete(struct rtwn_softc *sc, uint8_t *buf, int len)
+{
+#if __FreeBSD_version >= 1200012
+ struct ieee80211_ratectl_tx_status txs;
+#endif
+ struct r88e_tx_rpt_ccx *rpt;
+ struct ieee80211_node *ni;
+ uint8_t macid;
+ int ntries;
+
+ /* Skip Rx descriptor. */
+ buf += sizeof(struct r92c_rx_stat);
+ len -= sizeof(struct r92c_rx_stat);
+
+ rpt = (struct r88e_tx_rpt_ccx *)buf;
+ if (len != sizeof(*rpt)) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
+ "%s: wrong report size (%d, must be %zu)\n",
+ __func__, len, sizeof(*rpt));
+ return;
+ }
+
+ RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
+ "%s: ccx report dump: 0: %02X, 1: %02X, 2: %02X, queue time: "
+ "low %02X, high %02X, final ridx: %02X, 6: %02X, 7: %02X\n",
+ __func__, rpt->rptb0, rpt->rptb1, rpt->rptb2, rpt->queue_time_low,
+ rpt->queue_time_high, rpt->final_rate, rpt->rptb6, rpt->rptb7);
+
+ macid = MS(rpt->rptb1, R88E_RPTB1_MACID);
+ if (macid > sc->macid_limit) {
+ device_printf(sc->sc_dev,
+ "macid %u is too big; increase MACID_MAX limit\n",
+ macid);
+ return;
+ }
+
+ ntries = MS(rpt->rptb2, R88E_RPTB2_RETRY_CNT);
+
+ ni = sc->node_list[macid];
+ if (ni != NULL) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: frame for macid %u was"
+ "%s sent (%d retries)\n", __func__, macid,
+ (rpt->rptb1 & R88E_RPTB1_PKT_OK) ? "" : " not",
+ ntries);
+
+#if __FreeBSD_version >= 1200012
+ txs.flags = IEEE80211_RATECTL_STATUS_LONG_RETRY |
+ IEEE80211_RATECTL_STATUS_FINAL_RATE;
+ txs.long_retries = ntries;
+ if (rpt->final_rate > RTWN_RIDX_OFDM54) { /* MCS */
+ txs.final_rate =
+ (rpt->final_rate - 12) | IEEE80211_RATE_MCS;
+ } else
+ txs.final_rate = ridx2rate[rpt->final_rate];
+ if (rpt->rptb1 & R88E_RPTB1_PKT_OK)
+ txs.status = IEEE80211_RATECTL_TX_SUCCESS;
+ else if (rpt->rptb2 & R88E_RPTB2_RETRY_OVER)
+ txs.status = IEEE80211_RATECTL_TX_FAIL_LONG;
+ else if (rpt->rptb2 & R88E_RPTB2_LIFE_EXPIRE)
+ txs.status = IEEE80211_RATECTL_TX_FAIL_EXPIRED;
+ else
+ txs.status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED;
+ ieee80211_ratectl_tx_complete(ni, &txs);
+#else
+ struct ieee80211vap *vap = ni->ni_vap;
+ if (rpt->rptb1 & R88E_RPTB1_PKT_OK) {
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS, &ntries, NULL);
+ } else {
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_FAILURE, &ntries, NULL);
+ }
+#endif
+ } else {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: macid %u, ni is NULL\n",
+ __func__, macid);
+ }
+}
+
+void
+r88e_handle_c2h_report(struct rtwn_softc *sc, uint8_t *buf, int len)
+{
+
+ /* Skip Rx descriptor. */
+ buf += sizeof(struct r92c_rx_stat);
+ len -= sizeof(struct r92c_rx_stat);
+
+ if (len != R88E_INTR_MSG_LEN) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
+ "%s: wrong interrupt message size (%d, must be %d)\n",
+ __func__, len, R88E_INTR_MSG_LEN);
+ return;
+ }
+
+ /* XXX TODO */
+}
+
+int8_t
+r88e_get_rssi_cck(struct rtwn_softc *sc, void *physt)
+{
+ struct r88e_rx_phystat *phy = (struct r88e_rx_phystat *)physt;
+ int8_t lna_idx, vga_idx, rssi;
+
+ lna_idx = (phy->agc_rpt & 0xe0) >> 5;
+ vga_idx = (phy->agc_rpt & 0x1f);
+ rssi = 6 - 2 * vga_idx;
+
+ switch (lna_idx) {
+ case 7:
+ if (vga_idx > 27)
+ rssi = -100 + 6;
+ else
+ rssi += -100 + 2 * 27;
+ break;
+ case 6:
+ rssi += -48 + 2 * 2;
+ break;
+ case 5:
+ rssi += -42 + 2 * 7;
+ break;
+ case 4:
+ rssi += -36 + 2 * 7;
+ break;
+ case 3:
+ rssi += -24 + 2 * 7;
+ break;
+ case 2:
+ rssi += -6 + 2 * 5;
+ if (sc->sc_flags & RTWN_FLAG_CCK_HIPWR)
+ rssi -= 6;
+ break;
+ case 1:
+ rssi += 8;
+ break;
+ case 0:
+ rssi += 14;
+ break;
+ }
+
+ return (rssi);
+}
+
+int8_t
+r88e_get_rssi_ofdm(struct rtwn_softc *sc, void *physt)
+{
+ struct r88e_rx_phystat *phy = (struct r88e_rx_phystat *)physt;
+ int rssi;
+
+ /* Get average RSSI. */
+ rssi = ((phy->sig_qual >> 1) & 0x7f) - 110;
+
+ return (rssi);
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx_desc.h b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx_desc.h
new file mode 100644
index 00000000..2b72f3dd
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx_desc.h
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
+ * $FreeBSD$
+ */
+
+#ifndef R88E_RX_DESC_H
+#define R88E_RX_DESC_H
+
+#include <dev/rtwn/rtl8192c/r92c_rx_desc.h>
+
+/* Rx MAC descriptor defines (chip-specific). */
+/* Rx dword 3 */
+#define R88E_RXDW3_RPT_M 0x0000c000
+#define R88E_RXDW3_RPT_S 14
+#define R88E_RXDW3_RPT_RX 0
+#define R88E_RXDW3_RPT_TX1 1
+#define R88E_RXDW3_RPT_TX2 2
+#define R88E_RXDW3_RPT_HIS 3
+
+/* Rx PHY descriptor. */
+struct r88e_rx_phystat {
+ uint8_t path_agc[2];
+ uint8_t chan;
+ uint8_t reserved1;
+ uint8_t sig_qual;
+ uint8_t agc_rpt;
+ uint8_t rpt_b;
+ uint8_t reserved2;
+ 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 reserved3[3];
+ uint8_t stream_csi[2];
+ uint8_t stream_target_csi[2];
+ uint8_t sig_evm;
+} __packed;
+
+/* Tx report (type 1). */
+struct r88e_tx_rpt_ccx {
+ uint8_t rptb0;
+#define R88E_RPTB6_PKT_NUM_M 0x0e
+#define R88E_RPTB6_PKT_NUM_S 1
+#define R88E_RPTB0_INT_CCX 0x80
+
+ uint8_t rptb1;
+#define R88E_RPTB1_MACID_M 0x3f
+#define R88E_RPTB1_MACID_S 0
+#define R88E_RPTB1_PKT_OK 0x40
+#define R88E_RPTB1_BMC 0x80
+
+ uint8_t rptb2;
+#define R88E_RPTB2_RETRY_CNT_M 0x3f
+#define R88E_RPTB2_RETRY_CNT_S 0
+#define R88E_RPTB2_LIFE_EXPIRE 0x40
+#define R88E_RPTB2_RETRY_OVER 0x80
+
+ uint8_t queue_time_low;
+ uint8_t queue_time_high;
+ uint8_t final_rate;
+ uint8_t rptb6;
+#define R88E_RPTB6_QSEL_M 0xf0
+#define R88E_RPTB6_QSEL_S 4
+
+ uint8_t rptb7;
+} __packed;
+
+/* Interrupt message format. */
+/* XXX recheck */
+struct r88e_intr_msg {
+ uint8_t c2h_id;
+ uint8_t c2h_seq;
+ uint8_t c2h_evt;
+ uint8_t reserved1[13];
+ uint8_t cpwm1;
+ uint8_t reserved2[3];
+ uint8_t cpwm2;
+ uint8_t reserved3[27];
+ uint32_t hisr;
+ uint32_t hisr_ex;
+};
+
+#endif /* R88E_RX_DESC_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_tx.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_tx.c
new file mode 100644
index 00000000..4f70e61c
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_tx.c
@@ -0,0 +1,81 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/rtwn/if_rtwnreg.h>
+#include <dev/rtwn/if_rtwnvar.h>
+
+#include <dev/rtwn/rtl8188e/r88e.h>
+#include <dev/rtwn/rtl8188e/r88e_tx_desc.h>
+
+
+void
+r88e_tx_enable_ampdu(void *buf, int enable)
+{
+ struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
+
+ if (enable)
+ txd->txdw2 |= htole32(R88E_TXDW2_AGGEN);
+ else
+ txd->txdw2 |= htole32(R88E_TXDW2_AGGBK);
+}
+
+void
+r88e_tx_setup_hwseq(void *buf)
+{
+ struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
+
+ txd->txdseq |= htole16(R88E_TXDSEQ_HWSEQ_EN);
+}
+
+void
+r88e_tx_setup_macid(void *buf, int id)
+{
+ struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
+
+ txd->txdw1 |= htole32(SM(R88E_TXDW1_MACID, id));
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_tx_desc.h b/freebsd/sys/dev/rtwn/rtl8188e/r88e_tx_desc.h
new file mode 100644
index 00000000..98338fb7
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_tx_desc.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
+ * $FreeBSD$
+ */
+
+#ifndef R88E_TX_DESC_H
+#define R88E_TX_DESC_H
+
+#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
+
+/* Tx MAC descriptor defines (chip-specific). */
+/* Tx dword 1. */
+#define R88E_TXDW1_MACID_M 0x0000003f
+#define R88E_TXDW1_MACID_S 0
+
+/* Tx dword 2. */
+#define R88E_TXDW2_AGGEN 0x00001000
+#define R88E_TXDW2_AGGBK 0x00010000
+
+/* Tx dword 3. */
+#define R88E_TXDSEQ_HWSEQ_EN 0x8000
+
+#endif /* R88E_TX_DESC_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu.h b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu.h
new file mode 100644
index 00000000..85b637cb
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
+ * $FreeBSD$
+ */
+
+#ifndef RTL8188EU_H
+#define RTL8188EU_H
+
+#include <dev/rtwn/rtl8188e/r88e.h>
+
+
+/*
+ * Function declarations.
+ */
+/* r88eu_init.c */
+void r88eu_power_off(struct rtwn_softc *);
+void r88eu_init_intr(struct rtwn_softc *);
+void r88eu_init_rx_agg(struct rtwn_softc *);
+void r88eu_post_init(struct rtwn_softc *);
+
+/* r88eu_rx.c */
+int r88eu_classify_intr(struct rtwn_softc *, void *, int);
+
+#endif /* RTL8188EU_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
new file mode 100644
index 00000000..4d5452be
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
@@ -0,0 +1,218 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/rtwn/if_rtwnreg.h>
+#include <dev/rtwn/if_rtwnvar.h>
+#include <dev/rtwn/if_rtwn_nop.h>
+
+#include <dev/rtwn/usb/rtwn_usb_var.h>
+
+#include <dev/rtwn/rtl8192c/r92c_reg.h>
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+
+#include <dev/rtwn/rtl8192c/usb/r92cu.h>
+#include <dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h>
+
+#include <dev/rtwn/rtl8188e/r88e_priv.h>
+
+#include <dev/rtwn/rtl8188e/usb/r88eu.h>
+
+
+static struct rtwn_r88e_txpwr r88e_txpwr;
+
+void r88eu_attach(struct rtwn_usb_softc *);
+
+static void
+r88e_postattach(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ struct ieee80211com *ic = &sc->sc_ic;
+
+ rs->rs_scan_start = ic->ic_scan_start;
+ ic->ic_scan_start = r92c_scan_start;
+ rs->rs_scan_end = ic->ic_scan_end;
+ ic->ic_scan_end = r92c_scan_end;
+}
+
+static void
+r88eu_attach_private(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs;
+
+ rs = malloc(sizeof(struct r92c_softc), M_RTWN_PRIV, M_WAITOK | M_ZERO);
+
+ rs->rs_txpwr = &r88e_txpwr;
+ rs->rs_txagc = &r88e_txagc;
+
+ rs->rs_set_bw20 = r88e_set_bw20;
+ rs->rs_get_txpower = r88e_get_txpower;
+ rs->rs_set_gain = r88e_set_gain;
+ rs->rs_tx_enable_ampdu = r88e_tx_enable_ampdu;
+ rs->rs_tx_setup_hwseq = r88e_tx_setup_hwseq;
+ rs->rs_tx_setup_macid = r88e_tx_setup_macid;
+ rs->rs_set_name = rtwn_nop_softc; /* not used */
+
+ rs->rf_read_delay[0] = 10;
+ rs->rf_read_delay[1] = 100;
+ rs->rf_read_delay[2] = 10;
+
+ sc->sc_priv = rs;
+}
+
+static void
+r88eu_adj_devcaps(struct rtwn_softc *sc)
+{
+ /* XXX TODO? */
+}
+
+void
+r88eu_attach(struct rtwn_usb_softc *uc)
+{
+ struct rtwn_softc *sc = &uc->uc_sc;
+
+ /* USB part. */
+ uc->uc_align_rx = r92cu_align_rx;
+ uc->tx_agg_desc_num = 6;
+
+ /* Common part. */
+ sc->sc_flags = RTWN_FLAG_EXT_HDR;
+
+ sc->sc_set_chan = r92c_set_chan;
+ sc->sc_fill_tx_desc = r92c_fill_tx_desc;
+ sc->sc_fill_tx_desc_raw = r92c_fill_tx_desc_raw;
+ sc->sc_fill_tx_desc_null = r92c_fill_tx_desc_null;
+ sc->sc_dump_tx_desc = r92cu_dump_tx_desc;
+ sc->sc_tx_radiotap_flags = r92c_tx_radiotap_flags;
+ sc->sc_rx_radiotap_flags = r92c_rx_radiotap_flags;
+ sc->sc_get_rssi_cck = r88e_get_rssi_cck;
+ sc->sc_get_rssi_ofdm = r88e_get_rssi_ofdm;
+ sc->sc_classify_intr = r88eu_classify_intr;
+ sc->sc_handle_tx_report = r88e_ratectl_tx_complete;
+ sc->sc_handle_c2h_report = r88e_handle_c2h_report;
+ sc->sc_check_frame = rtwn_nop_int_softc_mbuf;
+ sc->sc_rf_read = r92c_rf_read;
+ sc->sc_rf_write = r88e_rf_write;
+ sc->sc_check_condition = r92c_check_condition;
+ sc->sc_efuse_postread = rtwn_nop_softc;
+ sc->sc_parse_rom = r88e_parse_rom;
+ sc->sc_set_led = r88e_set_led;
+ sc->sc_power_on = r88e_power_on;
+ sc->sc_power_off = r88eu_power_off;
+#ifndef RTWN_WITHOUT_UCODE
+ sc->sc_fw_reset = r88e_fw_reset;
+ sc->sc_fw_download_enable = r88e_fw_download_enable;
+#endif
+ sc->sc_set_page_size = r92c_set_page_size;
+ sc->sc_lc_calib = r92c_lc_calib;
+ sc->sc_iq_calib = r88e_iq_calib; /* XXX TODO */
+ sc->sc_read_chipid_vendor = rtwn_nop_softc_uint32;
+ sc->sc_adj_devcaps = r88eu_adj_devcaps;
+ sc->sc_vap_preattach = rtwn_nop_softc_vap;
+ sc->sc_postattach = r88e_postattach;
+ sc->sc_detach_private = r92c_detach_private;
+ sc->sc_set_media_status = r88e_set_media_status;
+#ifndef RTWN_WITHOUT_UCODE
+ sc->sc_set_rsvd_page = r88e_set_rsvd_page;
+ sc->sc_set_pwrmode = r88e_set_pwrmode;
+ sc->sc_set_rssi = rtwn_nop_softc; /* XXX TODO? */
+#endif
+ sc->sc_beacon_init = r92c_beacon_init;
+ sc->sc_beacon_enable = r88e_beacon_enable;
+ sc->sc_beacon_set_rate = rtwn_nop_void_int;
+ sc->sc_beacon_select = rtwn_nop_softc_int;
+ sc->sc_temp_measure = r88e_temp_measure;
+ sc->sc_temp_read = r88e_temp_read;
+ sc->sc_init_tx_agg = r92cu_init_tx_agg;
+ sc->sc_init_rx_agg = r88eu_init_rx_agg;
+ sc->sc_init_ampdu = rtwn_nop_softc;
+ sc->sc_init_intr = r88eu_init_intr;
+ sc->sc_init_edca = r92c_init_edca;
+ sc->sc_init_bb = r88e_init_bb;
+ sc->sc_init_rf = r92c_init_rf;
+ sc->sc_init_antsel = rtwn_nop_softc;
+ sc->sc_post_init = r88eu_post_init;
+ sc->sc_init_bcnq1_boundary = rtwn_nop_int_softc;
+
+ sc->mac_prog = &rtl8188eu_mac[0];
+ sc->mac_size = nitems(rtl8188eu_mac);
+ sc->bb_prog = &rtl8188eu_bb[0];
+ sc->bb_size = nitems(rtl8188eu_bb);
+ sc->agc_prog = &rtl8188eu_agc[0];
+ sc->agc_size = nitems(rtl8188eu_agc);
+ sc->rf_prog = &rtl8188eu_rf[0];
+
+ sc->name = "RTL8188EU";
+ sc->fwname = "rtwn-rtl8188eufw";
+ sc->fwsig = 0x88e;
+
+ sc->page_count = R88E_TX_PAGE_COUNT;
+ sc->pktbuf_count = R88E_TXPKTBUF_COUNT;
+
+ sc->ackto = 0x40;
+ sc->npubqpages = R88E_PUBQ_NPAGES;
+ sc->page_size = R92C_TX_PAGE_SIZE;
+
+ sc->txdesc_len = sizeof(struct r92cu_tx_desc);
+ sc->efuse_maxlen = R88E_EFUSE_MAX_LEN;
+ sc->efuse_maplen = R88E_EFUSE_MAP_LEN;
+ sc->rx_dma_size = R88E_RX_DMA_BUFFER_SIZE;
+
+ sc->macid_limit = R88E_MACID_MAX + 1;
+ sc->cam_entry_limit = R92C_CAM_ENTRY_COUNT;
+ sc->fwsize_limit = R92C_MAX_FW_SIZE;
+ sc->temp_delta = R88E_CALIB_THRESHOLD;
+
+ sc->bcn_status_reg[0] = R92C_TDECTRL;
+ sc->bcn_status_reg[1] = R92C_TDECTRL;
+ sc->rcr = 0;
+
+ sc->ntxchains = 1;
+ sc->nrxchains = 1;
+
+ r88eu_attach_private(sc);
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c
new file mode 100644
index 00000000..3f9ae320
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c
@@ -0,0 +1,226 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/rtwn/if_rtwnreg.h>
+#include <dev/rtwn/if_rtwnvar.h>
+
+#include <dev/rtwn/rtl8192c/r92c.h>
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+
+#include <dev/rtwn/rtl8188e/usb/r88eu.h>
+#include <dev/rtwn/rtl8188e/usb/r88eu_reg.h>
+
+
+void
+r88eu_power_off(struct rtwn_softc *sc)
+{
+ uint8_t reg;
+ int error, ntries;
+
+ /* Disable any kind of TX reports. */
+ error = rtwn_setbits_1(sc, R88E_TX_RPT_CTRL,
+ R88E_TX_RPT1_ENA | R88E_TX_RPT2_ENA, 0);
+ if (error == ENXIO) /* hardware gone */
+ return;
+
+ /* Stop Rx. */
+ rtwn_write_1(sc, R92C_CR, 0);
+
+ /* Move card to Low Power State. */
+ /* Block all Tx queues. */
+ rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
+
+ for (ntries = 0; ntries < 10; ntries++) {
+ /* Should be zero if no packet is transmitting. */
+ if (rtwn_read_4(sc, R88E_SCH_TXCMD) == 0)
+ break;
+
+ rtwn_delay(sc, 5000);
+ }
+ if (ntries == 10) {
+ device_printf(sc->sc_dev, "%s: failed to block Tx queues\n",
+ __func__);
+ return;
+ }
+
+ /* CCK and OFDM are disabled, and clock are gated. */
+ rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_BBRSTB, 0);
+
+ rtwn_delay(sc, 1);
+
+ /* Reset MAC TRX */
+ rtwn_write_1(sc, R92C_CR,
+ 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);
+
+ /* check if removed later */
+ rtwn_setbits_1_shift(sc, R92C_CR, R92C_CR_ENSEC, 0, 1);
+
+ /* Respond TxOK to scheduler */
+ rtwn_setbits_1(sc, R92C_DUAL_TSF_RST, 0, 0x20);
+
+ /* If firmware in ram code, do reset. */
+#ifndef RTWN_WITHOUT_UCODE
+ if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY)
+ r88e_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN);
+#endif
+
+ /* Reset MCU ready status. */
+ rtwn_write_1(sc, R92C_MCUFWDL, 0);
+
+ /* Disable 32k. */
+ rtwn_setbits_1(sc, R88E_32K_CTRL, 0x01, 0);
+
+ /* Move card to Disabled state. */
+ /* Turn off RF. */
+ rtwn_write_1(sc, R92C_RF_CTRL, 0);
+
+ /* LDO Sleep mode. */
+ rtwn_setbits_1(sc, R92C_LPLDO_CTRL, 0, R92C_LPLDO_CTRL_SLEEP);
+
+ /* Turn off MAC by HW state machine */
+ rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0,
+ R92C_APS_FSMCO_APFM_OFF, 1);
+
+ for (ntries = 0; ntries < 10; ntries++) {
+ /* Wait until it will be disabled. */
+ if ((rtwn_read_2(sc, R92C_APS_FSMCO) &
+ R92C_APS_FSMCO_APFM_OFF) == 0)
+ break;
+
+ rtwn_delay(sc, 5000);
+ }
+ if (ntries == 10) {
+ device_printf(sc->sc_dev, "%s: could not turn off MAC\n",
+ __func__);
+ return;
+ }
+
+ /* schmit trigger */
+ rtwn_setbits_1(sc, R92C_AFE_XTAL_CTRL + 2, 0, 0x80);
+
+ /* Enable WL suspend. */
+ rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
+ R92C_APS_FSMCO_AFSM_PCIE, R92C_APS_FSMCO_AFSM_HSUS, 1);
+
+ /* Enable bandgap mbias in suspend. */
+ rtwn_write_1(sc, R92C_APS_FSMCO + 3, 0);
+
+ /* Clear SIC_EN register. */
+ rtwn_setbits_1(sc, R92C_GPIO_MUXCFG + 1, 0x10, 0);
+
+ /* Set USB suspend enable local register */
+ rtwn_setbits_1(sc, R92C_USB_SUSPEND, 0, 0x10);
+
+ /* Reset MCU IO Wrapper. */
+ reg = rtwn_read_1(sc, R92C_RSV_CTRL + 1);
+ rtwn_write_1(sc, R92C_RSV_CTRL + 1, reg & ~0x08);
+ rtwn_write_1(sc, R92C_RSV_CTRL + 1, reg | 0x08);
+
+ /* marked as 'For Power Consumption' code. */
+ rtwn_write_1(sc, R92C_GPIO_OUT, rtwn_read_1(sc, R92C_GPIO_IN));
+ rtwn_write_1(sc, R92C_GPIO_IOSEL, 0xff);
+
+ rtwn_write_1(sc, R92C_GPIO_IO_SEL,
+ rtwn_read_1(sc, R92C_GPIO_IO_SEL) << 4);
+ rtwn_setbits_1(sc, R92C_GPIO_MOD, 0, 0x0f);
+
+ /* Set LNA, TRSW, EX_PA Pin to output mode. */
+ rtwn_write_4(sc, R88E_BB_PAD_CTRL, 0x00080808);
+}
+
+void
+r88eu_init_intr(struct rtwn_softc *sc)
+{
+ /* TODO: adjust */
+ 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);
+ rtwn_setbits_1(sc, R92C_USB_SPECIAL_OPTION, 0,
+ R92C_USB_SPECIAL_OPTION_INT_BULK_SEL);
+}
+
+void
+r88eu_init_rx_agg(struct rtwn_softc *sc)
+{
+ /* XXX merge? */
+ rtwn_setbits_1(sc, R92C_TRXDMA_CTRL, 0,
+ R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
+ /* XXX dehardcode */
+ rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
+ rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH + 1, 4);
+}
+
+void
+r88eu_post_init(struct rtwn_softc *sc)
+{
+
+ /* Enable per-packet TX report. */
+ rtwn_setbits_1(sc, R88E_TX_RPT_CTRL, 0, R88E_TX_RPT1_ENA);
+
+ /* Disable Tx if MACID is not associated. */
+ rtwn_write_4(sc, R88E_MACID_NO_LINK, 0xffffffff);
+ rtwn_write_4(sc, R88E_MACID_NO_LINK + 4, 0xffffffff);
+ r88e_macid_enable_link(sc, RTWN_MACID_BC, 1);
+
+ /* Perform LO and IQ calibrations. */
+ r88e_iq_calib(sc);
+ /* Perform LC calibration. */
+ r92c_lc_calib(sc);
+
+ rtwn_write_1(sc, R92C_USB_HRPWM, 0);
+
+ if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) {
+ /* No support (yet?) for f/w rate adaptation. */
+ sc->sc_ratectl = RTWN_RATECTL_NET80211;
+ } else
+ sc->sc_ratectl = sc->sc_ratectl_sysctl;
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_reg.h b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_reg.h
new file mode 100644
index 00000000..fc61eaae
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_reg.h
@@ -0,0 +1,27 @@
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
+ * $FreeBSD$
+ */
+
+#ifndef R88EU_REG_H
+#define R88EU_REG_H
+
+#include <dev/rtwn/rtl8192c/usb/r92cu_reg.h>
+#include <dev/rtwn/rtl8188e/r88e_reg.h>
+
+#endif /* R88EU_REG_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_rx.c b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_rx.c
new file mode 100644
index 00000000..3c2671c7
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_rx.c
@@ -0,0 +1,76 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <rtems/bsd/local/opt_wlan.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/rtwn/if_rtwnreg.h>
+#include <dev/rtwn/if_rtwnvar.h>
+
+#include <dev/rtwn/if_rtwn_debug.h>
+
+#include <dev/rtwn/rtl8188e/r88e_rx_desc.h>
+
+#include <dev/rtwn/rtl8188e/usb/r88eu.h>
+
+
+int
+r88eu_classify_intr(struct rtwn_softc *sc, void *buf, int len)
+{
+ struct r92c_rx_stat *stat = buf;
+ int report_sel = MS(le32toh(stat->rxdw3), R88E_RXDW3_RPT);
+
+ switch (report_sel) {
+ case R88E_RXDW3_RPT_RX:
+ return (RTWN_RX_DATA);
+ case R88E_RXDW3_RPT_TX1: /* per-packet Tx report */
+ case R88E_RXDW3_RPT_TX2: /* periodical Tx report */
+ return (RTWN_RX_TX_REPORT);
+ case R88E_RXDW3_RPT_HIS:
+ return (RTWN_RX_OTHER);
+ default: /* shut up the compiler */
+ return (RTWN_RX_DATA);
+ }
+}