summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/rtwn/rtl8192c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/dev/rtwn/rtl8192c')
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce.h74
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c265
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_calib.c388
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_fw.c77
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_init.c325
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_led.c69
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_priv.h182
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_reg.h103
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_rx.c134
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_rx_desc.h41
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_tx.c117
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_tx_desc.h55
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c.h114
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_attach.c82
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_beacon.c88
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_calib.c115
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c353
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c522
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_fw_cmd.h148
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_init.c319
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_priv.h408
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_reg.h855
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_rf.c95
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_rom.c141
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_defs.h57
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_image.h71
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c104
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h95
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c438
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h122
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_var.h83
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu.h56
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c247
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_init.c393
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_led.c68
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_priv.h322
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_reg.h65
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_rx.c65
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_tx.c66
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h45
40 files changed, 7367 insertions, 0 deletions
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce.h b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce.h
new file mode 100644
index 00000000..93379f8b
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce.h
@@ -0,0 +1,74 @@
+/* $OpenBSD: if_rtwnreg.h,v 1.3 2015/06/14 08:02:47 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef RTL8192CE_H
+#define RTL8192CE_H
+
+#include <dev/rtwn/rtl8192c/r92c.h>
+
+
+/*
+ * Global definitions.
+ */
+#define R92CE_PUBQ_NPAGES 176
+#define R92CE_HPQ_NPAGES 41
+#define R92CE_LPQ_NPAGES 28
+#define R92CE_TX_PAGE_COUNT \
+ (R92CE_PUBQ_NPAGES + R92CE_HPQ_NPAGES + R92CE_LPQ_NPAGES)
+
+
+/*
+ * Function declarations.
+ */
+/* r92ce_calib.c */
+void r92ce_iq_calib(struct rtwn_softc *);
+
+/* r92ce_fw.c */
+#ifndef RTWN_WITHOUT_UCODE
+void r92ce_fw_reset(struct rtwn_softc *, int);
+#endif
+
+/* r92ce_init.c */
+void r92ce_init_intr(struct rtwn_softc *);
+void r92ce_init_edca(struct rtwn_softc *);
+void r92ce_init_bb(struct rtwn_softc *);
+int r92ce_power_on(struct rtwn_softc *);
+void r92ce_power_off(struct rtwn_softc *);
+void r92ce_init_ampdu(struct rtwn_softc *);
+void r92ce_post_init(struct rtwn_softc *);
+
+/* r92ce_led.c */
+void r92ce_set_led(struct rtwn_softc *, int, int);
+
+/* r92ce_rx.c */
+int r92ce_classify_intr(struct rtwn_softc *, void *, int);
+void r92ce_enable_intr(struct rtwn_pci_softc *);
+void r92ce_start_xfers(struct rtwn_softc *);
+
+/* r92ce_tx.c */
+void r92ce_setup_tx_desc(struct rtwn_pci_softc *, void *, uint32_t);
+void r92ce_tx_postsetup(struct rtwn_pci_softc *, void *,
+ bus_dma_segment_t[]);
+void r92ce_copy_tx_desc(void *, const void *);
+void r92ce_dump_tx_desc(struct rtwn_softc *, const void *);
+
+#endif /* RTL8192CE_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
new file mode 100644
index 00000000..d53dbf98
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
@@ -0,0 +1,265 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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 <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.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/pci/rtwn_pci_var.h>
+
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+
+#include <dev/rtwn/rtl8192c/pci/r92ce.h>
+#include <dev/rtwn/rtl8192c/pci/r92ce_priv.h>
+#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
+#include <dev/rtwn/rtl8192c/pci/r92ce_tx_desc.h>
+
+
+static struct rtwn_r92c_txpwr r92c_txpwr;
+
+void r92ce_attach(struct rtwn_pci_softc *);
+
+static void
+r92ce_postattach(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ struct ieee80211com *ic = &sc->sc_ic;
+
+ if (!(rs->chip & R92C_CHIP_92C) &&
+ rs->board_type == R92C_BOARD_TYPE_HIGHPA)
+ rs->rs_txagc = &rtl8188ru_txagc[0];
+ else
+ rs->rs_txagc = &rtl8192cu_txagc[0];
+
+ if ((rs->chip & (R92C_CHIP_UMC_A_CUT | R92C_CHIP_92C)) ==
+ R92C_CHIP_UMC_A_CUT)
+ sc->fwname = "rtwn-rtl8192cfwE";
+ else
+ sc->fwname = "rtwn-rtl8192cfwE_B";
+ sc->fwsig = 0x88c;
+
+ 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
+r92ce_set_name(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+
+ if (rs->chip & R92C_CHIP_92C)
+ sc->name = "RTL8192CE";
+ else
+ sc->name = "RTL8188CE";
+}
+
+static void
+r92ce_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 = &r92c_txpwr;
+
+ rs->rs_set_bw20 = r92c_set_bw20;
+ rs->rs_get_txpower = r92c_get_txpower;
+ rs->rs_set_gain = r92c_set_gain;
+ rs->rs_tx_enable_ampdu = r92c_tx_enable_ampdu;
+ rs->rs_tx_setup_hwseq = r92c_tx_setup_hwseq;
+ rs->rs_tx_setup_macid = r92c_tx_setup_macid;
+ rs->rs_set_name = r92ce_set_name;
+
+ /* XXX TODO: test with net80211 ratectl! */
+#ifndef RTWN_WITHOUT_UCODE
+ rs->rs_c2h_timeout = hz;
+
+ callout_init_mtx(&rs->rs_c2h_report, &sc->sc_mtx, 0);
+#endif
+
+ rs->rf_read_delay[0] = 1000;
+ rs->rf_read_delay[1] = 1000;
+ rs->rf_read_delay[2] = 1000;
+
+ sc->sc_priv = rs;
+}
+
+static void
+r92ce_adj_devcaps(struct rtwn_softc *sc)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+
+ /*
+ * XXX do NOT enable PMGT until RSVD_PAGE command
+ * will not be tested / fixed + HRPWM register must be set too.
+ */
+ ic->ic_caps &= ~IEEE80211_C_PMGT;
+}
+
+void
+r92ce_attach(struct rtwn_pci_softc *pc)
+{
+ struct rtwn_softc *sc = &pc->pc_sc;
+
+ /* PCIe part. */
+ pc->pc_setup_tx_desc = r92ce_setup_tx_desc;
+ pc->pc_tx_postsetup = r92ce_tx_postsetup;
+ pc->pc_copy_tx_desc = r92ce_copy_tx_desc;
+ pc->pc_enable_intr = r92ce_enable_intr;
+
+ pc->pc_qmap = 0xf771;
+ pc->tcr =
+ R92C_TCR_CFENDFORM | (1 << 12) | (1 << 13);
+
+ /* Common part. */
+ /* RTL8192C* cannot use pairwise keys from first 4 slots */
+ sc->sc_flags = RTWN_FLAG_CAM_FIXED;
+
+ sc->sc_start_xfers = r92ce_start_xfers;
+ 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; /* XXX recheck */
+ sc->sc_dump_tx_desc = r92ce_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 = r92c_get_rssi_cck;
+ sc->sc_get_rssi_ofdm = r92c_get_rssi_ofdm;
+ sc->sc_classify_intr = r92ce_classify_intr;
+ sc->sc_handle_tx_report = rtwn_nop_softc_uint8_int;
+ sc->sc_handle_c2h_report = rtwn_nop_softc_uint8_int;
+ sc->sc_check_frame = rtwn_nop_int_softc_mbuf;
+ sc->sc_rf_read = r92c_rf_read;
+ sc->sc_rf_write = r92c_rf_write;
+ sc->sc_check_condition = r92c_check_condition;
+ sc->sc_efuse_postread = r92c_efuse_postread;
+ sc->sc_parse_rom = r92c_parse_rom;
+ sc->sc_set_led = r92ce_set_led;
+ sc->sc_power_on = r92ce_power_on;
+ sc->sc_power_off = r92ce_power_off;
+#ifndef RTWN_WITHOUT_UCODE
+ sc->sc_fw_reset = r92ce_fw_reset;
+ sc->sc_fw_download_enable = r92c_fw_download_enable;
+#endif
+ sc->sc_set_page_size = r92c_set_page_size;
+ sc->sc_lc_calib = r92c_lc_calib;
+ sc->sc_iq_calib = r92ce_iq_calib;
+ sc->sc_read_chipid_vendor = r92c_read_chipid_vendor;
+ sc->sc_adj_devcaps = r92ce_adj_devcaps;
+ sc->sc_vap_preattach = rtwn_nop_softc_vap;
+ sc->sc_postattach = r92ce_postattach;
+ sc->sc_detach_private = r92c_detach_private;
+ sc->sc_set_media_status = r92c_joinbss_rpt;
+#ifndef RTWN_WITHOUT_UCODE
+ sc->sc_set_rsvd_page = r92c_set_rsvd_page;
+ sc->sc_set_pwrmode = r92c_set_pwrmode;
+ sc->sc_set_rssi = r92c_set_rssi;
+#endif
+ sc->sc_beacon_init = r92c_beacon_init;
+ sc->sc_beacon_enable = r92c_beacon_enable;
+ sc->sc_beacon_set_rate = rtwn_nop_void_int;
+ sc->sc_beacon_select = rtwn_nop_softc_int;
+ sc->sc_temp_measure = r92c_temp_measure;
+ sc->sc_temp_read = r92c_temp_read;
+ sc->sc_init_tx_agg = rtwn_nop_softc;
+ sc->sc_init_rx_agg = rtwn_nop_softc;
+ sc->sc_init_ampdu = r92ce_init_ampdu;
+ sc->sc_init_intr = r92ce_init_intr;
+ sc->sc_init_edca = r92ce_init_edca;
+ sc->sc_init_bb = r92ce_init_bb;
+ sc->sc_init_rf = r92c_init_rf;
+ sc->sc_init_antsel = rtwn_nop_softc;
+ sc->sc_post_init = r92ce_post_init;
+ sc->sc_init_bcnq1_boundary = rtwn_nop_int_softc;
+
+ sc->mac_prog = &rtl8192ce_mac[0];
+ sc->mac_size = nitems(rtl8192ce_mac);
+ sc->bb_prog = &rtl8192ce_bb[0];
+ sc->bb_size = nitems(rtl8192ce_bb);
+ sc->agc_prog = &rtl8192ce_agc[0];
+ sc->agc_size = nitems(rtl8192ce_agc);
+ sc->rf_prog = &rtl8192c_rf[0];
+
+ sc->page_count = R92CE_TX_PAGE_COUNT;
+ sc->pktbuf_count = R92C_TXPKTBUF_COUNT;
+
+ sc->ackto = 0x40;
+ sc->npubqpages = R92CE_PUBQ_NPAGES;
+ sc->nhqpages = R92CE_HPQ_NPAGES;
+ sc->nnqpages = 0;
+ sc->nlqpages = R92CE_LPQ_NPAGES;
+ sc->page_size = R92C_TX_PAGE_SIZE;
+
+ sc->txdesc_len = sizeof(struct r92ce_tx_desc);
+ sc->efuse_maxlen = R92C_EFUSE_MAX_LEN;
+ sc->efuse_maplen = R92C_EFUSE_MAP_LEN;
+ sc->rx_dma_size = R92C_RX_DMA_BUFFER_SIZE;
+
+ sc->macid_limit = R92C_MACID_MAX + 1;
+ sc->cam_entry_limit = R92C_CAM_ENTRY_COUNT;
+ sc->fwsize_limit = R92C_MAX_FW_SIZE;
+ sc->temp_delta = R92C_CALIB_THRESHOLD;
+
+ sc->bcn_status_reg[0] = R92C_TDECTRL;
+ /*
+ * TODO: some additional setup is required
+ * to maintain few beacons at the same time.
+ *
+ * XXX BCNQ1 mechanism is not needed here; move it to the USB module.
+ */
+ sc->bcn_status_reg[1] = R92C_TDECTRL;
+ sc->rcr = 0;
+
+ r92ce_attach_private(sc);
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_calib.c b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_calib.c
new file mode 100644
index 00000000..e1b4f507
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_calib.c
@@ -0,0 +1,388 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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 <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.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/pci/rtwn_pci_var.h>
+
+#include <dev/rtwn/rtl8192c/pci/r92ce.h>
+#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
+
+
+/* Registers to save and restore during IQ calibration. */
+struct r92ce_iq_cal_reg_vals {
+ uint32_t adda[16];
+ uint8_t txpause;
+ uint8_t bcn_ctrl[2];
+ uint32_t gpio_muxcfg;
+ uint32_t ofdm0_trxpathena;
+ uint32_t ofdm0_trmuxpar;
+ uint32_t fpga0_rfifacesw1;
+};
+
+/* XXX 92CU? */
+static int
+r92ce_iq_calib_chain(struct rtwn_softc *sc, int chain, uint16_t tx[2],
+ uint16_t rx[2])
+{
+ uint32_t status;
+ int offset = chain * 0x20;
+
+ if (chain == 0) { /* IQ calibration for chain 0. */
+ /* IQ calibration settings for chain 0. */
+ rtwn_bb_write(sc, 0xe30, 0x10008c1f);
+ rtwn_bb_write(sc, 0xe34, 0x10008c1f);
+ rtwn_bb_write(sc, 0xe38, 0x82140102);
+
+ if (sc->ntxchains > 1) {
+ rtwn_bb_write(sc, 0xe3c, 0x28160202); /* 2T */
+ /* IQ calibration settings for chain 1. */
+ rtwn_bb_write(sc, 0xe50, 0x10008c22);
+ rtwn_bb_write(sc, 0xe54, 0x10008c22);
+ rtwn_bb_write(sc, 0xe58, 0x82140102);
+ rtwn_bb_write(sc, 0xe5c, 0x28160202);
+ } else
+ rtwn_bb_write(sc, 0xe3c, 0x28160502); /* 1T */
+
+ /* LO calibration settings. */
+ rtwn_bb_write(sc, 0xe4c, 0x001028d1);
+ /* We're doing LO and IQ calibration in one shot. */
+ rtwn_bb_write(sc, 0xe48, 0xf9000000);
+ rtwn_bb_write(sc, 0xe48, 0xf8000000);
+
+ } else { /* IQ calibration for chain 1. */
+ /* We're doing LO and IQ calibration in one shot. */
+ rtwn_bb_write(sc, 0xe60, 0x00000002);
+ rtwn_bb_write(sc, 0xe60, 0x00000000);
+ }
+
+ /* Give LO and IQ calibrations the time to complete. */
+ rtwn_delay(sc, 1000);
+
+ /* Read IQ calibration status. */
+ status = rtwn_bb_read(sc, 0xeac);
+
+ if (status & (1 << (28 + chain * 3)))
+ return (0); /* Tx failed. */
+ /* Read Tx IQ calibration results. */
+ tx[0] = (rtwn_bb_read(sc, 0xe94 + offset) >> 16) & 0x3ff;
+ tx[1] = (rtwn_bb_read(sc, 0xe9c + offset) >> 16) & 0x3ff;
+ if (tx[0] == 0x142 || tx[1] == 0x042)
+ return (0); /* Tx failed. */
+
+ if (status & (1 << (27 + chain * 3)))
+ return (1); /* Rx failed. */
+ /* Read Rx IQ calibration results. */
+ rx[0] = (rtwn_bb_read(sc, 0xea4 + offset) >> 16) & 0x3ff;
+ rx[1] = (rtwn_bb_read(sc, 0xeac + offset) >> 16) & 0x3ff;
+ if (rx[0] == 0x132 || rx[1] == 0x036)
+ return (1); /* Rx failed. */
+
+ return (3); /* Both Tx and Rx succeeded. */
+}
+
+static void
+r92ce_iq_calib_run(struct rtwn_softc *sc, int n, uint16_t tx[2][2],
+ uint16_t rx[2][2], struct r92ce_iq_cal_reg_vals *vals)
+{
+ /* Registers to save and restore during IQ calibration. */
+ static const uint16_t reg_adda[16] = {
+ 0x85c, 0xe6c, 0xe70, 0xe74,
+ 0xe78, 0xe7c, 0xe80, 0xe84,
+ 0xe88, 0xe8c, 0xed0, 0xed4,
+ 0xed8, 0xedc, 0xee0, 0xeec
+ };
+ int i, chain;
+ uint32_t hssi_param1;
+
+ if (n == 0) {
+ for (i = 0; i < nitems(reg_adda); i++)
+ vals->adda[i] = rtwn_bb_read(sc, reg_adda[i]);
+
+ vals->txpause = rtwn_read_1(sc, R92C_TXPAUSE);
+ vals->bcn_ctrl[0] = rtwn_read_1(sc, R92C_BCN_CTRL(0));
+ vals->bcn_ctrl[1] = rtwn_read_1(sc, R92C_BCN_CTRL(1));
+ vals->gpio_muxcfg = rtwn_read_4(sc, R92C_GPIO_MUXCFG);
+ }
+
+ if (sc->ntxchains == 1) {
+ rtwn_bb_write(sc, reg_adda[0], 0x0b1b25a0);
+ for (i = 1; i < nitems(reg_adda); i++)
+ rtwn_bb_write(sc, reg_adda[i], 0x0bdb25a0);
+ } else {
+ for (i = 0; i < nitems(reg_adda); i++)
+ rtwn_bb_write(sc, reg_adda[i], 0x04db25a4);
+ }
+
+ hssi_param1 = rtwn_bb_read(sc, R92C_HSSI_PARAM1(0));
+ if (!(hssi_param1 & R92C_HSSI_PARAM1_PI)) {
+ rtwn_bb_write(sc, R92C_HSSI_PARAM1(0),
+ hssi_param1 | R92C_HSSI_PARAM1_PI);
+ rtwn_bb_write(sc, R92C_HSSI_PARAM1(1),
+ hssi_param1 | R92C_HSSI_PARAM1_PI);
+ }
+
+ if (n == 0) {
+ vals->ofdm0_trxpathena =
+ rtwn_bb_read(sc, R92C_OFDM0_TRXPATHENA);
+ vals->ofdm0_trmuxpar = rtwn_bb_read(sc, R92C_OFDM0_TRMUXPAR);
+ vals->fpga0_rfifacesw1 =
+ rtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(1));
+ }
+
+ rtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA, 0x03a05600);
+ rtwn_bb_write(sc, R92C_OFDM0_TRMUXPAR, 0x000800e4);
+ rtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(1), 0x22204000);
+ if (sc->ntxchains > 1) {
+ rtwn_bb_write(sc, R92C_LSSI_PARAM(0), 0x00010000);
+ rtwn_bb_write(sc, R92C_LSSI_PARAM(1), 0x00010000);
+ }
+
+ rtwn_write_1(sc, R92C_TXPAUSE,
+ R92C_TX_QUEUE_AC | R92C_TX_QUEUE_MGT | R92C_TX_QUEUE_HIGH);
+ rtwn_write_1(sc, R92C_BCN_CTRL(0),
+ vals->bcn_ctrl[0] & ~R92C_BCN_CTRL_EN_BCN);
+ rtwn_write_1(sc, R92C_BCN_CTRL(1),
+ vals->bcn_ctrl[1] & ~R92C_BCN_CTRL_EN_BCN);
+ rtwn_write_1(sc, R92C_GPIO_MUXCFG,
+ vals->gpio_muxcfg & ~R92C_GPIO_MUXCFG_ENBT);
+
+ rtwn_bb_write(sc, 0x0b68, 0x00080000);
+ if (sc->ntxchains > 1)
+ rtwn_bb_write(sc, 0x0b6c, 0x00080000);
+
+ rtwn_bb_write(sc, 0x0e28, 0x80800000);
+ rtwn_bb_write(sc, 0x0e40, 0x01007c00);
+ rtwn_bb_write(sc, 0x0e44, 0x01004800);
+
+ rtwn_bb_write(sc, 0x0b68, 0x00080000);
+
+ for (chain = 0; chain < sc->ntxchains; chain++) {
+ if (chain > 0) {
+ /* Put chain 0 on standby. */
+ rtwn_bb_write(sc, 0x0e28, 0x00);
+ rtwn_bb_write(sc, R92C_LSSI_PARAM(0), 0x00010000);
+ rtwn_bb_write(sc, 0x0e28, 0x80800000);
+
+ /* Enable chain 1. */
+ for (i = 0; i < nitems(reg_adda); i++)
+ rtwn_bb_write(sc, reg_adda[i], 0x0b1b25a4);
+ }
+
+ /* Run IQ calibration twice. */
+ for (i = 0; i < 2; i++) {
+ int ret;
+
+ ret = r92ce_iq_calib_chain(sc, chain,
+ tx[chain], rx[chain]);
+ if (ret == 0) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_CALIB,
+ "%s: chain %d: Tx failed.\n",
+ __func__, chain);
+ tx[chain][0] = 0xff;
+ tx[chain][1] = 0xff;
+ rx[chain][0] = 0xff;
+ rx[chain][1] = 0xff;
+ } else if (ret == 1) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_CALIB,
+ "%s: chain %d: Rx failed.\n",
+ __func__, chain);
+ rx[chain][0] = 0xff;
+ rx[chain][1] = 0xff;
+ } else if (ret == 3) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_CALIB,
+ "%s: chain %d: Both Tx and Rx "
+ "succeeded.\n", __func__, chain);
+ }
+ }
+
+ RTWN_DPRINTF(sc, RTWN_DEBUG_CALIB,
+ "%s: results for run %d chain %d: tx[0] 0x%x, "
+ "tx[1] 0x%x, rx[0] 0x%x, rx[1] 0x%x\n", __func__, n, chain,
+ tx[chain][0], tx[chain][1], rx[chain][0], rx[chain][1]);
+ }
+
+ rtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA,
+ vals->ofdm0_trxpathena);
+ rtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(1),
+ vals->fpga0_rfifacesw1);
+ rtwn_bb_write(sc, R92C_OFDM0_TRMUXPAR, vals->ofdm0_trmuxpar);
+
+ rtwn_bb_write(sc, 0x0e28, 0x00);
+ rtwn_bb_write(sc, R92C_LSSI_PARAM(0), 0x00032ed3);
+ if (sc->ntxchains > 1)
+ rtwn_bb_write(sc, R92C_LSSI_PARAM(1), 0x00032ed3);
+
+ if (n != 0) {
+ if (!(hssi_param1 & R92C_HSSI_PARAM1_PI)) {
+ rtwn_bb_write(sc, R92C_HSSI_PARAM1(0), hssi_param1);
+ rtwn_bb_write(sc, R92C_HSSI_PARAM1(1), hssi_param1);
+ }
+
+ for (i = 0; i < nitems(reg_adda); i++)
+ rtwn_bb_write(sc, reg_adda[i], vals->adda[i]);
+
+ rtwn_write_1(sc, R92C_TXPAUSE, vals->txpause);
+ rtwn_write_1(sc, R92C_BCN_CTRL(0), vals->bcn_ctrl[0]);
+ rtwn_write_1(sc, R92C_BCN_CTRL(1), vals->bcn_ctrl[1]);
+ rtwn_write_4(sc, R92C_GPIO_MUXCFG, vals->gpio_muxcfg);
+ }
+}
+
+#define RTWN_IQ_CAL_MAX_TOLERANCE 5
+static int
+r92ce_iq_calib_compare_results(struct rtwn_softc *sc, uint16_t tx1[2][2],
+ uint16_t rx1[2][2], uint16_t tx2[2][2], uint16_t rx2[2][2])
+{
+ int chain, i, tx_ok[2], rx_ok[2];
+
+ tx_ok[0] = tx_ok[1] = rx_ok[0] = rx_ok[1] = 0;
+ for (chain = 0; chain < sc->ntxchains; chain++) {
+ for (i = 0; i < 2; i++) {
+ if (tx1[chain][i] == 0xff || tx2[chain][i] == 0xff ||
+ rx1[chain][i] == 0xff || rx2[chain][i] == 0xff)
+ continue;
+
+ tx_ok[chain] = (abs(tx1[chain][i] - tx2[chain][i]) <=
+ RTWN_IQ_CAL_MAX_TOLERANCE);
+
+ rx_ok[chain] = (abs(rx1[chain][i] - rx2[chain][i]) <=
+ RTWN_IQ_CAL_MAX_TOLERANCE);
+ }
+ }
+
+ if (sc->ntxchains > 1)
+ return (tx_ok[0] && tx_ok[1] && rx_ok[0] && rx_ok[1]);
+ else
+ return (tx_ok[0] && rx_ok[0]);
+}
+#undef RTWN_IQ_CAL_MAX_TOLERANCE
+
+static void
+r92ce_iq_calib_write_results(struct rtwn_softc *sc, uint16_t tx[2],
+ uint16_t rx[2], int chain)
+{
+ uint32_t reg, val, x;
+ long y, tx_c;
+
+ if (tx[0] == 0xff || tx[1] == 0xff)
+ return;
+
+ reg = rtwn_bb_read(sc, R92C_OFDM0_TXIQIMBALANCE(chain));
+ val = ((reg >> 22) & 0x3ff);
+ x = tx[0];
+ if (x & 0x00000200)
+ x |= 0xfffffc00;
+ reg = (((x * val) >> 8) & 0x3ff);
+ rtwn_bb_setbits(sc, R92C_OFDM0_TXIQIMBALANCE(chain), 0x3ff, reg);
+ rtwn_bb_setbits(sc, R92C_OFDM0_ECCATHRESHOLD, 0x80000000,
+ ((x * val) & 0x80) << 24);
+
+ y = tx[1];
+ if (y & 0x00000200)
+ y |= 0xfffffc00;
+ tx_c = (y * val) >> 8;
+ rtwn_bb_setbits(sc, R92C_OFDM0_TXAFE(chain), 0xf0000000,
+ (tx_c & 0x3c0) << 22);
+ rtwn_bb_setbits(sc, R92C_OFDM0_TXIQIMBALANCE(chain), 0x003f0000,
+ (tx_c & 0x3f) << 16);
+ rtwn_bb_setbits(sc, R92C_OFDM0_ECCATHRESHOLD, 0x20000000,
+ ((y * val) & 0x80) << 22);
+
+ if (rx[0] == 0xff || rx[1] == 0xff)
+ return;
+
+ rtwn_bb_setbits(sc, R92C_OFDM0_RXIQIMBALANCE(chain), 0x3ff,
+ rx[0] & 0x3ff);
+ rtwn_bb_setbits(sc, R92C_OFDM0_RXIQIMBALANCE(chain), 0xfc00,
+ (rx[1] & 0x3f) << 10);
+
+ if (chain == 0) {
+ rtwn_bb_setbits(sc, R92C_OFDM0_RXIQEXTANTA, 0xf0000000,
+ (rx[1] & 0x3c0) << 22);
+ } else {
+ rtwn_bb_setbits(sc, R92C_OFDM0_AGCRSSITABLE, 0xf000,
+ (rx[1] & 0x3c0) << 6);
+ }
+}
+
+#define RTWN_IQ_CAL_NRUN 3
+void
+r92ce_iq_calib(struct rtwn_softc *sc)
+{
+ struct r92ce_iq_cal_reg_vals vals;
+ uint16_t tx[RTWN_IQ_CAL_NRUN][2][2], rx[RTWN_IQ_CAL_NRUN][2][2];
+ int n, valid;
+
+ valid = 0;
+ for (n = 0; n < RTWN_IQ_CAL_NRUN; n++) {
+ r92ce_iq_calib_run(sc, n, tx[n], rx[n], &vals);
+
+ if (n == 0)
+ continue;
+
+ /* Valid results remain stable after consecutive runs. */
+ valid = r92ce_iq_calib_compare_results(sc, tx[n - 1],
+ rx[n - 1], tx[n], rx[n]);
+ if (valid)
+ break;
+ }
+
+ if (valid) {
+ r92ce_iq_calib_write_results(sc, tx[n][0], rx[n][0], 0);
+ if (sc->ntxchains > 1)
+ r92ce_iq_calib_write_results(sc, tx[n][1], rx[n][1], 1);
+ }
+}
+#undef RTWN_IQ_CAL_NRUN
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_fw.c b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_fw.c
new file mode 100644
index 00000000..c4905429
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_fw.c
@@ -0,0 +1,77 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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 <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.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/pci/rtwn_pci_var.h>
+
+#include <dev/rtwn/rtl8192c/pci/r92ce.h>
+
+
+#ifndef RTWN_WITHOUT_UCODE
+void
+r92ce_fw_reset(struct rtwn_softc *sc, int reason)
+{
+
+ if (reason == RTWN_FW_RESET_CHECKSUM)
+ return;
+
+ r92c_fw_reset(sc, reason);
+
+ /*
+ * We must sleep for one second to let the firmware settle.
+ * Accessing registers too early will hang the whole system.
+ */
+ if (reason == RTWN_FW_RESET_DOWNLOAD)
+ rtwn_delay(sc, 1000 * 1000);
+}
+#endif
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_init.c b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_init.c
new file mode 100644
index 00000000..e7ec8bfd
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_init.c
@@ -0,0 +1,325 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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 <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.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/pci/rtwn_pci_var.h>
+
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+
+#include <dev/rtwn/rtl8192c/pci/r92ce.h>
+#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
+
+
+void
+r92ce_init_intr(struct rtwn_softc *sc)
+{
+ /* Disable interrupts. */
+ rtwn_write_4(sc, R92C_HISR, 0x00000000);
+ rtwn_write_4(sc, R92C_HIMR, 0x00000000);
+}
+
+void
+r92ce_init_edca(struct rtwn_softc *sc)
+{
+ /* SIFS */
+ rtwn_write_2(sc, R92C_SPEC_SIFS, 0x1010);
+ rtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x1010);
+ rtwn_write_2(sc, R92C_SIFS_CCK, 0x1010);
+ rtwn_write_2(sc, R92C_SIFS_OFDM, 0x0e0e);
+ /* TXOP */
+ rtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b);
+ rtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f);
+ rtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005e4322);
+ rtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002f3222);
+}
+
+void
+r92ce_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_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
+
+ 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_DIO_PCIE | R92C_SYS_FUNC_EN_PCIEA |
+ R92C_SYS_FUNC_EN_PPLL | R92C_SYS_FUNC_EN_BB_GLB_RST |
+ R92C_SYS_FUNC_EN_BBRSTB);
+
+ rtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
+
+ rtwn_setbits_4(sc, R92C_LEDCFG0, 0, 0x00800000);
+
+ r92c_init_bb_common(sc);
+}
+
+int
+r92ce_power_on(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ uint32_t reg;
+ int ntries;
+
+ /* Wait for autoload done bit. */
+ for (ntries = 0; ntries < 1000; ntries++) {
+ if (rtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN)
+ break;
+ DELAY(5);
+ }
+ if (ntries == 1000) {
+ device_printf(sc->sc_dev,
+ "timeout waiting for chip autoload\n");
+ return (ETIMEDOUT);
+ }
+
+ /* Unlock ISO/CLK/Power control register. */
+ rtwn_write_1(sc, R92C_RSV_CTRL, 0);
+
+ if (rs->board_type != R92C_BOARD_TYPE_DONGLE) {
+ /* bt coex */
+ rtwn_setbits_4(sc, R92C_APS_FSMCO, 0,
+ R92C_APS_FSMCO_SOP_ABG |
+ R92C_APS_FSMCO_SOP_AMB |
+ R92C_APS_FSMCO_XOP_BTCK);
+ }
+
+ /* Move SPS into PWM mode. */
+ rtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b);
+
+ /* Set low byte to 0x0f, leave others unchanged. */
+ rtwn_write_1(sc, R92C_AFE_XTAL_CTRL, 0x0f);
+
+ /* TODO: check if we need this for 8188CE */
+ if (rs->board_type != R92C_BOARD_TYPE_DONGLE) {
+ /* bt coex */
+ /* XXX magic from linux */
+ rtwn_setbits_4(sc, R92C_AFE_XTAL_CTRL, 0x024800, 0);
+ }
+
+ rtwn_setbits_2(sc, R92C_SYS_ISO_CTRL, 0xff00,
+ R92C_SYS_ISO_CTRL_PWC_EV12V | R92C_SYS_ISO_CTRL_DIOR);
+
+ DELAY(200);
+
+ /* TODO: linux does additional btcoex stuff here */
+
+ /* Auto enable WLAN. */
+ rtwn_setbits_2(sc, R92C_APS_FSMCO, 0, R92C_APS_FSMCO_APFM_ONMAC);
+ for (ntries = 0; ntries < 1000; ntries++) {
+ if (!(rtwn_read_2(sc, R92C_APS_FSMCO) &
+ R92C_APS_FSMCO_APFM_ONMAC))
+ break;
+ DELAY(5);
+ }
+ if (ntries == 1000) {
+ device_printf(sc->sc_dev, "timeout waiting for MAC auto ON\n");
+ return (ETIMEDOUT);
+ }
+
+ /* Enable radio, GPIO and LED functions. */
+ rtwn_write_2(sc, R92C_APS_FSMCO,
+ R92C_APS_FSMCO_AFSM_PCIE |
+ R92C_APS_FSMCO_PDN_EN |
+ R92C_APS_FSMCO_PFM_ALDN);
+ /* Release RF digital isolation. */
+ rtwn_setbits_2(sc, R92C_SYS_ISO_CTRL, R92C_SYS_ISO_CTRL_DIOR, 0);
+
+ if (rs->chip & R92C_CHIP_92C)
+ rtwn_write_1(sc, R92C_PCIE_CTRL_REG + 3, 0x77);
+ else
+ rtwn_write_1(sc, R92C_PCIE_CTRL_REG + 3, 0x22);
+
+ rtwn_write_4(sc, R92C_INT_MIG, 0);
+
+ if (rs->board_type != R92C_BOARD_TYPE_DONGLE) {
+ /* bt coex */
+ /* XXX magic from linux */
+ rtwn_setbits_1(sc, R92C_AFE_XTAL_CTRL + 2, 0x02, 0);
+ }
+
+ rtwn_setbits_1(sc, R92C_GPIO_MUXCFG, R92C_GPIO_MUXCFG_RFKILL, 0);
+
+ reg = rtwn_read_1(sc, R92C_GPIO_IO_SEL);
+ if (!(reg & R92C_GPIO_IO_SEL_RFKILL)) {
+ device_printf(sc->sc_dev,
+ "radio is disabled by hardware switch\n");
+ /* XXX how driver will know when radio will be enabled? */
+ return (EPERM);
+ }
+
+ /* Initialize MAC. */
+ rtwn_setbits_1(sc, R92C_APSD_CTRL, R92C_APSD_CTRL_OFF, 0);
+ for (ntries = 0; ntries < 200; ntries++) {
+ if (!(rtwn_read_1(sc, R92C_APSD_CTRL) &
+ R92C_APSD_CTRL_OFF_STATUS))
+ break;
+ DELAY(500);
+ }
+ if (ntries == 200) {
+ device_printf(sc->sc_dev,
+ "timeout waiting for MAC initialization\n");
+ return (ETIMEDOUT);
+ }
+
+ /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
+ rtwn_setbits_2(sc, R92C_CR, 0,
+ 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 |
+ ((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0));
+
+ rtwn_write_4(sc, R92C_MCUTST_1, 0x0);
+
+ return (0);
+}
+
+void
+r92ce_power_off(struct rtwn_softc *sc)
+{
+#ifndef RTWN_WITHOUT_UCODE
+ struct r92c_softc *rs = sc->sc_priv;
+
+ /* Deinit C2H event handler. */
+ callout_stop(&rs->rs_c2h_report);
+ rs->rs_c2h_paused = 0;
+ rs->rs_c2h_pending = 0;
+ rs->rs_c2h_timeout = hz;
+#endif
+
+ /* Stop hardware. */
+ /* Disable interrupts. */
+ rtwn_write_4(sc, R92C_HISR, 0);
+ rtwn_write_4(sc, R92C_HIMR, 0);
+
+ /* Stop hardware. */
+ rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
+
+ /* Turn off RF. */
+ rtwn_write_1(sc, R92C_RF_CTRL, 0);
+
+ /* Reset BB state machine */
+ rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, 0, R92C_SYS_FUNC_EN_BB_GLB_RST);
+ rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_BB_GLB_RST, 0);
+
+ /* Disable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
+ rtwn_setbits_2(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 | R92C_CR_MACTXEN | R92C_CR_MACRXEN |
+ R92C_CR_ENSEC,
+ 0);
+
+ /* If firmware in ram code, do reset. */
+#ifndef RTWN_WITHOUT_UCODE
+ if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL)
+ r92ce_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN);
+#endif
+
+ /* TODO: linux does additional btcoex stuff here */
+ rtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0x80); /* linux magic number */
+ rtwn_write_1(sc, R92C_SPS0_CTRL, 0x23); /* ditto */
+ rtwn_write_1(sc, R92C_AFE_XTAL_CTRL, 0x0e); /* different with btcoex */
+ rtwn_write_1(sc, R92C_RSV_CTRL, 0x0e);
+ rtwn_write_1(sc, R92C_APS_FSMCO, R92C_APS_FSMCO_PDN_EN);
+}
+
+void
+r92ce_init_ampdu(struct rtwn_softc *sc)
+{
+
+ /* Setup AMPDU aggregation. */
+ rtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */
+ rtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
+}
+
+void
+r92ce_post_init(struct rtwn_softc *sc)
+{
+ rtwn_write_2(sc, R92C_FWHW_TXQ_CTRL,
+ 0x1f00 | R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW);
+
+ rtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff);
+
+ /* Perform LO and IQ calibrations. */
+ r92ce_iq_calib(sc);
+ /* Perform LC calibration. */
+ r92c_lc_calib(sc);
+
+ r92c_pa_bias_init(sc);
+
+ /* Fix for lower temperature. */
+ rtwn_write_1(sc, 0x15, 0xe9);
+
+#ifndef RTWN_WITHOUT_UCODE
+ if (sc->sc_flags & RTWN_FW_LOADED) {
+ struct r92c_softc *rs = sc->sc_priv;
+
+ if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) {
+ /* XXX TODO: fix (see comment in r92cu_init.c) */
+ sc->sc_ratectl = RTWN_RATECTL_NET80211;
+ } else
+ sc->sc_ratectl = sc->sc_ratectl_sysctl;
+
+ /* Start C2H event handling. */
+ callout_reset(&rs->rs_c2h_report, rs->rs_c2h_timeout,
+ r92c_handle_c2h_report, sc);
+ } else
+#endif
+ sc->sc_ratectl = RTWN_RATECTL_NONE;
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_led.c b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_led.c
new file mode 100644
index 00000000..28273a38
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_led.c
@@ -0,0 +1,69 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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 <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.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/pci/rtwn_pci_var.h>
+
+#include <dev/rtwn/rtl8192c/pci/r92ce.h>
+#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
+
+void
+r92ce_set_led(struct rtwn_softc *sc, int led, int on)
+{
+
+ if (led == RTWN_LED_LINK) {
+ rtwn_setbits_1(sc, R92C_LEDCFG2, 0x0f,
+ on ? R92C_LEDCFG2_EN : R92C_LEDCFG2_DIS);
+ sc->ledlink = on; /* Save LED state. */
+ }
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_priv.h b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_priv.h
new file mode 100644
index 00000000..7416516c
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_priv.h
@@ -0,0 +1,182 @@
+/* $OpenBSD: if_rtwnreg.h,v 1.3 2015/06/14 08:02:47 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef R92CE_PRIV_H
+#define R92CE_PRIV_H
+
+#include <dev/rtwn/rtl8192c/r92c_priv.h>
+
+
+/*
+ * MAC initialization values.
+ */
+static const struct rtwn_mac_prog rtl8192ce_mac[] = {
+ { 0x420, 0x80 }, { 0x423, 0x00 }, { 0x430, 0x00 }, { 0x431, 0x00 },
+ { 0x432, 0x00 }, { 0x433, 0x01 }, { 0x434, 0x04 }, { 0x435, 0x05 },
+ { 0x436, 0x06 }, { 0x437, 0x07 }, { 0x438, 0x00 }, { 0x439, 0x00 },
+ { 0x43a, 0x00 }, { 0x43b, 0x01 }, { 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, 0x88 }, { 0x461, 0x88 }, { 0x462, 0x06 },
+ { 0x463, 0x03 }, { 0x4c8, 0x04 }, { 0x4c9, 0x08 }, { 0x4cc, 0x02 },
+ { 0x4cd, 0x28 }, { 0x4ce, 0x01 }, { 0x500, 0x26 }, { 0x501, 0xa2 },
+ { 0x502, 0x2f }, { 0x503, 0x00 }, { 0x504, 0x28 }, { 0x505, 0xa3 },
+ { 0x506, 0x5e }, { 0x507, 0x00 }, { 0x508, 0x2b }, { 0x509, 0xa4 },
+ { 0x50a, 0x5e }, { 0x50b, 0x00 }, { 0x50c, 0x4f }, { 0x50d, 0xa4 },
+ { 0x50e, 0x00 }, { 0x50f, 0x00 }, { 0x512, 0x1c }, { 0x514, 0x0a },
+ { 0x515, 0x10 }, { 0x516, 0x0a }, { 0x517, 0x10 }, { 0x51a, 0x16 },
+ { 0x524, 0x0f }, { 0x525, 0x4f }, { 0x546, 0x20 }, { 0x547, 0x00 },
+ { 0x559, 0x02 }, { 0x55a, 0x02 }, { 0x55d, 0xff }, { 0x605, 0x30 },
+ { 0x608, 0x0e }, { 0x609, 0x2a }, { 0x652, 0x20 }, { 0x63c, 0x0a },
+ { 0x63d, 0x0e }, { 0x700, 0x21 }, { 0x701, 0x43 }, { 0x702, 0x65 },
+ { 0x703, 0x87 }, { 0x708, 0x21 }, { 0x709, 0x43 }, { 0x70a, 0x65 },
+ { 0x70b, 0x87 }
+};
+
+
+/*
+ * Baseband initialization values.
+ */
+static const uint16_t rtl8192ce_bb_regs0[] = {
+ 0x024, 0x028, 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, 0xa00, 0xa04, 0xa08, 0xa0c, 0xa10, 0xa14, 0xa18, 0xa1c,
+ 0xa20, 0xa24, 0xa28, 0xa2c, 0xa70, 0xa74, 0xc00, 0xc04
+}, rtl8192ce_bb_regs1[] = {
+ 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
+};
+
+static const uint32_t rtl8192ce_bb_vals0_2t[] = {
+ 0x0011800f, 0x00ffdb83, 0x80040002, 0x00000003, 0x0000fc00,
+ 0x0000000a, 0x10005388, 0x020c3d10, 0x02200385, 0x00000000,
+ 0x01000100, 0x00390004, 0x01000100, 0x00390004, 0x27272727,
+ 0x27272727, 0x27272727, 0x27272727, 0x00010000, 0x00010000,
+ 0x27272727, 0x27272727, 0x00000000, 0x00000000, 0x569a569a,
+ 0x0c1b25a4, 0x66e60230, 0x061f0130, 0x27272727, 0x2b2b2b27,
+ 0x07000700, 0x22184000, 0x08080808, 0x00000000, 0xc0083070,
+ 0x000004d5, 0x00000000, 0xcc0000c0, 0x00000800, 0xfffffffe,
+ 0x40302010, 0x00706050, 0x00000000, 0x00000023, 0x00000000,
+ 0x81121313, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e68120f,
+ 0x9500bb78, 0x11144028, 0x00881117, 0x89140f00, 0x1a1b0000,
+ 0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
+ 0x48071d40, 0x03a05633
+}, rtl8192ce_bb_vals0_1t[] = {
+ 0x0011800f, 0x00ffdb83, 0x80040000, 0x00000001, 0x0000fc00,
+ 0x0000000a, 0x10005388, 0x020c3d10, 0x02200385, 0x00000000,
+ 0x01000100, 0x00390004, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x569a569a,
+ 0x001b25a4, 0x66e60230, 0x061f0130, 0x00000000, 0x32323200,
+ 0x07000700, 0x22004000, 0x00000808, 0x00000000, 0xc0083070,
+ 0x000004d5, 0x00000000, 0xccc000c0, 0x00000800, 0xfffffffe,
+ 0x40302010, 0x00706050, 0x00000000, 0x00000023, 0x00000000,
+ 0x81121111, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e68120f,
+ 0x9500bb78, 0x11144028, 0x00881117, 0x89140f00, 0x1a1b0000,
+ 0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
+ 0x48071d40, 0x03a05611
+}, rtl8192ce_bb_vals1[] = {
+ 0x000000e4, 0x6c6c6c6c, 0x08800000, 0x40000100, 0x08800000,
+ 0x40000100, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x69e9ac44, 0x469652cf, 0x49795994, 0x0a97971c, 0x1f7c403f,
+ 0x000100b7, 0xec020107, 0x007f037f, 0x69543420, 0x43bc0094,
+ 0x69543420, 0x433c0094, 0x00000000, 0x5116848b, 0x47c00bff,
+ 0x00000036, 0x2c7f000d, 0x018610db, 0x0000001f, 0x00b91612,
+ 0x40000100, 0x20f60000, 0x40000100, 0x20200000, 0x00121820,
+ 0x00000000, 0x00121820, 0x00007f7f, 0x00000000, 0x00000080,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x28000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x64b22427, 0x00766932, 0x00222222,
+ 0x00000000, 0x37644302, 0x2f97d40c, 0x00080740
+}, rtl8192ce_bb_vals4_1t[] = {
+ 0x00000010, 0x001b25a4, 0x631b25a0, 0x631b25a0, 0x081b25a0,
+ 0x081b25a0, 0x081b25a0, 0x081b25a0, 0x631b25a0, 0x081b25a0,
+ 0x631b25a0, 0x631b25a0, 0x631b25a0, 0x631b25a0, 0x001b25a0,
+ 0x001b25a0, 0x6b1b25a0, 0x00000003, 0x00000000, 0x00000300
+};
+
+static const struct rtwn_bb_prog rtl8192ce_bb[] = {
+ {
+ nitems(rtl8192ce_bb_regs0),
+ rtl8192ce_bb_regs0,
+ rtl8192ce_bb_vals0_2t,
+ { R92C_COND_RTL8192C },
+ &(const struct rtwn_bb_prog){
+ nitems(rtl8192ce_bb_regs0),
+ rtl8192ce_bb_regs0,
+ rtl8192ce_bb_vals0_1t,
+ { 0 },
+ NULL
+ }
+ },
+ {
+ nitems(rtl8192ce_bb_regs1),
+ rtl8192ce_bb_regs1,
+ rtl8192ce_bb_vals1,
+ { 0 },
+ NULL
+ },
+ {
+ nitems(rtl8192c_bb_regs3),
+ rtl8192c_bb_regs3,
+ rtl8192c_bb_vals3_92ce_92cu,
+ { R92C_COND_RTL8192C },
+ &(const struct rtwn_bb_prog){
+ nitems(rtl8192c_bb_regs3),
+ rtl8192c_bb_regs3,
+ rtl8192c_bb_vals3_88cu_88ru,
+ { 0 },
+ NULL
+ }
+ },
+ {
+ nitems(rtl8192c_bb_regs4),
+ rtl8192c_bb_regs4,
+ rtl8192c_bb_vals4,
+ { 0 },
+ NULL
+ },
+ {
+ nitems(rtl8192c_bb_regs5),
+ rtl8192c_bb_regs5,
+ rtl8192c_bb_vals5_92ce_92cu,
+ { R92C_COND_RTL8192C },
+ &(const struct rtwn_bb_prog){
+ nitems(rtl8192c_bb_regs5),
+ rtl8192c_bb_regs5,
+ rtl8192ce_bb_vals4_1t,
+ { 0 },
+ NULL
+ }
+ }
+};
+
+#endif /* R92CE_PRIV_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_reg.h b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_reg.h
new file mode 100644
index 00000000..355d8f46
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_reg.h
@@ -0,0 +1,103 @@
+/* $OpenBSD: if_rtwnreg.h,v 1.3 2015/06/14 08:02:47 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef R92CE_REG_H
+#define R92CE_REG_H
+
+#include <dev/rtwn/rtl8192c/r92c_reg.h>
+
+/*
+ * MAC registers.
+ */
+/* System Configuration. */
+#define R92C_PCIE_MIO_INTF 0x0e4
+#define R92C_PCIE_MIO_INTD 0x0e8
+/* PCIe Configuration. */
+#define R92C_PCIE_CTRL_REG 0x300
+#define R92C_INT_MIG 0x304
+#define R92C_BCNQ_DESA 0x308
+#define R92C_HQ_DESA 0x310
+#define R92C_MGQ_DESA 0x318
+#define R92C_VOQ_DESA 0x320
+#define R92C_VIQ_DESA 0x328
+#define R92C_BEQ_DESA 0x330
+#define R92C_BKQ_DESA 0x338
+#define R92C_RX_DESA 0x340
+#define R92C_DBI 0x348
+#define R92C_MDIO 0x354
+#define R92C_DBG_SEL 0x360
+#define R92C_PCIE_HRPWM 0x361
+#define R92C_PCIE_HCPWM 0x363
+#define R92C_UART_CTRL 0x364
+#define R92C_UART_TX_DES 0x370
+#define R92C_UART_RX_DES 0x378
+
+
+/* Bits for R92C_GPIO_MUXCFG. */
+#define R92C_GPIO_MUXCFG_RFKILL 0x0008
+
+/* Bits for R92C_GPIO_IO_SEL. */
+#define R92C_GPIO_IO_SEL_RFKILL 0x0008
+
+/* Bits for R92C_LEDCFG2. */
+#define R92C_LEDCFG2_EN 0x60
+#define R92C_LEDCFG2_DIS 0x68
+
+/* Bits for R92C_HIMR. */
+#define R92C_IMR_ROK 0x00000001 /* receive DMA OK */
+#define R92C_IMR_VODOK 0x00000002 /* AC_VO DMA OK */
+#define R92C_IMR_VIDOK 0x00000004 /* AC_VI DMA OK */
+#define R92C_IMR_BEDOK 0x00000008 /* AC_BE DMA OK */
+#define R92C_IMR_BKDOK 0x00000010 /* AC_BK DMA OK */
+#define R92C_IMR_TXBDER 0x00000020 /* beacon transmit error */
+#define R92C_IMR_MGNTDOK 0x00000040 /* management queue DMA OK */
+#define R92C_IMR_TBDOK 0x00000080 /* beacon transmit OK */
+#define R92C_IMR_HIGHDOK 0x00000100 /* high queue DMA OK */
+#define R92C_IMR_BDOK 0x00000200 /* beacon queue DMA OK */
+#define R92C_IMR_ATIMEND 0x00000400 /* ATIM window end interrupt */
+#define R92C_IMR_RDU 0x00000800 /* Rx descriptor unavailable */
+#define R92C_IMR_RXFOVW 0x00001000 /* receive FIFO overflow */
+#define R92C_IMR_BCNINT 0x00002000 /* beacon DMA interrupt 0 */
+#define R92C_IMR_PSTIMEOUT 0x00004000 /* powersave timeout */
+#define R92C_IMR_TXFOVW 0x00008000 /* transmit FIFO overflow */
+#define R92C_IMR_TIMEOUT1 0x00010000 /* timeout interrupt 1 */
+#define R92C_IMR_TIMEOUT2 0x00020000 /* timeout interrupt 2 */
+#define R92C_IMR_BCNDOK1 0x00040000 /* beacon queue DMA OK (1) */
+#define R92C_IMR_BCNDOK2 0x00080000 /* beacon queue DMA OK (2) */
+#define R92C_IMR_BCNDOK3 0x00100000 /* beacon queue DMA OK (3) */
+#define R92C_IMR_BCNDOK4 0x00200000 /* beacon queue DMA OK (4) */
+#define R92C_IMR_BCNDOK5 0x00400000 /* beacon queue DMA OK (5) */
+#define R92C_IMR_BCNDOK6 0x00800000 /* beacon queue DMA OK (6) */
+#define R92C_IMR_BCNDOK7 0x01000000 /* beacon queue DMA OK (7) */
+#define R92C_IMR_BCNDOK8 0x02000000 /* beacon queue DMA OK (8) */
+#define R92C_IMR_BCNDMAINT1 0x04000000 /* beacon DMA interrupt 1 */
+#define R92C_IMR_BCNDMAINT2 0x08000000 /* beacon DMA interrupt 2 */
+#define R92C_IMR_BCNDMAINT3 0x10000000 /* beacon DMA interrupt 3 */
+#define R92C_IMR_BCNDMAINT4 0x20000000 /* beacon DMA interrupt 4 */
+#define R92C_IMR_BCNDMAINT5 0x40000000 /* beacon DMA interrupt 5 */
+#define R92C_IMR_BCNDMAINT6 0x80000000 /* beacon DMA interrupt 6 */
+
+/* Shortcut. */
+#define R92C_IBSS_INT_MASK \
+ (R92C_IMR_BCNINT | R92C_IMR_TBDOK | R92C_IMR_TBDER)
+
+#endif /* R92CE_REG_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_rx.c b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_rx.c
new file mode 100644
index 00000000..d496e7b8
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_rx.c
@@ -0,0 +1,134 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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 <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.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/if_rtwn_debug.h>
+
+#include <dev/rtwn/pci/rtwn_pci_var.h>
+
+#include <dev/rtwn/rtl8192c/pci/r92ce.h>
+#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
+
+
+int
+r92ce_classify_intr(struct rtwn_softc *sc, void *arg, int len __unused)
+{
+ uint32_t status;
+ int *rings = arg;
+ int ret;
+
+ *rings = 0;
+ status = rtwn_read_4(sc, R92C_HISR);
+ RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: HISR %08X, HISRE %04X\n",
+ __func__, status, rtwn_read_2(sc, R92C_HISRE));
+ if (status == 0 || status == 0xffffffff)
+ return (0);
+
+ /* Disable interrupts. */
+ rtwn_write_4(sc, R92C_HIMR, 0);
+
+ /* Ack interrupts. */
+ rtwn_write_4(sc, R92C_HISR, status);
+
+ if (status & R92C_IMR_BDOK)
+ *rings |= (1 << RTWN_PCI_BEACON_QUEUE);
+ if (status & R92C_IMR_HIGHDOK)
+ *rings |= (1 << RTWN_PCI_HIGH_QUEUE);
+ if (status & R92C_IMR_MGNTDOK)
+ *rings |= (1 << RTWN_PCI_MGNT_QUEUE);
+ if (status & R92C_IMR_BKDOK)
+ *rings |= (1 << RTWN_PCI_BK_QUEUE);
+ if (status & R92C_IMR_BEDOK)
+ *rings |= (1 << RTWN_PCI_BE_QUEUE);
+ if (status & R92C_IMR_VIDOK)
+ *rings |= (1 << RTWN_PCI_VI_QUEUE);
+ if (status & R92C_IMR_VODOK)
+ *rings |= (1 << RTWN_PCI_VO_QUEUE);
+
+ ret = 0;
+ if (status & R92C_IMR_RXFOVW)
+ ret |= RTWN_PCI_INTR_RX_OVERFLOW;
+ if (status & R92C_IMR_RDU)
+ ret |= RTWN_PCI_INTR_RX_DESC_UNAVAIL;
+ if (status & R92C_IMR_ROK)
+ ret |= RTWN_PCI_INTR_RX_DONE;
+ if (status & R92C_IMR_TXFOVW)
+ ret |= RTWN_PCI_INTR_TX_OVERFLOW;
+ if (status & R92C_IMR_PSTIMEOUT)
+ ret |= RTWN_PCI_INTR_PS_TIMEOUT;
+
+ return (ret);
+}
+
+#define R92C_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)
+void
+r92ce_enable_intr(struct rtwn_pci_softc *pc)
+{
+ struct rtwn_softc *sc = &pc->pc_sc;
+
+ /* Enable interrupts. */
+ rtwn_write_4(sc, R92C_HIMR, R92C_INT_ENABLE);
+}
+
+void
+r92ce_start_xfers(struct rtwn_softc *sc)
+{
+ /* Clear pending interrupts. */
+ rtwn_write_4(sc, R92C_HISR, 0xffffffff);
+
+ /* Enable interrupts. */
+ rtwn_write_4(sc, R92C_HIMR, R92C_INT_ENABLE);
+}
+#undef R92C_INT_ENABLE
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_rx_desc.h b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_rx_desc.h
new file mode 100644
index 00000000..476a9e88
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_rx_desc.h
@@ -0,0 +1,41 @@
+/* $OpenBSD: if_rtwnreg.h,v 1.3 2015/06/14 08:02:47 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef R92CE_RX_DESC_H
+#define R92CE_RX_DESC_H
+
+#include <dev/rtwn/rtl8192c/r92c_rx_desc.h>
+
+/* Rx MAC descriptor (PCIe). */
+struct r92ce_rx_stat {
+ uint32_t rxdw0;
+ uint32_t rxdw1;
+ uint32_t rxdw2;
+ uint32_t rxdw3;
+ uint32_t rxdw4;
+ uint32_t tsf_low;
+
+ uint32_t rxbufaddr;
+ uint32_t rxbufaddr64;
+} __packed __attribute__((aligned(4)));
+
+#endif /* R92CE_RX_DESC_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_tx.c b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_tx.c
new file mode 100644
index 00000000..31d621bd
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_tx.c
@@ -0,0 +1,117 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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 <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.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/if_rtwn_debug.h>
+
+#include <dev/rtwn/pci/rtwn_pci_var.h>
+
+#include <dev/rtwn/rtl8192c/pci/r92ce.h>
+#include <dev/rtwn/rtl8192c/pci/r92ce_tx_desc.h>
+
+
+void
+r92ce_setup_tx_desc(struct rtwn_pci_softc *pc, void *desc,
+ uint32_t next_desc_addr)
+{
+ struct r92ce_tx_desc *txd = desc;
+
+ /* setup tx desc */
+ txd->nextdescaddr = htole32(next_desc_addr);
+}
+
+void
+r92ce_tx_postsetup(struct rtwn_pci_softc *pc, void *desc,
+ bus_dma_segment_t segs[])
+{
+ struct r92ce_tx_desc *txd = desc;
+
+ txd->txbufaddr = htole32(segs[0].ds_addr);
+ txd->txbufsize = txd->pktlen;
+ bus_space_barrier(pc->pc_st, pc->pc_sh, 0, pc->pc_mapsize,
+ BUS_SPACE_BARRIER_WRITE);
+}
+
+void
+r92ce_copy_tx_desc(void *dest, const void *src)
+{
+ struct r92ce_tx_desc *txd = dest;
+ size_t len = sizeof(struct r92c_tx_desc) +
+ sizeof(txd->txbufsize) + sizeof(txd->pad);
+
+ if (src != NULL)
+ memcpy(dest, src, len);
+ else
+ memset(dest, 0, len);
+}
+
+void
+r92ce_dump_tx_desc(struct rtwn_softc *sc, const void *desc)
+{
+#ifdef RTWN_DEBUG
+ const struct r92ce_tx_desc *txd = desc;
+
+ RTWN_DPRINTF(sc, RTWN_DEBUG_XMIT_DESC,
+ "%s: len %d, off %d, flags0 %02X, dw: 1 %08X, 2 %08X, 3 %04X "
+ "(seq %04X), 4 %08X, 5 %08X, 6 %08X, size %04X, pad %04X, "
+ "addr: %08X (64: %08X), next: %08X (64: %08X), "
+ "rsvd: %08X %08X %08X %08X\n",
+ __func__, le16toh(txd->pktlen), txd->offset, txd->flags0,
+ le32toh(txd->txdw1), le32toh(txd->txdw2), le16toh(txd->txdw3),
+ le16toh(txd->txdseq), le32toh(txd->txdw4), le32toh(txd->txdw5),
+ le32toh(txd->txdw6), le16toh(txd->txbufsize), le16toh(txd->pad),
+ le32toh(txd->txbufaddr), le32toh(txd->txbufaddr64),
+ le32toh(txd->nextdescaddr), le32toh(txd->nextdescaddr64),
+ le32toh(txd->reserved[0]), le32toh(txd->reserved[1]),
+ le32toh(txd->reserved[2]), le32toh(txd->reserved[3]));
+#endif
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_tx_desc.h b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_tx_desc.h
new file mode 100644
index 00000000..4153710a
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_tx_desc.h
@@ -0,0 +1,55 @@
+/* $OpenBSD: if_rtwnreg.h,v 1.3 2015/06/14 08:02:47 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef R92CE_TX_DESC_H
+#define R92CE_TX_DESC_H
+
+#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
+
+/* Tx MAC descriptor (PCIe). */
+struct r92ce_tx_desc {
+ uint16_t pktlen;
+ uint8_t offset;
+ uint8_t flags0;
+
+ uint32_t txdw1;
+ uint32_t txdw2;
+ uint16_t txdw3;
+ uint16_t txdseq;
+
+ uint32_t txdw4;
+ uint32_t txdw5;
+ uint32_t txdw6;
+
+ uint16_t txbufsize;
+ uint16_t pad;
+
+ uint32_t txbufaddr;
+ uint32_t txbufaddr64;
+
+ uint32_t nextdescaddr;
+ uint32_t nextdescaddr64;
+
+ uint32_t reserved[4];
+} __packed __attribute__((aligned(4)));
+
+#endif /* R92CE_TX_DESC_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c.h
new file mode 100644
index 00000000..2b63179e
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c.h
@@ -0,0 +1,114 @@
+/*-
+ * 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 RTL8192C_H
+#define RTL8192C_H
+
+/*
+ * Global definitions.
+ */
+#define R92C_TXPKTBUF_COUNT 256
+
+#define R92C_TX_PAGE_SIZE 128
+#define R92C_RX_DMA_BUFFER_SIZE 0x2800
+
+#define R92C_MAX_FW_SIZE 0x4000
+#define R92C_MACID_MAX 31
+#define R92C_CAM_ENTRY_COUNT 32
+
+#define R92C_CALIB_THRESHOLD 2
+
+
+/*
+ * Function declarations.
+ */
+/* r92c_attach.c */
+void r92c_detach_private(struct rtwn_softc *);
+void r92c_read_chipid_vendor(struct rtwn_softc *, uint32_t);
+
+/* r92c_beacon.c */
+void r92c_beacon_init(struct rtwn_softc *, void *, int);
+void r92c_beacon_enable(struct rtwn_softc *, int, int);
+
+/* r92c_calib.c */
+void r92c_iq_calib(struct rtwn_softc *);
+void r92c_lc_calib(struct rtwn_softc *);
+void r92c_temp_measure(struct rtwn_softc *);
+uint8_t r92c_temp_read(struct rtwn_softc *);
+
+/* r92c_chan.c */
+void r92c_get_txpower(struct rtwn_softc *, int,
+ struct ieee80211_channel *, uint16_t[]);
+void r92c_set_bw20(struct rtwn_softc *, uint8_t);
+void r92c_set_chan(struct rtwn_softc *, struct ieee80211_channel *);
+void r92c_set_gain(struct rtwn_softc *, uint8_t);
+void r92c_scan_start(struct ieee80211com *);
+void r92c_scan_end(struct ieee80211com *);
+
+/* r92c_fw.c */
+#ifndef RTWN_WITHOUT_UCODE
+void r92c_fw_reset(struct rtwn_softc *, int);
+void r92c_fw_download_enable(struct rtwn_softc *, int);
+#endif
+void r92c_joinbss_rpt(struct rtwn_softc *, int);
+#ifndef RTWN_WITHOUT_UCODE
+int r92c_set_rsvd_page(struct rtwn_softc *, int, int, int);
+int r92c_set_pwrmode(struct rtwn_softc *, struct ieee80211vap *, int);
+void r92c_set_rssi(struct rtwn_softc *);
+void r92c_handle_c2h_report(void *);
+#endif
+
+/* r92c_init.c */
+int r92c_check_condition(struct rtwn_softc *, const uint8_t[]);
+int r92c_set_page_size(struct rtwn_softc *);
+void r92c_init_bb_common(struct rtwn_softc *);
+int r92c_init_rf_chain(struct rtwn_softc *,
+ const struct rtwn_rf_prog *, int);
+void r92c_init_rf(struct rtwn_softc *);
+void r92c_init_edca(struct rtwn_softc *);
+void r92c_init_ampdu(struct rtwn_softc *);
+void r92c_init_antsel(struct rtwn_softc *);
+void r92c_pa_bias_init(struct rtwn_softc *);
+
+/* r92c_rf.c */
+uint32_t r92c_rf_read(struct rtwn_softc *, int, uint8_t);
+void r92c_rf_write(struct rtwn_softc *, int, uint8_t, uint32_t);
+
+/* r92c_rom.c */
+void r92c_efuse_postread(struct rtwn_softc *);
+void r92c_parse_rom(struct rtwn_softc *, uint8_t *);
+
+/* r92c_rx.c */
+int8_t r92c_get_rssi_cck(struct rtwn_softc *, void *);
+int8_t r92c_get_rssi_ofdm(struct rtwn_softc *, void *);
+uint8_t r92c_rx_radiotap_flags(const void *);
+
+/* r92c_tx.c */
+void r92c_tx_enable_ampdu(void *, int);
+void r92c_tx_setup_hwseq(void *);
+void r92c_tx_setup_macid(void *, int);
+void r92c_fill_tx_desc(struct rtwn_softc *, struct ieee80211_node *,
+ struct mbuf *, void *, uint8_t, int);
+void r92c_fill_tx_desc_raw(struct rtwn_softc *, struct ieee80211_node *,
+ struct mbuf *, void *, const struct ieee80211_bpf_params *);
+void r92c_fill_tx_desc_null(struct rtwn_softc *, void *, int, int, int);
+uint8_t r92c_tx_radiotap_flags(const void *);
+
+#endif /* RTL8192C_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_attach.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_attach.c
new file mode 100644
index 00000000..cfb76acc
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_attach.c
@@ -0,0 +1,82 @@
+#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/rtl8192c/r92c.h>
+#include <dev/rtwn/rtl8192c/r92c_reg.h>
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+
+
+void
+r92c_detach_private(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+
+ free(rs, M_RTWN_PRIV);
+}
+
+void
+r92c_read_chipid_vendor(struct rtwn_softc *sc, uint32_t reg_sys_cfg)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+
+ if (reg_sys_cfg & R92C_SYS_CFG_TYPE_92C) {
+ rs->chip |= R92C_CHIP_92C;
+ /* Check if it is a castrated 8192C. */
+ if (MS(rtwn_read_4(sc, R92C_HPON_FSM),
+ R92C_HPON_FSM_CHIP_BONDING_ID) ==
+ R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R)
+ rs->chip |= R92C_CHIP_92C_1T2R;
+ }
+ if (reg_sys_cfg & R92C_SYS_CFG_VENDOR_UMC) {
+ if (MS(reg_sys_cfg, R92C_SYS_CFG_CHIP_VER_RTL) == 0)
+ rs->chip |= R92C_CHIP_UMC_A_CUT;
+ }
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_beacon.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_beacon.c
new file mode 100644
index 00000000..fc106a47
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_beacon.c
@@ -0,0 +1,88 @@
+#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/if_rtwnreg.h>
+
+#include <dev/rtwn/if_rtwn_ridx.h>
+
+#include <dev/rtwn/rtl8192c/r92c.h>
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+#include <dev/rtwn/rtl8192c/r92c_reg.h>
+#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
+
+
+void
+r92c_beacon_init(struct rtwn_softc *sc, void *buf, int id)
+{
+ struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
+
+ /*
+ * NB: there is no need to setup HWSEQ_EN bit;
+ * QSEL_BEACON already implies it.
+ */
+ txd->flags0 |= R92C_FLAGS0_BMCAST | R92C_FLAGS0_FSG | R92C_FLAGS0_LSG;
+ txd->txdw1 |= htole32(
+ SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BEACON) |
+ SM(R92C_TXDW1_RAID, R92C_RAID_11B));
+
+ rtwn_r92c_tx_setup_macid(sc, buf, id);
+ txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
+ txd->txdw4 |= htole32(SM(R92C_TXDW4_SEQ_SEL, id));
+ txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, id));
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, RTWN_RIDX_CCK1));
+}
+
+void
+r92c_beacon_enable(struct rtwn_softc *sc, int id, int enable)
+{
+
+ if (enable) {
+ rtwn_setbits_1(sc, R92C_BCN_CTRL(id),
+ 0, R92C_BCN_CTRL_EN_BCN);
+ } else {
+ rtwn_setbits_1(sc, R92C_BCN_CTRL(id),
+ R92C_BCN_CTRL_EN_BCN, 0);
+ }
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_calib.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_calib.c
new file mode 100644
index 00000000..e7706b8d
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_calib.c
@@ -0,0 +1,115 @@
+#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/rtl8192c/r92c.h>
+#include <dev/rtwn/rtl8192c/r92c_reg.h>
+
+
+void
+r92c_iq_calib(struct rtwn_softc *sc)
+{
+ /* XXX TODO */
+}
+
+void
+r92c_lc_calib(struct rtwn_softc *sc)
+{
+ uint32_t rf_ac[2];
+ uint8_t txmode;
+ int i;
+
+ txmode = rtwn_read_1(sc, R92C_OFDM1_LSTF + 3);
+ if ((txmode & 0x70) != 0) {
+ /* Disable all continuous Tx. */
+ rtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode & ~0x70);
+
+ /* Set RF mode to standby mode. */
+ for (i = 0; i < sc->nrxchains; i++) {
+ rf_ac[i] = rtwn_rf_read(sc, i, R92C_RF_AC);
+ rtwn_rf_write(sc, i, R92C_RF_AC,
+ RW(rf_ac[i], R92C_RF_AC_MODE,
+ R92C_RF_AC_MODE_STANDBY));
+ }
+ } else {
+ /* Block all Tx queues. */
+ rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
+ }
+ /* Start calibration. */
+ rtwn_rf_setbits(sc, 0, R92C_RF_CHNLBW, 0, R92C_RF_CHNLBW_LCSTART);
+
+ /* Give calibration the time to complete. */
+ rtwn_delay(sc, 100000); /* 100ms */
+
+ /* Restore configuration. */
+ if ((txmode & 0x70) != 0) {
+ /* Restore Tx mode. */
+ rtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode);
+ /* Restore RF mode. */
+ for (i = 0; i < sc->nrxchains; i++)
+ rtwn_rf_write(sc, i, R92C_RF_AC, rf_ac[i]);
+ } else {
+ /* Unblock all Tx queues. */
+ rtwn_write_1(sc, R92C_TXPAUSE, 0x00);
+ }
+}
+
+void
+r92c_temp_measure(struct rtwn_softc *sc)
+{
+ rtwn_rf_write(sc, 0, R92C_RF_T_METER, R92C_RF_T_METER_START);
+}
+
+uint8_t
+r92c_temp_read(struct rtwn_softc *sc)
+{
+ return (MS(rtwn_rf_read(sc, 0, R92C_RF_T_METER),
+ R92C_RF_T_METER_VAL));
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c
new file mode 100644
index 00000000..a4ba2766
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c
@@ -0,0 +1,353 @@
+#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/if_rtwn_debug.h>
+#include <dev/rtwn/if_rtwn_ridx.h>
+
+#include <dev/rtwn/rtl8192c/r92c.h>
+#include <dev/rtwn/rtl8192c/r92c_priv.h>
+#include <dev/rtwn/rtl8192c/r92c_reg.h>
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+
+
+static int
+r92c_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 <= 3) group = 0;
+ else if (chan <= 9) group = 1;
+ else if (chan <= 14) group = 2;
+ 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);
+}
+
+/* XXX recheck */
+void
+r92c_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;
+ struct rtwn_r92c_txpwr *rt = rs->rs_txpwr;
+ const struct rtwn_r92c_txagc *base = rs->rs_txagc;
+ uint8_t ofdmpow, htpow, diff, max;
+ int max_mcs, ridx, group;
+
+ /* Determine channel group. */
+ group = r92c_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[chain].pwr[0][ridx];
+ }
+ for (ridx = RTWN_RIDX_OFDM6; ridx < RTWN_RIDX_COUNT; ridx++) {
+ if (rs->regulatory == 3) {
+ power[ridx] = base[chain].pwr[0][ridx];
+ /* Apply vendor limits. */
+ if (IEEE80211_IS_CHAN_HT40(c))
+ max = rt->ht40_max_pwr[chain][group];
+ else
+ max = rt->ht20_max_pwr[chain][group];
+ if (power[ridx] > max)
+ power[ridx] = max;
+ } else if (rs->regulatory == 1) {
+ if (!IEEE80211_IS_CHAN_HT40(c))
+ power[ridx] = base[chain].pwr[group][ridx];
+ } else if (rs->regulatory != 2)
+ power[ridx] = base[chain].pwr[0][ridx];
+ }
+
+ /* Compute per-CCK rate Tx power. */
+ for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++)
+ power[ridx] += rt->cck_tx_pwr[chain][group];
+
+ htpow = rt->ht40_1s_tx_pwr[chain][group];
+ if (sc->ntxchains > 1) {
+ /* Apply reduction for 2 spatial streams. */
+ diff = rt->ht40_2s_tx_pwr_diff[chain][group];
+ htpow = (htpow > diff) ? htpow - diff : 0;
+ }
+
+ /* Compute per-OFDM rate Tx power. */
+ diff = rt->ofdm_tx_pwr_diff[chain][group];
+ ofdmpow = htpow + diff; /* HT->OFDM correction. */
+ for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++)
+ power[ridx] += ofdmpow;
+
+ /* Compute per-MCS Tx power. */
+ if (!IEEE80211_IS_CHAN_HT40(c)) {
+ diff = rt->ht20_tx_pwr_diff[chain][group];
+ htpow += diff; /* HT40->HT20 correction. */
+ }
+ for (ridx = RTWN_RIDX_MCS(0); ridx <= max_mcs; ridx++)
+ power[ridx] += htpow;
+
+ /* 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;
+ }
+}
+
+static void
+r92c_write_txpower(struct rtwn_softc *sc, int chain,
+ uint16_t power[RTWN_RIDX_COUNT])
+{
+ uint32_t reg;
+
+ /* Write per-CCK rate Tx power. */
+ if (chain == 0) {
+ reg = rtwn_bb_read(sc, R92C_TXAGC_A_CCK1_MCS32);
+ reg = RW(reg, R92C_TXAGC_A_CCK1, power[RTWN_RIDX_CCK1]);
+ rtwn_bb_write(sc, R92C_TXAGC_A_CCK1_MCS32, reg);
+ reg = rtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
+ reg = RW(reg, R92C_TXAGC_A_CCK2, power[RTWN_RIDX_CCK2]);
+ reg = RW(reg, R92C_TXAGC_A_CCK55, power[RTWN_RIDX_CCK55]);
+ reg = RW(reg, R92C_TXAGC_A_CCK11, power[RTWN_RIDX_CCK11]);
+ rtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
+ } else {
+ reg = rtwn_bb_read(sc, R92C_TXAGC_B_CCK1_55_MCS32);
+ reg = RW(reg, R92C_TXAGC_B_CCK1, power[RTWN_RIDX_CCK1]);
+ reg = RW(reg, R92C_TXAGC_B_CCK2, power[RTWN_RIDX_CCK2]);
+ reg = RW(reg, R92C_TXAGC_B_CCK55, power[RTWN_RIDX_CCK55]);
+ rtwn_bb_write(sc, R92C_TXAGC_B_CCK1_55_MCS32, reg);
+ reg = rtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
+ reg = RW(reg, R92C_TXAGC_B_CCK11, power[RTWN_RIDX_CCK11]);
+ rtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
+ }
+ /* Write per-OFDM rate Tx power. */
+ rtwn_bb_write(sc, R92C_TXAGC_RATE18_06(chain),
+ SM(R92C_TXAGC_RATE06, power[RTWN_RIDX_OFDM6]) |
+ SM(R92C_TXAGC_RATE09, power[RTWN_RIDX_OFDM9]) |
+ SM(R92C_TXAGC_RATE12, power[RTWN_RIDX_OFDM12]) |
+ SM(R92C_TXAGC_RATE18, power[RTWN_RIDX_OFDM18]));
+ rtwn_bb_write(sc, R92C_TXAGC_RATE54_24(chain),
+ SM(R92C_TXAGC_RATE24, power[RTWN_RIDX_OFDM24]) |
+ SM(R92C_TXAGC_RATE36, power[RTWN_RIDX_OFDM36]) |
+ SM(R92C_TXAGC_RATE48, power[RTWN_RIDX_OFDM48]) |
+ SM(R92C_TXAGC_RATE54, power[RTWN_RIDX_OFDM54]));
+ /* Write per-MCS Tx power. */
+ rtwn_bb_write(sc, R92C_TXAGC_MCS03_MCS00(chain),
+ SM(R92C_TXAGC_MCS00, power[RTWN_RIDX_MCS(0)]) |
+ SM(R92C_TXAGC_MCS01, power[RTWN_RIDX_MCS(1)]) |
+ SM(R92C_TXAGC_MCS02, power[RTWN_RIDX_MCS(2)]) |
+ SM(R92C_TXAGC_MCS03, power[RTWN_RIDX_MCS(3)]));
+ rtwn_bb_write(sc, R92C_TXAGC_MCS07_MCS04(chain),
+ SM(R92C_TXAGC_MCS04, power[RTWN_RIDX_MCS(4)]) |
+ SM(R92C_TXAGC_MCS05, power[RTWN_RIDX_MCS(5)]) |
+ SM(R92C_TXAGC_MCS06, power[RTWN_RIDX_MCS(6)]) |
+ SM(R92C_TXAGC_MCS07, power[RTWN_RIDX_MCS(7)]));
+ if (sc->ntxchains >= 2) {
+ rtwn_bb_write(sc, R92C_TXAGC_MCS11_MCS08(chain),
+ SM(R92C_TXAGC_MCS08, power[RTWN_RIDX_MCS(8)]) |
+ SM(R92C_TXAGC_MCS09, power[RTWN_RIDX_MCS(9)]) |
+ SM(R92C_TXAGC_MCS10, power[RTWN_RIDX_MCS(10)]) |
+ SM(R92C_TXAGC_MCS11, power[RTWN_RIDX_MCS(11)]));
+ rtwn_bb_write(sc, R92C_TXAGC_MCS15_MCS12(chain),
+ SM(R92C_TXAGC_MCS12, power[RTWN_RIDX_MCS(12)]) |
+ SM(R92C_TXAGC_MCS13, power[RTWN_RIDX_MCS(13)]) |
+ SM(R92C_TXAGC_MCS14, power[RTWN_RIDX_MCS(14)]) |
+ SM(R92C_TXAGC_MCS15, power[RTWN_RIDX_MCS(15)]));
+ }
+}
+
+static void
+r92c_set_txpower(struct rtwn_softc *sc, struct ieee80211_channel *c)
+{
+ uint16_t power[RTWN_RIDX_COUNT];
+ int i;
+
+ for (i = 0; i < sc->ntxchains; i++) {
+ /* Compute per-rate Tx power values. */
+ rtwn_r92c_get_txpower(sc, i, c, power);
+#ifdef RTWN_DEBUG
+ if (sc->sc_debug & RTWN_DEBUG_TXPWR) {
+ int ridx;
+
+ /* Dump per-rate Tx power values. */
+ printf("Tx power for chain %d:\n", i);
+ for (ridx = RTWN_RIDX_CCK1;
+ ridx < RTWN_RIDX_COUNT;
+ ridx++)
+ printf("Rate %d = %u\n", ridx, power[ridx]);
+ }
+#endif
+ /* Write per-rate Tx power values to hardware. */
+ r92c_write_txpower(sc, i, power);
+ }
+}
+
+static void
+r92c_set_bw40(struct rtwn_softc *sc, uint8_t chan, int prichlo)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+
+ rtwn_setbits_1(sc, R92C_BWOPMODE, R92C_BWOPMODE_20MHZ, 0);
+ rtwn_setbits_1(sc, R92C_RRSR + 2, 0x6f, (prichlo ? 1 : 2) << 5);
+
+ rtwn_bb_setbits(sc, R92C_FPGA0_RFMOD, 0, R92C_RFMOD_40MHZ);
+ rtwn_bb_setbits(sc, R92C_FPGA1_RFMOD, 0, R92C_RFMOD_40MHZ);
+
+ /* Set CCK side band. */
+ rtwn_bb_setbits(sc, R92C_CCK0_SYSTEM, 0x10,
+ (prichlo ? 0 : 1) << 4);
+
+ rtwn_bb_setbits(sc, R92C_OFDM1_LSTF, 0x0c00,
+ (prichlo ? 1 : 2) << 10);
+
+ rtwn_bb_setbits(sc, R92C_FPGA0_ANAPARAM2,
+ R92C_FPGA0_ANAPARAM2_CBW20, 0);
+
+ rtwn_bb_setbits(sc, 0x818, 0x0c000000, (prichlo ? 2 : 1) << 26);
+
+ /* Select 40MHz bandwidth. */
+ rtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
+ (rs->rf_chnlbw[0] & ~0xfff) | chan);
+}
+
+void
+r92c_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);
+
+ rtwn_bb_setbits(sc, R92C_FPGA0_ANAPARAM2, 0,
+ R92C_FPGA0_ANAPARAM2_CBW20);
+
+ /* Select 20MHz bandwidth. */
+ rtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
+ (rs->rf_chnlbw[0] & ~0xfff) | chan | R92C_RF_CHNLBW_BW20);
+}
+
+void
+r92c_set_chan(struct rtwn_softc *sc, struct ieee80211_channel *c)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ u_int chan;
+ int i;
+
+ chan = rtwn_chan2centieee(c);
+
+ /* Set Tx power for this new channel. */
+ r92c_set_txpower(sc, c);
+
+ for (i = 0; i < sc->nrxchains; i++) {
+ rtwn_rf_write(sc, i, R92C_RF_CHNLBW,
+ RW(rs->rf_chnlbw[i], R92C_RF_CHNLBW_CHNL, chan));
+ }
+ if (IEEE80211_IS_CHAN_HT40(c))
+ r92c_set_bw40(sc, chan, IEEE80211_IS_CHAN_HT40U(c));
+ else
+ rtwn_r92c_set_bw20(sc, chan);
+}
+
+void
+r92c_set_gain(struct rtwn_softc *sc, uint8_t gain)
+{
+
+ rtwn_bb_setbits(sc, R92C_OFDM0_AGCCORE1(0),
+ R92C_OFDM0_AGCCORE1_GAIN_M, gain);
+ rtwn_bb_setbits(sc, R92C_OFDM0_AGCCORE1(1),
+ R92C_OFDM0_AGCCORE1_GAIN_M, gain);
+}
+
+void
+r92c_scan_start(struct ieee80211com *ic)
+{
+ struct rtwn_softc *sc = ic->ic_softc;
+ struct r92c_softc *rs = sc->sc_priv;
+
+ RTWN_LOCK(sc);
+ /* Set gain for scanning. */
+ rtwn_r92c_set_gain(sc, 0x20);
+ RTWN_UNLOCK(sc);
+
+ rs->rs_scan_start(ic);
+}
+
+void
+r92c_scan_end(struct ieee80211com *ic)
+{
+ struct rtwn_softc *sc = ic->ic_softc;
+ struct r92c_softc *rs = sc->sc_priv;
+
+ RTWN_LOCK(sc);
+ /* Set gain under link. */
+ rtwn_r92c_set_gain(sc, 0x32);
+ RTWN_UNLOCK(sc);
+
+ rs->rs_scan_end(ic);
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c
new file mode 100644
index 00000000..74c7d205
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c
@@ -0,0 +1,522 @@
+#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/if_rtwn_rx.h>
+#include <dev/rtwn/if_rtwn_task.h>
+#include <dev/rtwn/if_rtwn_tx.h>
+
+#include <dev/rtwn/rtl8192c/r92c.h>
+#include <dev/rtwn/rtl8192c/r92c_reg.h>
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+#include <dev/rtwn/rtl8192c/r92c_fw_cmd.h>
+#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
+
+
+#ifndef RTWN_WITHOUT_UCODE
+static int
+r92c_fw_cmd(struct rtwn_softc *sc, uint8_t id, const void *buf, int len)
+{
+ struct r92c_fw_cmd cmd;
+ int ntries, error;
+
+ KASSERT(len <= sizeof(cmd.msg),
+ ("%s: firmware command too long (%d > %zu)\n",
+ __func__, len, sizeof(cmd.msg)));
+
+ if (!(sc->sc_flags & RTWN_FW_LOADED)) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_FIRMWARE, "%s: firmware "
+ "was not loaded; command (id %u) 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;
+ if (len > 3) {
+ /* Ext command: [id : byte2 : byte3 : byte4 : byte0 : byte1] */
+ cmd.id |= R92C_CMD_FLAG_EXT;
+ memcpy(cmd.msg, (const uint8_t *)buf + 2, len - 2);
+ memcpy(cmd.msg + 3, buf, 2);
+ } else
+ memcpy(cmd.msg, buf, len);
+
+ /* Write the first word last since that will trigger the FW. */
+ if (len > 3) {
+ error = rtwn_write_2(sc, R92C_HMEBOX_EXT(sc->fwcur),
+ *(uint16_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
+r92c_fw_reset(struct rtwn_softc *sc, int reason)
+{
+ int ntries;
+
+ if (reason == RTWN_FW_RESET_CHECKSUM)
+ return;
+
+ /* Tell 8051 to reset itself. */
+ rtwn_write_1(sc, R92C_HMETFR + 3, 0x20);
+
+ /* Wait until 8051 resets by itself. */
+ for (ntries = 0; ntries < 100; ntries++) {
+ if ((rtwn_read_2(sc, R92C_SYS_FUNC_EN) &
+ R92C_SYS_FUNC_EN_CPUEN) == 0)
+ return;
+ rtwn_delay(sc, 50);
+ }
+ /* Force 8051 reset. */
+ rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN,
+ R92C_SYS_FUNC_EN_CPUEN, 0, 1);
+}
+
+void
+r92c_fw_download_enable(struct rtwn_softc *sc, int enable)
+{
+ if (enable) {
+ /* 8051 enable. */
+ rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN, 0,
+ R92C_SYS_FUNC_EN_CPUEN, 1);
+ /* 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
+
+/*
+ * Initialize firmware rate adaptation.
+ */
+#ifndef RTWN_WITHOUT_UCODE
+static int
+r92c_send_ra_cmd(struct rtwn_softc *sc, int macid, uint32_t rates,
+ int maxrate)
+{
+ struct r92c_fw_cmd_macid_cfg cmd;
+ uint8_t mode;
+ int error = 0;
+
+ /* XXX should be called directly from iv_newstate() for MACID_BC */
+ /* XXX joinbss, not send_ra_cmd() */
+#ifdef RTWN_TODO
+ /* NB: group addressed frames are done at 11bg rates for now */
+ if (ic->ic_curmode == IEEE80211_MODE_11B)
+ mode = R92C_RAID_11B;
+ else
+ mode = R92C_RAID_11BG;
+ /* XXX misleading 'mode' value here for unicast frames */
+ RTWN_DPRINTF(sc, RTWN_DEBUG_RA,
+ "%s: mode 0x%x, rates 0x%08x, basicrates 0x%08x\n", __func__,
+ mode, rates, basicrates);
+
+ /* Set rates mask for group addressed frames. */
+ cmd.macid = RTWN_MACID_BC | R92C_CMD_MACID_VALID;
+ cmd.mask = htole32(mode << 28 | basicrates);
+ error = rtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd));
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "could not set RA mask for broadcast station\n");
+ return (error);
+ }
+#endif
+
+ /* Set rates mask for unicast frames. */
+ if (maxrate >= RTWN_RIDX_MCS(0))
+ mode = R92C_RAID_11GN;
+ else if (maxrate >= RTWN_RIDX_OFDM6)
+ mode = R92C_RAID_11BG;
+ else
+ mode = R92C_RAID_11B;
+ cmd.macid = macid | R92C_CMD_MACID_VALID;
+ cmd.mask = htole32(mode << 28 | rates);
+ error = r92c_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd));
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "%s: could not set RA mask for %d station\n",
+ __func__, macid);
+ return (error);
+ }
+
+ return (0);
+}
+#endif
+
+static void
+r92c_init_ra(struct rtwn_softc *sc, int macid)
+{
+ struct ieee80211_htrateset *rs_ht;
+ struct ieee80211_node *ni;
+ uint32_t rates;
+ int maxrate;
+
+ RTWN_NT_LOCK(sc);
+ if (sc->node_list[macid] == NULL) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_RA, "%s: macid %d, ni is NULL\n",
+ __func__, macid);
+ RTWN_NT_UNLOCK(sc);
+ return;
+ }
+
+ ni = ieee80211_ref_node(sc->node_list[macid]);
+ if (ni->ni_flags & IEEE80211_NODE_HT)
+ rs_ht = &ni->ni_htrates;
+ else
+ rs_ht = NULL;
+ /* XXX MACID_BC */
+ rtwn_get_rates(sc, &ni->ni_rates, rs_ht, &rates, &maxrate, 0);
+ RTWN_NT_UNLOCK(sc);
+
+#ifndef RTWN_WITHOUT_UCODE
+ if (sc->sc_ratectl == RTWN_RATECTL_FW) {
+ r92c_send_ra_cmd(sc, macid, rates, maxrate);
+ }
+#endif
+
+ rtwn_write_1(sc, R92C_INIDATA_RATE_SEL(macid), maxrate);
+
+ ieee80211_free_node(ni);
+}
+
+void
+r92c_joinbss_rpt(struct rtwn_softc *sc, int macid)
+{
+#ifndef RTWN_WITHOUT_UCODE
+ struct r92c_softc *rs = sc->sc_priv;
+ struct ieee80211vap *vap;
+ struct r92c_fw_cmd_joinbss_rpt cmd;
+
+ if (sc->vaps[0] == NULL) /* XXX fix */
+ goto end;
+
+ vap = &sc->vaps[0]->vap;
+ if ((vap->iv_state == IEEE80211_S_RUN) ^
+ !(rs->rs_flags & R92C_FLAG_ASSOCIATED))
+ goto end;
+
+ if (rs->rs_flags & R92C_FLAG_ASSOCIATED) {
+ cmd.mstatus = R92C_MSTATUS_DISASSOC;
+ rs->rs_flags &= ~R92C_FLAG_ASSOCIATED;
+ } else {
+ cmd.mstatus = R92C_MSTATUS_ASSOC;
+ rs->rs_flags |= R92C_FLAG_ASSOCIATED;
+ }
+
+ if (r92c_fw_cmd(sc, R92C_CMD_JOINBSS_RPT, &cmd, sizeof(cmd)) != 0) {
+ device_printf(sc->sc_dev, "%s: cannot change media status!\n",
+ __func__);
+ }
+
+end:
+#endif
+
+ /* TODO: init rates for RTWN_MACID_BC. */
+ if (macid & RTWN_MACID_VALID)
+ r92c_init_ra(sc, macid & ~RTWN_MACID_VALID);
+}
+
+#ifndef RTWN_WITHOUT_UCODE
+int
+r92c_set_rsvd_page(struct rtwn_softc *sc, int probe_resp, int null,
+ int qos_null)
+{
+ struct r92c_fw_cmd_rsvdpage rsvd;
+
+ rsvd.probe_resp = probe_resp;
+ rsvd.ps_poll = 0;
+ rsvd.null_data = null;
+
+ return (r92c_fw_cmd(sc, R92C_CMD_RSVD_PAGE, &rsvd, sizeof(rsvd)));
+}
+
+int
+r92c_set_pwrmode(struct rtwn_softc *sc, struct ieee80211vap *vap,
+ int off)
+{
+ struct r92c_fw_cmd_pwrmode mode;
+ int error;
+
+ /* XXX dm_RF_saving */
+
+ if (off && vap->iv_state == IEEE80211_S_RUN &&
+ (vap->iv_flags & IEEE80211_F_PMGTON))
+ mode.mode = R92C_PWRMODE_MIN;
+ else
+ mode.mode = R92C_PWRMODE_CAM;
+ mode.smart_ps = R92C_PWRMODE_SMARTPS_NULLDATA;
+ mode.bcn_pass = 1; /* XXX */
+ error = r92c_fw_cmd(sc, R92C_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);
+}
+
+void
+r92c_set_rssi(struct rtwn_softc *sc)
+{
+ struct ieee80211_node *ni;
+ struct rtwn_node *rn;
+ struct r92c_fw_cmd_rssi cmd;
+ int i;
+
+ cmd.reserved = 0;
+
+ RTWN_NT_LOCK(sc);
+ for (i = 0; i < sc->macid_limit; i++) {
+ /* XXX optimize? */
+ ni = sc->node_list[i];
+ if (ni == NULL)
+ continue;
+
+ rn = RTWN_NODE(ni);
+ cmd.macid = i;
+ cmd.pwdb = rn->avg_pwdb;
+ RTWN_DPRINTF(sc, RTWN_DEBUG_RSSI,
+ "%s: sending RSSI command (macid %d, rssi %d)\n",
+ __func__, i, rn->avg_pwdb);
+
+ RTWN_NT_UNLOCK(sc);
+ r92c_fw_cmd(sc, R92C_CMD_RSSI_SETTING, &cmd, sizeof(cmd));
+ RTWN_NT_LOCK(sc);
+ }
+ RTWN_NT_UNLOCK(sc);
+}
+
+static void
+r92c_ratectl_tx_complete(struct rtwn_softc *sc, uint8_t *buf, int len)
+{
+#if __FreeBSD_version >= 1200012
+ struct ieee80211_ratectl_tx_status txs;
+#endif
+ struct r92c_c2h_tx_rpt *rpt;
+ struct ieee80211_node *ni;
+ uint8_t macid;
+ int ntries;
+
+ if (sc->sc_ratectl != RTWN_RATECTL_NET80211) {
+ /* shouldn't happen */
+ device_printf(sc->sc_dev, "%s called while ratectl = %d!\n",
+ __func__, sc->sc_ratectl);
+ return;
+ }
+
+ rpt = (struct r92c_c2h_tx_rpt *)buf;
+ if (len != sizeof(*rpt)) {
+ device_printf(sc->sc_dev,
+ "%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, queue time: "
+ "low %02X, high %02X, 4: %02X, 5: %02X, 6: %02X, 7: %02X\n",
+ __func__, rpt->rptb0, rpt->rptb1, rpt->queue_time_low,
+ rpt->queue_time_high, rpt->rptb4, rpt->rptb5, rpt->rptb6,
+ rpt->rptb7);
+
+ macid = MS(rpt->rptb5, R92C_RPTB5_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->rptb0, R92C_RPTB0_RETRY_CNT);
+
+ RTWN_NT_LOCK(sc);
+ 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->rptb7 & R92C_RPTB7_PKT_OK) ? "" : " not",
+ ntries);
+
+#if __FreeBSD_version >= 1200012
+ txs.flags = IEEE80211_RATECTL_STATUS_LONG_RETRY;
+ txs.long_retries = ntries;
+ if (rpt->rptb7 & R92C_RPTB7_PKT_OK)
+ txs.status = IEEE80211_RATECTL_TX_SUCCESS;
+ else if (rpt->rptb6 & R92C_RPTB6_RETRY_OVER)
+ txs.status = IEEE80211_RATECTL_TX_FAIL_LONG; /* XXX */
+ else if (rpt->rptb6 & R92C_RPTB6_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->rptb7 & R92C_RPTB7_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);
+ }
+ RTWN_NT_UNLOCK(sc);
+
+#ifdef IEEE80211_SUPPORT_SUPERG
+ if (sc->sc_tx_n_active > 0 && --sc->sc_tx_n_active <= 1)
+ rtwn_cmd_sleepable(sc, NULL, 0, rtwn_ff_flush_all);
+#endif
+}
+
+static void
+r92c_handle_c2h_task(struct rtwn_softc *sc, union sec_param *data)
+{
+ const uint16_t off = R92C_C2H_EVT_MSG + sizeof(struct r92c_c2h_evt);
+ struct r92c_softc *rs = sc->sc_priv;
+ uint16_t buf[R92C_C2H_MSG_MAX_LEN / 2 + 1];
+ uint8_t id, len, status;
+ int i;
+
+ /* Do not reschedule the task if device is not running. */
+ if (!(sc->sc_flags & RTWN_RUNNING))
+ return;
+
+ /* Read current status. */
+ status = rtwn_read_1(sc, R92C_C2H_EVT_CLEAR);
+ if (status == R92C_C2H_EVT_HOST_CLOSE)
+ goto end; /* nothing to do */
+ else if (status == R92C_C2H_EVT_FW_CLOSE) {
+ len = rtwn_read_1(sc, R92C_C2H_EVT_MSG);
+ id = MS(len, R92C_C2H_EVTB0_ID);
+ len = MS(len, R92C_C2H_EVTB0_LEN);
+
+ memset(buf, 0, sizeof(buf));
+ /* Try to optimize event reads. */
+ for (i = 0; i < len; i += 2)
+ buf[i / 2] = rtwn_read_2(sc, off + i);
+ KASSERT(i < sizeof(buf), ("%s: buffer overrun (%d >= %zu)!",
+ __func__, i, sizeof(buf)));
+
+ switch (id) {
+ case R92C_C2H_EVT_TX_REPORT:
+ r92c_ratectl_tx_complete(sc, (uint8_t *)buf, len);
+ break;
+ default:
+ device_printf(sc->sc_dev,
+ "%s: C2H report %u (len %u) was not handled\n",
+ __func__, id, len);
+ break;
+ }
+ }
+
+ /* Prepare for next event. */
+ rtwn_write_1(sc, R92C_C2H_EVT_CLEAR, R92C_C2H_EVT_HOST_CLOSE);
+
+end:
+ /* Adjust timeout for next call. */
+ if (rs->rs_c2h_pending != 0) {
+ rs->rs_c2h_pending = 0;
+ rs->rs_c2h_paused = 0;
+ } else
+ rs->rs_c2h_paused++;
+
+ if (rs->rs_c2h_paused > R92C_TX_PAUSED_THRESHOLD)
+ rs->rs_c2h_timeout = hz;
+ else
+ rs->rs_c2h_timeout = MAX(hz / 100, 1);
+
+ /* Reschedule the task. */
+ callout_reset(&rs->rs_c2h_report, rs->rs_c2h_timeout,
+ r92c_handle_c2h_report, sc);
+}
+
+void
+r92c_handle_c2h_report(void *arg)
+{
+ struct rtwn_softc *sc = arg;
+
+ rtwn_cmd_sleepable(sc, NULL, 0, r92c_handle_c2h_task);
+}
+
+#endif /* RTWN_WITHOUT_UCODE */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw_cmd.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw_cmd.h
new file mode 100644
index 00000000..998a7805
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw_cmd.h
@@ -0,0 +1,148 @@
+/*-
+ * 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 R92C_FW_CMD_H
+#define R92C_FW_CMD_H
+
+/*
+ * Host to firmware commands.
+ */
+struct r92c_fw_cmd {
+ uint8_t id;
+#define R92C_CMD_SET_PWRMODE 1
+#define R92C_CMD_JOINBSS_RPT 2
+#define R92C_CMD_RSVD_PAGE 3
+#define R92C_CMD_RSSI_SETTING 5
+#define R92C_CMD_MACID_CONFIG 6
+
+#define R92C_CMD_FLAG_EXT 0x80
+
+ uint8_t msg[5];
+} __packed __attribute__((aligned(4)));
+
+/* Structure for R92C_CMD_JOINBSS_RPT. */
+struct r92c_fw_cmd_joinbss_rpt {
+ uint8_t mstatus;
+#define R92C_MSTATUS_DISASSOC 0x00
+#define R92C_MSTATUS_ASSOC 0x01
+} __packed;
+
+/* Structure for R92C_CMD_SET_PWRMODE. */
+struct r92c_fw_cmd_pwrmode {
+ uint8_t mode;
+#define R92C_PWRMODE_CAM 0
+#define R92C_PWRMODE_MIN 1
+#define R92C_PWRMODE_MAX 2
+#define R92C_PWRMODE_DTIM 3
+#define R92C_PWRMODE_UAPSD_WMM 5
+#define R92C_PWRMODE_UAPSD 6
+#define R92C_PWRMODE_IBSS 7
+
+ uint8_t smart_ps;
+/* XXX undocumented */
+#define R92C_PWRMODE_SMARTPS_NULLDATA 2
+
+ uint8_t bcn_pass; /* unit: beacon interval */
+} __packed;
+
+/* Structure for R92C_CMD_RSVD_PAGE. */
+struct r92c_fw_cmd_rsvdpage {
+ uint8_t probe_resp;
+ uint8_t ps_poll;
+ uint8_t null_data;
+} __packed;
+
+/* Structure for R92C_CMD_RSSI_SETTING. */
+struct r92c_fw_cmd_rssi {
+ uint8_t macid;
+ uint8_t reserved;
+ uint8_t pwdb;
+} __packed;
+
+/* Structure for R92C_CMD_MACID_CONFIG. */
+struct r92c_fw_cmd_macid_cfg {
+ uint32_t mask;
+ uint8_t macid;
+#define R92C_CMD_MACID_VALID 0x80
+} __packed;
+
+/*
+ * C2H event structure.
+ */
+/* Bigger value is used to prevent buffer overrun. */
+#define R92C_C2H_MSG_MAX_LEN 16
+
+struct r92c_c2h_evt {
+ uint8_t evtb0;
+#define R92C_C2H_EVTB0_ID_M 0x0f
+#define R92C_C2H_EVTB0_ID_S 0
+#define R92C_C2H_EVTB0_LEN_M 0xf0
+#define R92C_C2H_EVTB0_LEN_S 4
+
+ uint8_t seq;
+
+ /* Followed by payload (see below). */
+} __packed;
+
+/*
+ * C2H event types.
+ */
+#define R92C_C2H_EVT_DEBUG 0
+#define R92C_C2H_EVT_TX_REPORT 3
+#define R92C_C2H_EVT_EXT_RA_RPT 6
+
+/* Structure for R92C_C2H_EVT_TX_REPORT event. */
+struct r92c_c2h_tx_rpt {
+ uint8_t rptb0;
+#define R92C_RPTB0_RETRY_CNT_M 0x3f
+#define R92C_RPTB0_RETRY_CNT_S 0
+
+ uint8_t rptb1; /* XXX junk */
+#define R92C_RPTB1_RTS_RETRY_CNT_M 0x3f
+#define R92C_RPTB1_RTS_RETRY_CNT_S 0
+
+ uint8_t queue_time_low;
+ uint8_t queue_time_high;
+ uint8_t rptb4;
+#define R92C_RPTB4_MISSED_PKT_NUM_M 0x1f
+#define R92C_RPTB4_MISSED_PKT_NUM_S 0
+
+ uint8_t rptb5;
+#define R92C_RPTB5_MACID_M 0x1f
+#define R92C_RPTB5_MACID_S 0
+#define R92C_RPTB5_DES1_FRAGSSN_M 0xe0
+#define R92C_RPTB5_DES1_FRAGSSN_S 5
+
+ uint8_t rptb6;
+#define R92C_RPTB6_RPT_PKT_NUM_M 0x1f
+#define R92C_RPTB6_RPT_PKT_NUM_S 0
+#define R92C_RPTB6_PKT_DROP 0x20
+#define R92C_RPTB6_LIFE_EXPIRE 0x40
+#define R92C_RPTB6_RETRY_OVER 0x80
+
+ uint8_t rptb7;
+#define R92C_RPTB7_EDCA_M 0x0f
+#define R92C_RPTB7_EDCA_S 0
+#define R92C_RPTB7_BMC 0x20
+#define R92C_RPTB7_PKT_OK 0x40
+#define R92C_RPTB7_INT_CCX 0x80
+} __packed;
+
+#endif /* R92C_FW_CMD_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_init.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_init.c
new file mode 100644
index 00000000..d8db0286
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_init.c
@@ -0,0 +1,319 @@
+#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_priv.h>
+#include <dev/rtwn/rtl8192c/r92c_reg.h>
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+
+
+int
+r92c_check_condition(struct rtwn_softc *sc, const uint8_t cond[])
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ uint8_t mask;
+ int i;
+
+ if (cond[0] == 0)
+ return (1);
+
+ RTWN_DPRINTF(sc, RTWN_DEBUG_RESET,
+ "%s: condition byte 0: %02X; chip %02X, board %02X\n",
+ __func__, cond[0], rs->chip, rs->board_type);
+
+ if (!(rs->chip & R92C_CHIP_92C)) {
+ if (rs->board_type == R92C_BOARD_TYPE_HIGHPA)
+ mask = R92C_COND_RTL8188RU;
+ else if (rs->board_type == R92C_BOARD_TYPE_MINICARD)
+ mask = R92C_COND_RTL8188CE;
+ else
+ mask = R92C_COND_RTL8188CU;
+ } else {
+ if (rs->board_type == R92C_BOARD_TYPE_MINICARD)
+ mask = R92C_COND_RTL8192CE;
+ else
+ mask = R92C_COND_RTL8192CU;
+ }
+
+ for (i = 0; i < RTWN_MAX_CONDITIONS && cond[i] != 0; i++)
+ if ((cond[i] & mask) == mask)
+ return (1);
+
+ return (0);
+}
+
+int
+r92c_set_page_size(struct rtwn_softc *sc)
+{
+ return (rtwn_write_1(sc, R92C_PBP, SM(R92C_PBP_PSRX, R92C_PBP_128) |
+ SM(R92C_PBP_PSTX, R92C_PBP_128)) == 0);
+}
+
+void
+r92c_init_bb_common(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ int i, j;
+
+ /* Write BB initialization values. */
+ for (i = 0; i < sc->bb_size; i++) {
+ const struct rtwn_bb_prog *bb_prog = &sc->bb_prog[i];
+
+ while (!rtwn_check_condition(sc, bb_prog->cond)) {
+ KASSERT(bb_prog->next != NULL,
+ ("%s: wrong condition value (i %d)\n",
+ __func__, i));
+ bb_prog = bb_prog->next;
+ }
+
+ for (j = 0; j < bb_prog->count; j++) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_RESET,
+ "BB: reg 0x%03x, val 0x%08x\n",
+ bb_prog->reg[j], bb_prog->val[j]);
+
+ rtwn_bb_write(sc, bb_prog->reg[j], bb_prog->val[j]);
+ rtwn_delay(sc, 1);
+ }
+ }
+
+ if (rs->chip & R92C_CHIP_92C_1T2R) {
+ /* 8192C 1T only configuration. */
+ rtwn_bb_setbits(sc, R92C_FPGA0_TXINFO, 0x03, 0x02);
+ rtwn_bb_setbits(sc, R92C_FPGA1_TXINFO, 0x300033, 0x200022);
+ rtwn_bb_setbits(sc, R92C_CCK0_AFESETTING, 0xff000000,
+ 0x45000000);
+ rtwn_bb_setbits(sc, R92C_OFDM0_TRXPATHENA, 0xff, 0x23);
+ rtwn_bb_setbits(sc, R92C_OFDM0_AGCPARAM1, 0x30, 0x10);
+
+ rtwn_bb_setbits(sc, 0xe74, 0x0c000000, 0x08000000);
+ rtwn_bb_setbits(sc, 0xe78, 0x0c000000, 0x08000000);
+ rtwn_bb_setbits(sc, 0xe7c, 0x0c000000, 0x08000000);
+ rtwn_bb_setbits(sc, 0xe80, 0x0c000000, 0x08000000);
+ rtwn_bb_setbits(sc, 0xe88, 0x0c000000, 0x08000000);
+ }
+
+ /* Write AGC values. */
+ for (i = 0; i < sc->agc_size; i++) {
+ const struct rtwn_agc_prog *agc_prog = &sc->agc_prog[i];
+
+ while (!rtwn_check_condition(sc, agc_prog->cond)) {
+ KASSERT(agc_prog->next != NULL,
+ ("%s: wrong condition value (2) (i %d)\n",
+ __func__, i));
+ agc_prog = agc_prog->next;
+ }
+
+ for (j = 0; j < agc_prog->count; j++) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_RESET,
+ "AGC: val 0x%08x\n", agc_prog->val[j]);
+
+ rtwn_bb_write(sc, R92C_OFDM0_AGCRSSITABLE,
+ agc_prog->val[j]);
+ rtwn_delay(sc, 1);
+ }
+ }
+
+ if (rtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) & R92C_HSSI_PARAM2_CCK_HIPWR)
+ sc->sc_flags |= RTWN_FLAG_CCK_HIPWR;
+}
+
+int
+r92c_init_rf_chain(struct rtwn_softc *sc,
+ const struct rtwn_rf_prog *rf_prog, int chain)
+{
+ int i, j;
+
+ RTWN_DPRINTF(sc, RTWN_DEBUG_RESET, "%s: chain %d\n",
+ __func__, chain);
+
+ for (i = 0; rf_prog[i].reg != NULL; i++) {
+ const struct rtwn_rf_prog *prog = &rf_prog[i];
+
+ while (!rtwn_check_condition(sc, prog->cond)) {
+ KASSERT(prog->next != NULL,
+ ("%s: wrong condition value (i %d)\n",
+ __func__, i));
+ prog = prog->next;
+ }
+
+ for (j = 0; j < prog->count; j++) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_RESET,
+ "RF: reg 0x%02x, val 0x%05x\n",
+ prog->reg[j], prog->val[j]);
+
+ /*
+ * These are fake RF registers offsets that
+ * indicate a delay is required.
+ */
+ /* NB: we are using 'value' to store required delay. */
+ if (prog->reg[j] > 0xf8) {
+ rtwn_delay(sc, prog->val[j]);
+ continue;
+ }
+
+ rtwn_rf_write(sc, chain, prog->reg[j], prog->val[j]);
+ rtwn_delay(sc, 1);
+ }
+ }
+
+ return (i);
+}
+
+void
+r92c_init_rf(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ uint32_t reg, type;
+ int i, chain, idx, off;
+
+ for (chain = 0, i = 0; chain < sc->nrxchains; chain++, i++) {
+ /* Save RF_ENV control type. */
+ idx = chain / 2;
+ off = (chain % 2) * 16;
+ reg = rtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx));
+ type = (reg >> off) & 0x10;
+
+ /* Set RF_ENV enable. */
+ rtwn_bb_setbits(sc, R92C_FPGA0_RFIFACEOE(chain),
+ 0, 0x100000);
+ rtwn_delay(sc, 1);
+ /* Set RF_ENV output high. */
+ rtwn_bb_setbits(sc, R92C_FPGA0_RFIFACEOE(chain),
+ 0, 0x10);
+ rtwn_delay(sc, 1);
+ /* Set address and data lengths of RF registers. */
+ rtwn_bb_setbits(sc, R92C_HSSI_PARAM2(chain),
+ R92C_HSSI_PARAM2_ADDR_LENGTH, 0);
+ rtwn_delay(sc, 1);
+ rtwn_bb_setbits(sc, R92C_HSSI_PARAM2(chain),
+ R92C_HSSI_PARAM2_DATA_LENGTH, 0);
+ rtwn_delay(sc, 1);
+
+ /* Write RF initialization values for this chain. */
+ i += r92c_init_rf_chain(sc, &sc->rf_prog[i], chain);
+
+ /* Restore RF_ENV control type. */
+ rtwn_bb_setbits(sc, R92C_FPGA0_RFIFACESW(idx),
+ 0x10 << off, type << off);
+
+ /* Cache RF register CHNLBW. */
+ rs->rf_chnlbw[chain] = rtwn_rf_read(sc, chain,
+ R92C_RF_CHNLBW);
+ }
+
+ if ((rs->chip & (R92C_CHIP_UMC_A_CUT | R92C_CHIP_92C)) ==
+ R92C_CHIP_UMC_A_CUT) {
+ rtwn_rf_write(sc, 0, R92C_RF_RX_G1, 0x30255);
+ rtwn_rf_write(sc, 0, R92C_RF_RX_G2, 0x50a00);
+ }
+
+ /* Turn CCK and OFDM blocks on. */
+ rtwn_bb_setbits(sc, R92C_FPGA0_RFMOD, 0, R92C_RFMOD_CCK_EN);
+ rtwn_bb_setbits(sc, R92C_FPGA0_RFMOD, 0, R92C_RFMOD_OFDM_EN);
+}
+
+void
+r92c_init_edca(struct rtwn_softc *sc)
+{
+ /* SIFS */
+ rtwn_write_2(sc, R92C_SPEC_SIFS, 0x100a);
+ rtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x100a);
+ rtwn_write_2(sc, R92C_SIFS_CCK, 0x100a);
+ rtwn_write_2(sc, R92C_SIFS_OFDM, 0x100a);
+ /* TXOP */
+ rtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b);
+ rtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f);
+ rtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005ea324);
+ rtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002fa226);
+}
+
+void
+r92c_init_ampdu(struct rtwn_softc *sc)
+{
+
+ /* Setup AMPDU aggregation. */
+ rtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */
+ rtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
+ rtwn_write_2(sc, R92C_MAX_AGGR_NUM, 0x0708);
+}
+
+void
+r92c_init_antsel(struct rtwn_softc *sc)
+{
+ uint32_t reg;
+
+ if (sc->ntxchains != 1 || sc->nrxchains != 1)
+ return;
+
+ rtwn_setbits_1(sc, R92C_LEDCFG2, 0, 0x80);
+ rtwn_bb_setbits(sc, R92C_FPGA0_RFPARAM(0), 0, 0x2000);
+ reg = rtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(0));
+ sc->sc_ant = MS(reg, R92C_FPGA0_RFIFACEOE0_ANT); /* XXX */
+}
+
+void
+r92c_pa_bias_init(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ int i;
+
+ for (i = 0; i < sc->nrxchains; i++) {
+ if (rs->pa_setting & (1 << i))
+ continue;
+ r92c_rf_write(sc, i, R92C_RF_IPA, 0x0f406);
+ r92c_rf_write(sc, i, R92C_RF_IPA, 0x4f406);
+ r92c_rf_write(sc, i, R92C_RF_IPA, 0x8f406);
+ r92c_rf_write(sc, i, R92C_RF_IPA, 0xcf406);
+ }
+ if (!(rs->pa_setting & 0x10))
+ rtwn_setbits_1(sc, 0x16, 0xf0, 0x90);
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_priv.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_priv.h
new file mode 100644
index 00000000..13c38fb2
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_priv.h
@@ -0,0 +1,408 @@
+/*-
+ * 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 R92C_PRIV_H
+#define R92C_PRIV_H
+
+#include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
+
+/*
+ * Parsed Tx power (diff) values.
+ */
+struct rtwn_r92c_txpwr {
+ uint8_t cck_tx_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
+ uint8_t ht40_1s_tx_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
+ int8_t ht40_2s_tx_pwr_diff[R92C_MAX_CHAINS][R92C_GROUP_2G];
+ int8_t ht20_tx_pwr_diff[R92C_MAX_CHAINS][R92C_GROUP_2G];
+ int8_t ofdm_tx_pwr_diff[R92C_MAX_CHAINS][R92C_GROUP_2G];
+ int8_t ht40_max_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
+ int8_t ht20_max_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
+};
+
+
+/*
+ * Baseband initialization values (shared parts).
+ */
+#define R92C_COND_RTL8188CE 0x01
+#define R92C_COND_RTL8188CU 0x02
+#define R92C_COND_RTL8188RU 0x04
+#define R92C_COND_RTL8192CE 0x08
+#define R92C_COND_RTL8192CU 0x10
+
+/* Shortcut. */
+#define R92C_COND_RTL8192C (R92C_COND_RTL8192CE | R92C_COND_RTL8192CU)
+
+static const uint16_t rtl8192c_bb_regs3[] = {
+ 0xd04
+}, rtl8192c_bb_regs4[] = {
+ 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
+}, rtl8192c_bb_regs5[] = {
+ 0xe60, 0xe68, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,
+ 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec, 0xf14,
+ 0xf4c, 0xf00
+};
+
+static const uint32_t rtl8192c_bb_vals3_88cu_88ru[] = {
+ 0x00020401
+}, rtl8192c_bb_vals3_92ce_92cu[] = {
+ 0x00020403
+}, rtl8192c_bb_vals4[] = {
+ 0x0000907f, 0x20010201, 0xa0633333, 0x3333bc43, 0x7a8f5b6b,
+ 0xcc979975, 0x00000000, 0x80608000, 0x00000000, 0x00027293,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x6437140a,
+ 0x00000000, 0x00000000, 0x30032064, 0x4653de68, 0x04518a3c,
+ 0x00002101, 0x2a201c16, 0x1812362e, 0x322c2220, 0x000e3c24,
+ 0x2a2a2a2a, 0x2a2a2a2a, 0x03902a2a, 0x2a2a2a2a, 0x2a2a2a2a,
+ 0x2a2a2a2a, 0x2a2a2a2a, 0x00000000, 0x1000dc1f, 0x10008c1f,
+ 0x02140102, 0x681604c2, 0x01007c00, 0x01004800, 0xfb000000,
+ 0x000028d1, 0x1000dc1f, 0x10008c1f, 0x02140102, 0x28160d05
+},rtl8192c_bb_vals5_92ce_92cu[] = {
+ 0x00000010, 0x001b25a4, 0x63db25a4, 0x63db25a4, 0x0c1b25a4,
+ 0x0c1b25a4, 0x0c1b25a4, 0x0c1b25a4, 0x63db25a4, 0x0c1b25a4,
+ 0x63db25a4, 0x63db25a4, 0x63db25a4, 0x63db25a4, 0x001b25a4,
+ 0x001b25a4, 0x6fdb25a4, 0x00000003, 0x00000000, 0x00000300
+};
+
+/*
+ * RTL8192CU and RTL8192CE-VAU.
+ */
+
+static const uint32_t rtl8192ce_agc_vals[] = {
+ 0x7b000001, 0x7b010001, 0x7b020001, 0x7b030001, 0x7b040001,
+ 0x7b050001, 0x7a060001, 0x79070001, 0x78080001, 0x77090001,
+ 0x760a0001, 0x750b0001, 0x740c0001, 0x730d0001, 0x720e0001,
+ 0x710f0001, 0x70100001, 0x6f110001, 0x6e120001, 0x6d130001,
+ 0x6c140001, 0x6b150001, 0x6a160001, 0x69170001, 0x68180001,
+ 0x67190001, 0x661a0001, 0x651b0001, 0x641c0001, 0x631d0001,
+ 0x621e0001, 0x611f0001, 0x60200001, 0x49210001, 0x48220001,
+ 0x47230001, 0x46240001, 0x45250001, 0x44260001, 0x43270001,
+ 0x42280001, 0x41290001, 0x402a0001, 0x262b0001, 0x252c0001,
+ 0x242d0001, 0x232e0001, 0x222f0001, 0x21300001, 0x20310001,
+ 0x06320001, 0x05330001, 0x04340001, 0x03350001, 0x02360001,
+ 0x01370001, 0x00380001, 0x00390001, 0x003a0001, 0x003b0001,
+ 0x003c0001, 0x003d0001, 0x003e0001, 0x003f0001, 0x7b400001,
+ 0x7b410001, 0x7b420001, 0x7b430001, 0x7b440001, 0x7b450001,
+ 0x7a460001, 0x79470001, 0x78480001, 0x77490001, 0x764a0001,
+ 0x754b0001, 0x744c0001, 0x734d0001, 0x724e0001, 0x714f0001,
+ 0x70500001, 0x6f510001, 0x6e520001, 0x6d530001, 0x6c540001,
+ 0x6b550001, 0x6a560001, 0x69570001, 0x68580001, 0x67590001,
+ 0x665a0001, 0x655b0001, 0x645c0001, 0x635d0001, 0x625e0001,
+ 0x615f0001, 0x60600001, 0x49610001, 0x48620001, 0x47630001,
+ 0x46640001, 0x45650001, 0x44660001, 0x43670001, 0x42680001,
+ 0x41690001, 0x406a0001, 0x266b0001, 0x256c0001, 0x246d0001,
+ 0x236e0001, 0x226f0001, 0x21700001, 0x20710001, 0x06720001,
+ 0x05730001, 0x04740001, 0x03750001, 0x02760001, 0x01770001,
+ 0x00780001, 0x00790001, 0x007a0001, 0x007b0001, 0x007c0001,
+ 0x007d0001, 0x007e0001, 0x007f0001, 0x3800001e, 0x3801001e,
+ 0x3802001e, 0x3803001e, 0x3804001e, 0x3805001e, 0x3806001e,
+ 0x3807001e, 0x3808001e, 0x3c09001e, 0x3e0a001e, 0x400b001e,
+ 0x440c001e, 0x480d001e, 0x4c0e001e, 0x500f001e, 0x5210001e,
+ 0x5611001e, 0x5a12001e, 0x5e13001e, 0x6014001e, 0x6015001e,
+ 0x6016001e, 0x6217001e, 0x6218001e, 0x6219001e, 0x621a001e,
+ 0x621b001e, 0x621c001e, 0x621d001e, 0x621e001e, 0x621f001e
+};
+
+static const struct rtwn_agc_prog rtl8192ce_agc[] = {
+ {
+ nitems(rtl8192ce_agc_vals),
+ rtl8192ce_agc_vals,
+ { 0 },
+ NULL
+ }
+};
+
+
+/*
+ * RF initialization values.
+ */
+static const uint8_t rtl8192c_rf0_regs0[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+ 0x0f, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21
+}, rtl8192c_rf0_regs1[] = {
+ 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28
+}, rtl8192c_rf0_regs2[] = {
+ 0x29, 0x2a, 0x2b, 0x2a, 0x2b, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b,
+ 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a,
+ 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c,
+ 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b,
+ 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b,
+ 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x10, 0x11, 0x10, 0x11,
+ 0x10, 0x11, 0x10, 0x11, 0x10, 0x11, 0x10, 0x11, 0x10, 0x11
+}, rtl8192c_rf0_regs3[] = {
+ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13
+}, rtl8192c_rf0_regs4[] = {
+ 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15
+}, rtl8192c_rf0_regs5[] = {
+ 0x16, 0x16, 0x16, 0x16, 0x00, 0x18, 0xfe, 0xfe, 0x1f, 0xfe, 0xfe,
+ 0x1e, 0x1f, 0x00
+};
+
+static const uint32_t rtl8192c_rf0_vals0_88ce_88cu_92ce[] = {
+ 0x30159, 0x31284, 0x98000, 0x18c63, 0x210e7, 0x2044f, 0x1adb1,
+ 0x54867, 0x8992e, 0x0e52c, 0x39ce7, 0x00451, 0x00000, 0x10255,
+ 0x60a00, 0xfc378, 0xa1250, 0x4445f, 0x80001, 0x0b614, 0x6c000
+}, rtl8192c_rf0_vals0_88ru[] = {
+ 0x30159, 0x31284, 0x98000, 0x18c63, 0x210e7, 0x2044f, 0x1adb0,
+ 0x54867, 0x8992e, 0x0e529, 0x39ce7, 0x00451, 0x00000, 0x00255,
+ 0x60a00, 0xfc378, 0xa1250, 0x4445f, 0x80001, 0x0b614, 0x6c000
+}, rtl8192c_rf0_vals1_88ru[] = {
+ 0x0083c, 0x01558, 0x00060, 0x00483, 0x4f000, 0xec7d9, 0x977c0
+}, rtl8192c_rf0_vals1_88ce[] = {
+ 0x00000, 0x01558, 0x00060, 0x00483, 0x4f200, 0xec7d9, 0x577c0
+}, rtl8192c_rf0_vals1_88cu_92ce[] = {
+ 0x00000, 0x01558, 0x00060, 0x00483, 0x4f000, 0xec7d9, 0x577c0
+}, rtl8192c_rf0_vals2[] = {
+ 0x04783, 0x00001, 0x21334, 0x00000, 0x00054, 0x00001, 0x00808,
+ 0x53333, 0x0000c, 0x00002, 0x00808, 0x5b333, 0x0000d, 0x00003,
+ 0x00808, 0x63333, 0x0000d, 0x00004, 0x00808, 0x6b333, 0x0000d,
+ 0x00005, 0x00808, 0x73333, 0x0000d, 0x00006, 0x00709, 0x5b333,
+ 0x0000d, 0x00007, 0x00709, 0x63333, 0x0000d, 0x00008, 0x0060a,
+ 0x4b333, 0x0000d, 0x00009, 0x0060a, 0x53333, 0x0000d, 0x0000a,
+ 0x0060a, 0x5b333, 0x0000d, 0x0000b, 0x0060a, 0x63333, 0x0000d,
+ 0x0000c, 0x0060a, 0x6b333, 0x0000d, 0x0000d, 0x0060a, 0x73333,
+ 0x0000d, 0x0000e, 0x0050b, 0x66666, 0x0001a, 0xe0000, 0x4000f,
+ 0xe31fc, 0x6000f, 0xff9f8, 0x2000f, 0x203f9, 0x3000f, 0xff500,
+ 0x00000, 0x00000, 0x8000f, 0x3f100, 0x9000f, 0x23100
+}, rtl8192c_rf0_vals3_88ru[] = {
+ 0xd8000, 0x90000, 0x51000, 0x12000, 0x28fb4, 0x24fa8, 0x207a4,
+ 0x1c798, 0x183a4, 0x14398, 0x101a4, 0x0c198, 0x080a4, 0x04098,
+ 0x00014
+}, rtl8192c_rf0_vals3_92ce[] = {
+ 0x32000, 0x71000, 0xb0000, 0xfc000, 0x287af, 0x244b7, 0x204ab,
+ 0x1c49f, 0x18493, 0x14297, 0x10295, 0x0c298, 0x0819c, 0x040a8,
+ 0x0001c
+}, rtl8192c_rf0_vals3_88cu_88ce[] = {
+ 0x32000, 0x71000, 0xb0000, 0xfc000, 0x287b3, 0x244b7, 0x204ab,
+ 0x1c49f, 0x18493, 0x1429b, 0x10299, 0x0c29c, 0x081a0, 0x040ac,
+ 0x00020
+}, rtl8192c_rf0_vals4_92ce_88ce[] = {
+ 0x1944c, 0x59444, 0x9944c, 0xd9444, 0x0f424, 0x4f424, 0x8f424,
+ 0xcf424
+}, rtl8192c_rf0_vals4_88cu_88ru[] = {
+ 0x1944c, 0x59444, 0x9944c, 0xd9444, 0x0f405, 0x4f405, 0x8f405,
+ 0xcf405
+}, rtl8192c_rf0_vals5[] = {
+ 0xe0330, 0xa0330, 0x60330, 0x20330, 0x10159, 0x0f401, 0x0c350,
+ 0x0c350, 0x80003, 0x0c350, 0x0c350, 0x44457, 0x80000, 0x30159
+};
+
+static const struct rtwn_rf_prog rtl8192c_rf[] = {
+ /* RF chain 0 */
+ /* RTL8188RU. */
+ {
+ nitems(rtl8192c_rf0_regs0),
+ rtl8192c_rf0_regs0,
+ rtl8192c_rf0_vals0_88ru,
+ { R92C_COND_RTL8188RU },
+ /* Others. */
+ &(const struct rtwn_rf_prog){
+ nitems(rtl8192c_rf0_regs0),
+ rtl8192c_rf0_regs0,
+ rtl8192c_rf0_vals0_88ce_88cu_92ce,
+ { 0 },
+ NULL
+ }
+ },
+ /* RTL8188RU. */
+ {
+ nitems(rtl8192c_rf0_regs1),
+ rtl8192c_rf0_regs1,
+ rtl8192c_rf0_vals1_88ru,
+ { R92C_COND_RTL8188RU },
+ /* RTL8188CE. */
+ &(const struct rtwn_rf_prog){
+ nitems(rtl8192c_rf0_regs1),
+ rtl8192c_rf0_regs1,
+ rtl8192c_rf0_vals1_88ce,
+ { R92C_COND_RTL8188CE },
+ /* Others. */
+ &(const struct rtwn_rf_prog){
+ nitems(rtl8192c_rf0_regs1),
+ rtl8192c_rf0_regs1,
+ rtl8192c_rf0_vals1_88cu_92ce,
+ { 0 },
+ NULL
+ }
+ }
+ },
+ {
+ nitems(rtl8192c_rf0_regs2),
+ rtl8192c_rf0_regs2,
+ rtl8192c_rf0_vals2,
+ { 0 },
+ NULL
+ },
+ /* RTL8188RU. */
+ {
+ nitems(rtl8192c_rf0_regs3),
+ rtl8192c_rf0_regs3,
+ rtl8192c_rf0_vals3_88ru,
+ { R92C_COND_RTL8188RU },
+ /* RTL8192C. */
+ &(const struct rtwn_rf_prog){
+ nitems(rtl8192c_rf0_regs3),
+ rtl8192c_rf0_regs3,
+ rtl8192c_rf0_vals3_92ce,
+ { R92C_COND_RTL8192C },
+ /* Others. */
+ &(struct rtwn_rf_prog){
+ nitems(rtl8192c_rf0_regs3),
+ rtl8192c_rf0_regs3,
+ rtl8192c_rf0_vals3_88cu_88ce,
+ { 0 },
+ NULL
+ }
+ }
+ },
+ /* RTL8188CE / RTL8192C. */
+ {
+ nitems(rtl8192c_rf0_regs4),
+ rtl8192c_rf0_regs4,
+ rtl8192c_rf0_vals4_92ce_88ce,
+ { R92C_COND_RTL8188CE | R92C_COND_RTL8192C },
+ /* Others. */
+ &(const struct rtwn_rf_prog){
+ nitems(rtl8192c_rf0_regs4),
+ rtl8192c_rf0_regs4,
+ rtl8192c_rf0_vals4_88cu_88ru,
+ { 0 },
+ NULL
+ }
+ },
+ {
+ nitems(rtl8192c_rf0_regs5),
+ rtl8192c_rf0_regs5,
+ rtl8192c_rf0_vals5,
+ { 0 },
+ NULL
+ },
+ { 0, NULL, NULL, { 0 }, NULL },
+ /* RF chain 1 (RTL8192C). */
+ {
+ 12, /* 0x00 - 0x0f */
+ rtl8192c_rf0_regs0,
+ rtl8192c_rf0_vals0_88ce_88cu_92ce,
+ { 0 },
+ NULL
+ },
+ {
+ nitems(rtl8192c_rf0_regs3), /* 0x12 - 0x13 */
+ rtl8192c_rf0_regs3,
+ rtl8192c_rf0_vals3_92ce,
+ { 0 },
+ NULL
+ },
+ {
+ nitems(rtl8192c_rf0_regs4), /* 0x14 - 0x15 */
+ rtl8192c_rf0_regs4,
+ rtl8192c_rf0_vals4_92ce_88ce,
+ { 0 },
+ NULL
+ },
+ {
+ 4, /* 0x16 */
+ rtl8192c_rf0_regs5,
+ rtl8192c_rf0_vals5,
+ { 0 },
+ NULL
+ },
+ { 0, NULL, NULL, { 0 }, NULL }
+};
+
+
+struct rtwn_r92c_txagc {
+ uint8_t pwr[R92C_GROUP_2G][28]; /* RTWN_RIDX_MCS(15) + 1 */
+};
+
+/*
+ * Per RF chain/group/rate Tx gain values.
+ */
+static const struct rtwn_r92c_txagc rtl8192cu_txagc[] = {
+ { { /* Chain 0. */
+ { /* Group 0. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x0c, 0x0c, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02, /* OFDM6~54. */
+ 0x0e, 0x0d, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02, /* MCS0~7. */
+ 0x0e, 0x0d, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02 /* MCS8~15. */
+ },
+ { /* Group 1. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ },
+ { /* Group 2. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ }
+ } },
+ { { /* Chain 1. */
+ { /* Group 0. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ },
+ { /* Group 1. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ },
+ { /* Group 2. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ }
+ } }
+};
+
+static const struct rtwn_r92c_txagc rtl8188ru_txagc[] = {
+ { { /* Chain 0. */
+ { /* Group 0. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x08, 0x08, 0x08, 0x06, 0x06, 0x04, 0x04, 0x00, /* OFDM6~54. */
+ 0x08, 0x06, 0x06, 0x04, 0x04, 0x02, 0x02, 0x00, /* MCS0~7. */
+ 0x08, 0x06, 0x06, 0x04, 0x04, 0x02, 0x02, 0x00 /* MCS8~15. */
+ },
+ { /* Group 1. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ },
+ { /* Group 2. */
+ 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
+ }
+ } }
+};
+
+#endif /* R92C_PRIV_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_reg.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_reg.h
new file mode 100644
index 00000000..ff03d191
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_reg.h
@@ -0,0 +1,855 @@
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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.
+ *
+ * $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
+ * $FreeBSD$
+ */
+
+#ifndef R92C_REG_H
+#define R92C_REG_H
+
+/*
+ * MAC registers.
+ */
+/* System Configuration. */
+#define R92C_SYS_ISO_CTRL 0x000
+#define R92C_SYS_FUNC_EN 0x002
+#define R92C_APS_FSMCO 0x004
+#define R92C_SYS_CLKR 0x008
+#define R92C_AFE_MISC 0x010
+#define R92C_SPS0_CTRL 0x011
+#define R92C_SPS_OCP_CFG 0x018
+#define R92C_RSV_CTRL 0x01c
+#define R92C_RF_CTRL 0x01f
+#define R92C_LDOA15_CTRL 0x020
+#define R92C_LDOV12D_CTRL 0x021
+#define R92C_LDOHCI12_CTRL 0x022
+#define R92C_LPLDO_CTRL 0x023
+#define R92C_AFE_XTAL_CTRL 0x024
+#define R92C_AFE_PLL_CTRL 0x028
+#define R92C_APE_PLL_CTRL_EXT 0x02c
+#define R92C_MAC_PHY_CTRL R92C_APE_PLL_CTRL_EXT
+#define R92C_EFUSE_CTRL 0x030
+#define R92C_EFUSE_TEST 0x034
+#define R92C_PWR_DATA 0x038
+#define R92C_CAL_TIMER 0x03c
+#define R92C_ACLK_MON 0x03e
+#define R92C_GPIO_MUXCFG 0x040
+#define R92C_GPIO_IO_SEL 0x042
+#define R92C_MAC_PINMUX_CFG 0x043
+#define R92C_GPIO_PIN_CTRL 0x044
+#define R92C_GPIO_IN 0x044
+#define R92C_GPIO_OUT 0x045
+#define R92C_GPIO_IOSEL 0x046
+#define R92C_GPIO_MOD 0x047
+#define R92C_GPIO_INTM 0x048
+#define R92C_LEDCFG0 0x04c
+#define R92C_LEDCFG1 0x04d
+#define R92C_LEDCFG2 0x04e
+#define R92C_LEDCFG3 0x04f
+#define R92C_FSIMR 0x050
+#define R92C_FSISR 0x054
+#define R92C_HSIMR 0x058
+#define R92C_HSISR 0x05c
+#define R92C_MULTI_FUNC_CTRL 0x068
+#define R92C_MCUFWDL 0x080
+#define R92C_HMEBOX_EXT(idx) (0x088 + (idx) * 2)
+#define R92C_EFUSE_ACCESS 0x0cf
+#define R92C_BIST_SCAN 0x0d0
+#define R92C_BIST_RPT 0x0d4
+#define R92C_BIST_ROM_RPT 0x0d8
+#define R92C_HPON_FSM 0x0ec
+#define R92C_SYS_CFG 0x0f0
+#define R92C_TYPE_ID 0x0fc
+/* MAC General Configuration. */
+#define R92C_CR 0x100
+#define R92C_MSR 0x102
+#define R92C_PBP 0x104
+#define R92C_TRXDMA_CTRL 0x10c
+#define R92C_TRXFF_BNDY 0x114
+#define R92C_TRXFF_STATUS 0x118
+#define R92C_RXFF_PTR 0x11c
+#define R92C_HIMR 0x120
+#define R92C_HISR 0x124
+#define R92C_HIMRE 0x128
+#define R92C_HISRE 0x12c
+#define R92C_CPWM 0x12f
+#define R92C_FWIMR 0x130
+#define R92C_FWISR 0x134
+#define R92C_PKTBUF_DBG_CTRL 0x140
+#define R92C_PKTBUF_DBG_DATA_L 0x144
+#define R92C_PKTBUF_DBG_DATA_H 0x148
+#define R92C_TC0_CTRL(i) (0x150 + (i) * 4)
+#define R92C_TCUNIT_BASE 0x164
+#define R92C_MBIST_START 0x174
+#define R92C_MBIST_DONE 0x178
+#define R92C_MBIST_FAIL 0x17c
+#define R92C_C2H_EVT_MSG 0x1a0
+#define R92C_C2H_EVT_CLEAR 0x1af
+#define R92C_C2H_EVT_MSG_TEST 0x1b8
+#define R92C_MCUTST_1 0x1c0
+#define R92C_FMETHR 0x1c8
+#define R92C_HMETFR 0x1cc
+#define R92C_HMEBOX(idx) (0x1d0 + (idx) * 4)
+#define R92C_LLT_INIT 0x1e0
+#define R92C_BB_ACCESS_CTRL 0x1e8
+#define R92C_BB_ACCESS_DATA 0x1ec
+/* Tx DMA Configuration. */
+#define R92C_RQPN 0x200
+#define R92C_FIFOPAGE 0x204
+#define R92C_TDECTRL 0x208
+#define R92C_TXDMA_OFFSET_CHK 0x20c
+#define R92C_TXDMA_STATUS 0x210
+#define R92C_RQPN_NPQ 0x214
+/* Rx DMA Configuration. */
+#define R92C_RXDMA_AGG_PG_TH 0x280
+#define R92C_RXPKT_NUM 0x284
+#define R92C_RXDMA_STATUS 0x288
+/* Protocol Configuration. */
+#define R92C_VOQ_INFORMATION 0x400
+#define R92C_VIQ_INFORMATION 0x404
+#define R92C_BEQ_INFORMATION 0x408
+#define R92C_BKQ_INFORMATION 0x40c
+#define R92C_MGQ_INFORMATION 0x410
+#define R92C_HGQ_INFORMATION 0x414
+#define R92C_BCNQ_INFORMATION 0x418
+#define R92C_CPU_MGQ_INFORMATION 0x41c
+#define R92C_FWHW_TXQ_CTRL 0x420
+#define R92C_HWSEQ_CTRL 0x423
+#define R92C_TXPKTBUF_BCNQ_BDNY 0x424
+#define R92C_TXPKTBUF_MGQ_BDNY 0x425
+#define R92C_SPEC_SIFS 0x428
+#define R92C_RL 0x42a
+#define R92C_DARFRC 0x430
+#define R92C_RARFRC 0x438
+#define R92C_RRSR 0x440
+#define R92C_ARFR(i) (0x444 + (i) * 4)
+#define R92C_AGGLEN_LMT 0x458
+#define R92C_AMPDU_MIN_SPACE 0x45c
+#define R92C_TXPKTBUF_WMAC_LBK_BF_HD 0x45d
+#define R92C_FAST_EDCA_CTRL 0x460
+#define R92C_RD_RESP_PKT_TH 0x463
+#define R92C_INIRTS_RATE_SEL 0x480
+#define R92C_INIDATA_RATE_SEL(macid) (0x484 + (macid))
+#define R92C_QUEUE_CTRL 0x4c6
+#define R92C_MAX_AGGR_NUM 0x4ca
+#define R92C_BAR_MODE_CTRL 0x4cc
+/* EDCA Configuration. */
+#define R92C_EDCA_VO_PARAM 0x500
+#define R92C_EDCA_VI_PARAM 0x504
+#define R92C_EDCA_BE_PARAM 0x508
+#define R92C_EDCA_BK_PARAM 0x50c
+#define R92C_BCNTCFG 0x510
+#define R92C_PIFS 0x512
+#define R92C_RDG_PIFS 0x513
+#define R92C_SIFS_CCK 0x514
+#define R92C_SIFS_OFDM 0x516
+#define R92C_AGGR_BREAK_TIME 0x51a
+#define R92C_SLOT 0x51b
+#define R92C_TX_PTCL_CTRL 0x520
+#define R92C_TXPAUSE 0x522
+#define R92C_DIS_TXREQ_CLR 0x523
+#define R92C_RD_CTRL 0x524
+#define R92C_TBTT_PROHIBIT 0x540
+#define R92C_RD_NAV_NXT 0x544
+#define R92C_NAV_PROT_LEN 0x546
+#define R92C_BCN_CTRL(id) ((id) + 0x550)
+/* WARNING: R92C_USTIME_TSF == 0x55c, not 0x551 */
+#define R92C_MBID_NUM 0x552
+#define R92C_DUAL_TSF_RST 0x553
+#define R92C_BCN_INTERVAL(id) (0x554 + (id) * 2)
+#define R92C_DRVERLYINT 0x558
+#define R92C_BCNDMATIM 0x559
+#define R92C_ATIMWND 0x55a
+#define R92C_USTIME_TSF 0x55c
+#define R92C_BCN_MAX_ERR 0x55d
+#define R92C_RXTSF_OFFSET_CCK 0x55e
+#define R92C_RXTSF_OFFSET_OFDM 0x55f
+#define R92C_TSFTR(i) (0x560 + (i) * 8)
+#define R92C_PSTIMER 0x580
+#define R92C_TIMER0 0x584
+#define R92C_TIMER1 0x588
+#define R92C_ACMHWCTRL 0x5c0
+#define R92C_ACMRSTCTRL 0x5c1
+#define R92C_ACMAVG 0x5c2
+#define R92C_VO_ADMTIME 0x5c4
+#define R92C_VI_ADMTIME 0x5c6
+#define R92C_BE_ADMTIME 0x5c8
+#define R92C_EDCA_RANDOM_GEN 0x5cc
+#define R92C_SCH_TXCMD 0x5d0
+/* WMAC Configuration. */
+#define R92C_APSD_CTRL 0x600
+#define R92C_BWOPMODE 0x603
+#define R92C_TCR 0x604
+#define R92C_RCR 0x608
+#define R92C_RX_PKT_LIMIT 0x60c
+#define R92C_RX_DRVINFO_SZ 0x60f
+#define R92C_MACID0 0x610
+#define R92C_BSSID0 0x618
+#define R92C_MAR 0x620
+#define R92C_USTIME_EDCA 0x638
+#define R92C_MAC_SPEC_SIFS 0x63a
+#define R92C_R2T_SIFS 0x63c
+#define R92C_T2T_SIFS 0x63e
+#define R92C_ACKTO 0x640
+#define R92C_NAV_UPPER 0x652
+#define R92C_WMAC_TRXPTCL_CTL 0x668
+#define R92C_CAMCMD 0x670
+#define R92C_CAMWRITE 0x674
+#define R92C_CAMREAD 0x678
+#define R92C_CAMDBG 0x67c
+#define R92C_SECCFG 0x680
+#define R92C_RXFLTMAP0 0x6a0
+#define R92C_RXFLTMAP1 0x6a2
+#define R92C_RXFLTMAP2 0x6a4
+#define R92C_BCN_PSR_RPT 0x6a8
+#define R92C_MACID1 0x700
+#define R92C_BSSID1 0x708
+
+
+#define R92C_MACID(id) ((id) == 0 ? R92C_MACID0 : R92C_MACID1)
+#define R92C_BSSID(id) ((id) == 0 ? R92C_BSSID0 : R92C_BSSID1)
+
+/* Bits for R92C_SYS_ISO_CTRL. */
+#define R92C_SYS_ISO_CTRL_MD2PP 0x0001
+#define R92C_SYS_ISO_CTRL_UA2USB 0x0002
+#define R92C_SYS_ISO_CTRL_UD2CORE 0x0004
+#define R92C_SYS_ISO_CTRL_PA2PCIE 0x0008
+#define R92C_SYS_ISO_CTRL_PD2CORE 0x0010
+#define R92C_SYS_ISO_CTRL_IP2MAC 0x0020
+#define R92C_SYS_ISO_CTRL_DIOP 0x0040
+#define R92C_SYS_ISO_CTRL_DIOE 0x0080
+#define R92C_SYS_ISO_CTRL_EB2CORE 0x0100
+#define R92C_SYS_ISO_CTRL_DIOR 0x0200
+#define R92C_SYS_ISO_CTRL_PWC_EV25V 0x4000
+#define R92C_SYS_ISO_CTRL_PWC_EV12V 0x8000
+
+/* Bits for R92C_SYS_FUNC_EN. */
+#define R92C_SYS_FUNC_EN_BBRSTB 0x0001
+#define R92C_SYS_FUNC_EN_BB_GLB_RST 0x0002
+#define R92C_SYS_FUNC_EN_USBA 0x0004
+#define R92C_SYS_FUNC_EN_UPLL 0x0008
+#define R92C_SYS_FUNC_EN_USBD 0x0010
+#define R92C_SYS_FUNC_EN_DIO_PCIE 0x0020
+#define R92C_SYS_FUNC_EN_PCIEA 0x0040
+#define R92C_SYS_FUNC_EN_PPLL 0x0080
+#define R92C_SYS_FUNC_EN_PCIED 0x0100
+#define R92C_SYS_FUNC_EN_DIOE 0x0200
+#define R92C_SYS_FUNC_EN_CPUEN 0x0400
+#define R92C_SYS_FUNC_EN_DCORE 0x0800
+#define R92C_SYS_FUNC_EN_ELDR 0x1000
+#define R92C_SYS_FUNC_EN_DIO_RF 0x2000
+#define R92C_SYS_FUNC_EN_HWPDN 0x4000
+#define R92C_SYS_FUNC_EN_MREGEN 0x8000
+
+/* Bits for R92C_APS_FSMCO. */
+#define R92C_APS_FSMCO_PFM_LDALL 0x00000001
+#define R92C_APS_FSMCO_PFM_ALDN 0x00000002
+#define R92C_APS_FSMCO_PFM_LDKP 0x00000004
+#define R92C_APS_FSMCO_PFM_WOWL 0x00000008
+#define R92C_APS_FSMCO_PDN_EN 0x00000010
+#define R92C_APS_FSMCO_PDN_PL 0x00000020
+#define R92C_APS_FSMCO_APFM_ONMAC 0x00000100
+#define R92C_APS_FSMCO_APFM_OFF 0x00000200
+#define R92C_APS_FSMCO_APFM_RSM 0x00000400
+#define R92C_APS_FSMCO_AFSM_HSUS 0x00000800
+#define R92C_APS_FSMCO_AFSM_PCIE 0x00001000
+#define R92C_APS_FSMCO_APDM_MAC 0x00002000
+#define R92C_APS_FSMCO_APDM_HOST 0x00004000
+#define R92C_APS_FSMCO_APDM_HPDN 0x00008000
+#define R92C_APS_FSMCO_RDY_MACON 0x00010000
+#define R92C_APS_FSMCO_SUS_HOST 0x00020000
+#define R92C_APS_FSMCO_ROP_ALD 0x00100000
+#define R92C_APS_FSMCO_ROP_PWR 0x00200000
+#define R92C_APS_FSMCO_ROP_SPS 0x00400000
+#define R92C_APS_FSMCO_SOP_MRST 0x02000000
+#define R92C_APS_FSMCO_SOP_FUSE 0x04000000
+#define R92C_APS_FSMCO_SOP_ABG 0x08000000
+#define R92C_APS_FSMCO_SOP_AMB 0x10000000
+#define R92C_APS_FSMCO_SOP_RCK 0x20000000
+#define R92C_APS_FSMCO_SOP_A8M 0x40000000
+#define R92C_APS_FSMCO_XOP_BTCK 0x80000000
+
+/* Bits for R92C_SYS_CLKR. */
+#define R92C_SYS_CLKR_ANAD16V_EN 0x00000001
+#define R92C_SYS_CLKR_ANA8M 0x00000002
+#define R92C_SYS_CLKR_MACSLP 0x00000010
+#define R92C_SYS_CLKR_LOADER_EN 0x00000020
+#define R92C_SYS_CLKR_80M_SSC_DIS 0x00000080
+#define R92C_SYS_CLKR_80M_SSC_EN_HO 0x00000100
+#define R92C_SYS_CLKR_PHY_SSC_RSTB 0x00000200
+#define R92C_SYS_CLKR_SEC_EN 0x00000400
+#define R92C_SYS_CLKR_MAC_EN 0x00000800
+#define R92C_SYS_CLKR_SYS_EN 0x00001000
+#define R92C_SYS_CLKR_RING_EN 0x00002000
+
+/* Bits for R92C_RF_CTRL. */
+#define R92C_RF_CTRL_EN 0x01
+#define R92C_RF_CTRL_RSTB 0x02
+#define R92C_RF_CTRL_SDMRSTB 0x04
+
+/* Bits for R92C_LDOA15_CTRL. */
+#define R92C_LDOA15_CTRL_EN 0x01
+#define R92C_LDOA15_CTRL_STBY 0x02
+#define R92C_LDOA15_CTRL_OBUF 0x04
+#define R92C_LDOA15_CTRL_REG_VOS 0x08
+
+/* Bits for R92C_LDOV12D_CTRL. */
+#define R92C_LDOV12D_CTRL_LDV12_EN 0x01
+
+/* Bits for R92C_LPLDO_CTRL. */
+#define R92C_LPLDO_CTRL_SLEEP 0x10
+
+/* Bits for R92C_AFE_XTAL_CTRL. */
+#define R92C_AFE_XTAL_CTRL_ADDR_M 0x007ff800
+#define R92C_AFE_XTAL_CTRL_ADDR_S 11
+
+/* Bits for R92C_AFE_PLL_CTRL. */
+#define R92C_AFE_PLL_CTRL_EN 0x0001
+#define R92C_AFE_PLL_CTRL_320_EN 0x0002
+#define R92C_AFE_PLL_CTRL_FREF_SEL 0x0004
+#define R92C_AFE_PLL_CTRL_EDGE_SEL 0x0008
+#define R92C_AFE_PLL_CTRL_WDOGB 0x0010
+#define R92C_AFE_PLL_CTRL_LPFEN 0x0020
+
+/* Bits for R92C_EFUSE_CTRL. */
+#define R92C_EFUSE_CTRL_DATA_M 0x000000ff
+#define R92C_EFUSE_CTRL_DATA_S 0
+#define R92C_EFUSE_CTRL_ADDR_M 0x0003ff00
+#define R92C_EFUSE_CTRL_ADDR_S 8
+#define R92C_EFUSE_CTRL_VALID 0x80000000
+
+/* Bits for R92C_GPIO_MUXCFG. */
+#define R92C_GPIO_MUXCFG_ENBT 0x0020
+
+/* Bits for R92C_LEDCFG0. */
+#define R92C_LEDCFG0_DIS 0x08
+
+/* Bits for R92C_MULTI_FUNC_CTRL. */
+#define R92C_MULTI_BT_FUNC_EN 0x00040000
+
+/* Bits for R92C_MCUFWDL. */
+#define R92C_MCUFWDL_EN 0x00000001
+#define R92C_MCUFWDL_RDY 0x00000002
+#define R92C_MCUFWDL_CHKSUM_RPT 0x00000004
+#define R92C_MCUFWDL_MACINI_RDY 0x00000008
+#define R92C_MCUFWDL_BBINI_RDY 0x00000010
+#define R92C_MCUFWDL_RFINI_RDY 0x00000020
+#define R92C_MCUFWDL_WINTINI_RDY 0x00000040
+#define R92C_MCUFWDL_RAM_DL_SEL 0x00000080 /* 1: RAM, 0: ROM */
+#define R92C_MCUFWDL_PAGE_M 0x00070000
+#define R92C_MCUFWDL_PAGE_S 16
+#define R92C_MCUFWDL_ROM_DLEN 0x00080000
+#define R92C_MCUFWDL_CPRST 0x00800000
+
+/* Bits for R92C_EFUSE_ACCESS. */
+#define R92C_EFUSE_ACCESS_OFF 0x00
+#define R92C_EFUSE_ACCESS_ON 0x69
+
+/* Bits for R92C_HPON_FSM. */
+#define R92C_HPON_FSM_CHIP_BONDING_ID_S 22
+#define R92C_HPON_FSM_CHIP_BONDING_ID_M 0x00c00000
+#define R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R 1
+
+/* Bits for R92C_SYS_CFG. */
+#define R92C_SYS_CFG_XCLK_VLD 0x00000001
+#define R92C_SYS_CFG_ACLK_VLD 0x00000002
+#define R92C_SYS_CFG_UCLK_VLD 0x00000004
+#define R92C_SYS_CFG_PCLK_VLD 0x00000008
+#define R92C_SYS_CFG_PCIRSTB 0x00000010
+#define R92C_SYS_CFG_V15_VLD 0x00000020
+#define R92C_SYS_CFG_TRP_B15V_EN 0x00000080
+#define R92C_SYS_CFG_SIC_IDLE 0x00000100
+#define R92C_SYS_CFG_BD_MAC2 0x00000200
+#define R92C_SYS_CFG_BD_MAC1 0x00000400
+#define R92C_SYS_CFG_IC_MACPHY_MODE 0x00000800
+#define R92C_SYS_CFG_CHIP_VER_RTL_M 0x0000f000
+#define R92C_SYS_CFG_CHIP_VER_RTL_S 12
+#define R92C_SYS_CFG_BT_FUNC 0x00010000
+#define R92C_SYS_CFG_VENDOR_UMC 0x00080000
+#define R92C_SYS_CFG_PAD_HWPD_IDN 0x00400000
+#define R92C_SYS_CFG_TRP_VAUX_EN 0x00800000
+#define R92C_SYS_CFG_TRP_BT_EN 0x01000000
+#define R92C_SYS_CFG_BD_PKG_SEL 0x02000000
+#define R92C_SYS_CFG_BD_HCI_SEL 0x04000000
+#define R92C_SYS_CFG_TYPE_92C 0x08000000
+
+/* Bits for R92C_CR. */
+#define R92C_CR_HCI_TXDMA_EN 0x0001
+#define R92C_CR_HCI_RXDMA_EN 0x0002
+#define R92C_CR_TXDMA_EN 0x0004
+#define R92C_CR_RXDMA_EN 0x0008
+#define R92C_CR_PROTOCOL_EN 0x0010
+#define R92C_CR_SCHEDULE_EN 0x0020
+#define R92C_CR_MACTXEN 0x0040
+#define R92C_CR_MACRXEN 0x0080
+#define R92C_CR_ENSWBCN 0x0100
+#define R92C_CR_ENSEC 0x0200
+#define R92C_CR_CALTMR_EN 0x0400
+
+/* Bits for R92C_MSR. */
+#define R92C_MSR_NOLINK 0x00
+#define R92C_MSR_ADHOC 0x01
+#define R92C_MSR_INFRA 0x02
+#define R92C_MSR_AP 0x03
+#define R92C_MSR_MASK (R92C_MSR_AP)
+
+/* Bits for R92C_PBP. */
+#define R92C_PBP_PSRX_M 0x0f
+#define R92C_PBP_PSRX_S 0
+#define R92C_PBP_PSTX_M 0xf0
+#define R92C_PBP_PSTX_S 4
+#define R92C_PBP_64 0
+#define R92C_PBP_128 1
+#define R92C_PBP_256 2
+#define R92C_PBP_512 3
+#define R92C_PBP_1024 4
+
+/* Bits for R92C_TRXDMA_CTRL. */
+#define R92C_TRXDMA_CTRL_RXDMA_AGG_EN 0x0004
+#define R92C_TRXDMA_CTRL_TXDMA_VOQ_MAP_M 0x0030
+#define R92C_TRXDMA_CTRL_TXDMA_VOQ_MAP_S 4
+#define R92C_TRXDMA_CTRL_TXDMA_VIQ_MAP_M 0x00c0
+#define R92C_TRXDMA_CTRL_TXDMA_VIQ_MAP_S 6
+#define R92C_TRXDMA_CTRL_TXDMA_BEQ_MAP_M 0x0300
+#define R92C_TRXDMA_CTRL_TXDMA_BEQ_MAP_S 8
+#define R92C_TRXDMA_CTRL_TXDMA_BKQ_MAP_M 0x0c00
+#define R92C_TRXDMA_CTRL_TXDMA_BKQ_MAP_S 10
+#define R92C_TRXDMA_CTRL_TXDMA_MGQ_MAP_M 0x3000
+#define R92C_TRXDMA_CTRL_TXDMA_MGQ_MAP_S 12
+#define R92C_TRXDMA_CTRL_TXDMA_HIQ_MAP_M 0xc000
+#define R92C_TRXDMA_CTRL_TXDMA_HIQ_MAP_S 14
+#define R92C_TRXDMA_CTRL_QUEUE_LOW 1
+#define R92C_TRXDMA_CTRL_QUEUE_NORMAL 2
+#define R92C_TRXDMA_CTRL_QUEUE_HIGH 3
+#define R92C_TRXDMA_CTRL_QMAP_M 0xfff0
+/* Shortcuts. */
+#define R92C_TRXDMA_CTRL_QMAP_3EP 0xf5b0
+#define R92C_TRXDMA_CTRL_QMAP_HQ_LQ 0xf5f0
+#define R92C_TRXDMA_CTRL_QMAP_HQ_NQ 0xfaf0
+#define R92C_TRXDMA_CTRL_QMAP_LQ 0x5550
+#define R92C_TRXDMA_CTRL_QMAP_NQ 0xaaa0
+#define R92C_TRXDMA_CTRL_QMAP_HQ 0xfff0
+
+/* Bits for R92C_C2H_EVT_CLEAR. */
+#define R92C_C2H_EVT_HOST_CLOSE 0x00
+#define R92C_C2H_EVT_FW_CLOSE 0xff
+
+/* Bits for R92C_LLT_INIT. */
+#define R92C_LLT_INIT_DATA_M 0x000000ff
+#define R92C_LLT_INIT_DATA_S 0
+#define R92C_LLT_INIT_ADDR_M 0x0000ff00
+#define R92C_LLT_INIT_ADDR_S 8
+#define R92C_LLT_INIT_OP_M 0xc0000000
+#define R92C_LLT_INIT_OP_S 30
+#define R92C_LLT_INIT_OP_NO_ACTIVE 0
+#define R92C_LLT_INIT_OP_WRITE 1
+
+/* Bits for R92C_RQPN. */
+#define R92C_RQPN_HPQ_M 0x000000ff
+#define R92C_RQPN_HPQ_S 0
+#define R92C_RQPN_LPQ_M 0x0000ff00
+#define R92C_RQPN_LPQ_S 8
+#define R92C_RQPN_PUBQ_M 0x00ff0000
+#define R92C_RQPN_PUBQ_S 16
+#define R92C_RQPN_LD 0x80000000
+
+/* Bits for R92C_TDECTRL. */
+#define R92C_TDECTRL_BLK_DESC_NUM_M 0x000000f0
+#define R92C_TDECTRL_BLK_DESC_NUM_S 4
+#define R92C_TDECTRL_BCN_VALID 0x00010000
+
+/* Bits for R92C_TXDMA_OFFSET_CHK. */
+#define R92C_TXDMA_OFFSET_DROP_DATA_EN 0x00000200
+
+/* Bits for R92C_FWHW_TXQ_CTRL. */
+#define R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW 0x80
+#define R92C_FWHW_TXQ_CTRL_REAL_BEACON 0x400000
+
+/* Bits for R92C_SPEC_SIFS. */
+#define R92C_SPEC_SIFS_CCK_M 0x00ff
+#define R92C_SPEC_SIFS_CCK_S 0
+#define R92C_SPEC_SIFS_OFDM_M 0xff00
+#define R92C_SPEC_SIFS_OFDM_S 8
+
+/* Bits for R92C_RL. */
+#define R92C_RL_LRL_M 0x003f
+#define R92C_RL_LRL_S 0
+#define R92C_RL_SRL_M 0x3f00
+#define R92C_RL_SRL_S 8
+
+/* Size of R92C_DARFRC. */
+#define R92C_DARFRC_SIZE 8
+
+/* Bits for R92C_RRSR. */
+#define R92C_RRSR_RATE_BITMAP_M 0x000fffff
+#define R92C_RRSR_RATE_BITMAP_S 0
+#define R92C_RRSR_RATE_CCK_ONLY_1M 0xffff1
+#define R92C_RRSR_RATE_ALL 0xfffff
+#define R92C_RRSR_RSC_LOWSUBCHNL 0x00200000
+#define R92C_RRSR_RSC_UPSUBCHNL 0x00400000
+#define R92C_RRSR_SHORT 0x00800000
+
+/* Bits for R92C_EDCA_XX_PARAM. */
+#define R92C_EDCA_PARAM_AIFS_M 0x000000ff
+#define R92C_EDCA_PARAM_AIFS_S 0
+#define R92C_EDCA_PARAM_ECWMIN_M 0x00000f00
+#define R92C_EDCA_PARAM_ECWMIN_S 8
+#define R92C_EDCA_PARAM_ECWMAX_M 0x0000f000
+#define R92C_EDCA_PARAM_ECWMAX_S 12
+#define R92C_EDCA_PARAM_TXOP_M 0xffff0000
+#define R92C_EDCA_PARAM_TXOP_S 16
+
+/* Bits for R92C_HWSEQ_CTRL / R92C_TXPAUSE. */
+#define R92C_TX_QUEUE_VO 0x01
+#define R92C_TX_QUEUE_VI 0x02
+#define R92C_TX_QUEUE_BE 0x04
+#define R92C_TX_QUEUE_BK 0x08
+#define R92C_TX_QUEUE_MGT 0x10
+#define R92C_TX_QUEUE_HIGH 0x20
+#define R92C_TX_QUEUE_BCN 0x40
+
+/* Shortcuts. */
+#define R92C_TX_QUEUE_AC \
+ (R92C_TX_QUEUE_VO | R92C_TX_QUEUE_VI | \
+ R92C_TX_QUEUE_BE | R92C_TX_QUEUE_BK)
+
+#define R92C_TX_QUEUE_ALL \
+ (R92C_TX_QUEUE_AC | R92C_TX_QUEUE_MGT | \
+ R92C_TX_QUEUE_HIGH | R92C_TX_QUEUE_BCN | 0x80) /* XXX */
+
+/* Bits for R92C_BCN_CTRL. */
+#define R92C_BCN_CTRL_EN_MBSSID 0x02
+#define R92C_BCN_CTRL_TXBCN_RPT 0x04
+#define R92C_BCN_CTRL_EN_BCN 0x08
+#define R92C_BCN_CTRL_DIS_TSF_UDT0 0x10
+
+/* Bits for R92C_DUAL_TSF_RST. */
+#define R92C_DUAL_TSF_RESET(id) (0x01 << (id))
+#define R92C_DUAL_TSF_RST_TXOK 0x20
+
+/* Bits for R92C_ACMHWCTRL. */
+#define R92C_ACMHWCTRL_EN 0x01
+#define R92C_ACMHWCTRL_BE 0x02
+#define R92C_ACMHWCTRL_VI 0x04
+#define R92C_ACMHWCTRL_VO 0x08
+#define R92C_ACMHWCTRL_ACM_MASK 0x0f
+
+/* Bits for R92C_APSD_CTRL. */
+#define R92C_APSD_CTRL_OFF 0x40
+#define R92C_APSD_CTRL_OFF_STATUS 0x80
+
+/* Bits for R92C_BWOPMODE. */
+#define R92C_BWOPMODE_11J 0x01
+#define R92C_BWOPMODE_5G 0x02
+#define R92C_BWOPMODE_20MHZ 0x04
+
+/* Bits for R92C_TCR. */
+#define R92C_TCR_TSFRST 0x00000001
+#define R92C_TCR_DIS_GCLK 0x00000002
+#define R92C_TCR_PAD_SEL 0x00000004
+#define R92C_TCR_PWR_ST 0x00000040
+#define R92C_TCR_PWRBIT_OW_EN 0x00000080
+#define R92C_TCR_ACRC 0x00000100
+#define R92C_TCR_CFENDFORM 0x00000200
+#define R92C_TCR_ICV 0x00000400
+
+/* Bits for R92C_RCR. */
+#define R92C_RCR_AAP 0x00000001
+#define R92C_RCR_APM 0x00000002
+#define R92C_RCR_AM 0x00000004
+#define R92C_RCR_AB 0x00000008
+#define R92C_RCR_ADD3 0x00000010
+#define R92C_RCR_APWRMGT 0x00000020
+#define R92C_RCR_CBSSID_DATA 0x00000040
+#define R92C_RCR_CBSSID_BCN 0x00000080
+#define R92C_RCR_ACRC32 0x00000100
+#define R92C_RCR_AICV 0x00000200
+#define R92C_RCR_ADF 0x00000800
+#define R92C_RCR_ACF 0x00001000
+#define R92C_RCR_AMF 0x00002000
+#define R92C_RCR_HTC_LOC_CTRL 0x00004000
+#define R92C_RCR_MFBEN 0x00400000
+#define R92C_RCR_LSIGEN 0x00800000
+#define R92C_RCR_ENMBID 0x01000000
+#define R92C_RCR_APP_BA_SSN 0x08000000
+#define R92C_RCR_APP_PHYSTS 0x10000000
+#define R92C_RCR_APP_ICV 0x20000000
+#define R92C_RCR_APP_MIC 0x40000000
+#define R92C_RCR_APPFCS 0x80000000
+
+/* Bits for R92C_RX_DRVINFO_SZ. */
+#define R92C_RX_DRVINFO_SZ_DEF 4 /* XXX other values will not work */
+
+/* Bits for R92C_WMAC_TRXPTCL_CTL. */
+#define R92C_WMAC_TRXPTCL_SHPRE 0x00020000
+
+/* Bits for R92C_CAMCMD. */
+#define R92C_CAMCMD_ADDR_M 0x0000ffff
+#define R92C_CAMCMD_ADDR_S 0
+#define R92C_CAMCMD_WRITE 0x00010000
+#define R92C_CAMCMD_CLR 0x40000000
+#define R92C_CAMCMD_POLLING 0x80000000
+
+
+/*
+ * CAM entries.
+ */
+#define R92C_CAM_CTL0(entry) ((entry) * 8 + 0)
+#define R92C_CAM_CTL1(entry) ((entry) * 8 + 1)
+#define R92C_CAM_KEY(entry, i) ((entry) * 8 + 2 + (i))
+#define R92C_CAM_CTL6(entry) ((entry) * 8 + 6)
+#define R92C_CAM_CTL7(entry) ((entry) * 8 + 7)
+
+/* Bits for R92C_CAM_CTL0(i). */
+#define R92C_CAM_KEYID_M 0x00000003
+#define R92C_CAM_KEYID_S 0
+#define R92C_CAM_ALGO_M 0x0000001c
+#define R92C_CAM_ALGO_S 2
+#define R92C_CAM_ALGO_NONE 0
+#define R92C_CAM_ALGO_WEP40 1
+#define R92C_CAM_ALGO_TKIP 2
+#define R92C_CAM_ALGO_AES 4
+#define R92C_CAM_ALGO_WEP104 5
+#define R92C_CAM_VALID 0x00008000
+#define R92C_CAM_MACLO_M 0xffff0000
+#define R92C_CAM_MACLO_S 16
+
+/* Bits for R92C_SECCFG. */
+#define R92C_SECCFG_TXUCKEY_DEF 0x0001
+#define R92C_SECCFG_RXUCKEY_DEF 0x0002
+#define R92C_SECCFG_TXENC_ENA 0x0004
+#define R92C_SECCFG_RXDEC_ENA 0x0008
+#define R92C_SECCFG_CMP_A2 0x0010
+#define R92C_SECCFG_MC_SRCH_DIS 0x0020
+#define R92C_SECCFG_TXBCKEY_DEF 0x0040
+#define R92C_SECCFG_RXBCKEY_DEF 0x0080
+
+/* Bits for R92C_RXFLTMAP*. */
+#define R92C_RXFLTMAP_SUBTYPE(subtype) \
+ (1 << ((subtype) >> IEEE80211_FC0_SUBTYPE_SHIFT))
+
+
+/*
+ * Baseband registers.
+ */
+#define R92C_FPGA0_RFMOD 0x800
+#define R92C_FPGA0_TXINFO 0x804
+#define R92C_HSSI_PARAM1(chain) (0x820 + (chain) * 8)
+#define R92C_HSSI_PARAM2(chain) (0x824 + (chain) * 8)
+#define R92C_TXAGC_RATE18_06(i) (((i) == 0) ? 0xe00 : 0x830)
+#define R92C_TXAGC_RATE54_24(i) (((i) == 0) ? 0xe04 : 0x834)
+#define R92C_TXAGC_A_CCK1_MCS32 0xe08
+#define R92C_TXAGC_B_CCK1_55_MCS32 0x838
+#define R92C_TXAGC_B_CCK11_A_CCK2_11 0x86c
+#define R92C_TXAGC_MCS03_MCS00(i) (((i) == 0) ? 0xe10 : 0x83c)
+#define R92C_TXAGC_MCS07_MCS04(i) (((i) == 0) ? 0xe14 : 0x848)
+#define R92C_TXAGC_MCS11_MCS08(i) (((i) == 0) ? 0xe18 : 0x84c)
+#define R92C_TXAGC_MCS15_MCS12(i) (((i) == 0) ? 0xe1c : 0x868)
+#define R92C_LSSI_PARAM(chain) (0x840 + (chain) * 4)
+#define R92C_FPGA0_RFIFACEOE(chain) (0x860 + (chain) * 4)
+#define R92C_FPGA0_RFIFACESW(idx) (0x870 + (idx) * 4)
+#define R92C_FPGA0_RFPARAM(idx) (0x878 + (idx) * 4)
+#define R92C_FPGA0_ANAPARAM2 0x884
+#define R92C_LSSI_READBACK(chain) (0x8a0 + (chain) * 4)
+#define R92C_HSPI_READBACK(chain) (0x8b8 + (chain) * 4)
+#define R92C_FPGA1_RFMOD 0x900
+#define R92C_FPGA1_TXINFO 0x90c
+#define R92C_CCK0_SYSTEM 0xa00
+#define R92C_CCK0_AFESETTING 0xa04
+#define R92C_OFDM0_TRXPATHENA 0xc04
+#define R92C_OFDM0_TRMUXPAR 0xc08
+#define R92C_OFDM0_RXIQIMBALANCE(chain) (0xc14 + (chain) * 8)
+#define R92C_OFDM0_ECCATHRESHOLD 0xc4c
+#define R92C_OFDM0_AGCCORE1(chain) (0xc50 + (chain) * 8)
+#define R92C_OFDM0_AGCPARAM1 0xc70
+#define R92C_OFDM0_AGCRSSITABLE 0xc78
+#define R92C_OFDM0_TXIQIMBALANCE(chain) (0xc80 + (chain) * 8)
+#define R92C_OFDM0_TXAFE(chain) (0xc94 + (chain) * 8)
+#define R92C_OFDM0_RXIQEXTANTA 0xca0
+#define R92C_OFDM1_LSTF 0xd00
+
+/* Bits for R92C_FPGA[01]_RFMOD. */
+#define R92C_RFMOD_40MHZ 0x00000001
+#define R92C_RFMOD_JAPAN 0x00000002
+#define R92C_RFMOD_CCK_TXSC 0x00000030
+#define R92C_RFMOD_CCK_EN 0x01000000
+#define R92C_RFMOD_OFDM_EN 0x02000000
+
+/* Bits for R92C_HSSI_PARAM1(i). */
+#define R92C_HSSI_PARAM1_PI 0x00000100
+
+/* Bits for R92C_HSSI_PARAM2(i). */
+#define R92C_HSSI_PARAM2_CCK_HIPWR 0x00000200
+#define R92C_HSSI_PARAM2_ADDR_LENGTH 0x00000400
+#define R92C_HSSI_PARAM2_DATA_LENGTH 0x00000800
+#define R92C_HSSI_PARAM2_READ_ADDR_M 0x7f800000
+#define R92C_HSSI_PARAM2_READ_ADDR_S 23
+#define R92C_HSSI_PARAM2_READ_EDGE 0x80000000
+
+/* Bits for R92C_TXAGC_A_CCK1_MCS32. */
+#define R92C_TXAGC_A_CCK1_M 0x0000ff00
+#define R92C_TXAGC_A_CCK1_S 8
+
+/* Bits for R92C_TXAGC_B_CCK11_A_CCK2_11. */
+#define R92C_TXAGC_B_CCK11_M 0x000000ff
+#define R92C_TXAGC_B_CCK11_S 0
+#define R92C_TXAGC_A_CCK2_M 0x0000ff00
+#define R92C_TXAGC_A_CCK2_S 8
+#define R92C_TXAGC_A_CCK55_M 0x00ff0000
+#define R92C_TXAGC_A_CCK55_S 16
+#define R92C_TXAGC_A_CCK11_M 0xff000000
+#define R92C_TXAGC_A_CCK11_S 24
+
+/* Bits for R92C_TXAGC_B_CCK1_55_MCS32. */
+#define R92C_TXAGC_B_CCK1_M 0x0000ff00
+#define R92C_TXAGC_B_CCK1_S 8
+#define R92C_TXAGC_B_CCK2_M 0x00ff0000
+#define R92C_TXAGC_B_CCK2_S 16
+#define R92C_TXAGC_B_CCK55_M 0xff000000
+#define R92C_TXAGC_B_CCK55_S 24
+
+/* Bits for R92C_TXAGC_RATE18_06(x). */
+#define R92C_TXAGC_RATE06_M 0x000000ff
+#define R92C_TXAGC_RATE06_S 0
+#define R92C_TXAGC_RATE09_M 0x0000ff00
+#define R92C_TXAGC_RATE09_S 8
+#define R92C_TXAGC_RATE12_M 0x00ff0000
+#define R92C_TXAGC_RATE12_S 16
+#define R92C_TXAGC_RATE18_M 0xff000000
+#define R92C_TXAGC_RATE18_S 24
+
+/* Bits for R92C_TXAGC_RATE54_24(x). */
+#define R92C_TXAGC_RATE24_M 0x000000ff
+#define R92C_TXAGC_RATE24_S 0
+#define R92C_TXAGC_RATE36_M 0x0000ff00
+#define R92C_TXAGC_RATE36_S 8
+#define R92C_TXAGC_RATE48_M 0x00ff0000
+#define R92C_TXAGC_RATE48_S 16
+#define R92C_TXAGC_RATE54_M 0xff000000
+#define R92C_TXAGC_RATE54_S 24
+
+/* Bits for R92C_TXAGC_MCS03_MCS00(x). */
+#define R92C_TXAGC_MCS00_M 0x000000ff
+#define R92C_TXAGC_MCS00_S 0
+#define R92C_TXAGC_MCS01_M 0x0000ff00
+#define R92C_TXAGC_MCS01_S 8
+#define R92C_TXAGC_MCS02_M 0x00ff0000
+#define R92C_TXAGC_MCS02_S 16
+#define R92C_TXAGC_MCS03_M 0xff000000
+#define R92C_TXAGC_MCS03_S 24
+
+/* Bits for R92C_TXAGC_MCS07_MCS04(x). */
+#define R92C_TXAGC_MCS04_M 0x000000ff
+#define R92C_TXAGC_MCS04_S 0
+#define R92C_TXAGC_MCS05_M 0x0000ff00
+#define R92C_TXAGC_MCS05_S 8
+#define R92C_TXAGC_MCS06_M 0x00ff0000
+#define R92C_TXAGC_MCS06_S 16
+#define R92C_TXAGC_MCS07_M 0xff000000
+#define R92C_TXAGC_MCS07_S 24
+
+/* Bits for R92C_TXAGC_MCS11_MCS08(x). */
+#define R92C_TXAGC_MCS08_M 0x000000ff
+#define R92C_TXAGC_MCS08_S 0
+#define R92C_TXAGC_MCS09_M 0x0000ff00
+#define R92C_TXAGC_MCS09_S 8
+#define R92C_TXAGC_MCS10_M 0x00ff0000
+#define R92C_TXAGC_MCS10_S 16
+#define R92C_TXAGC_MCS11_M 0xff000000
+#define R92C_TXAGC_MCS11_S 24
+
+/* Bits for R92C_TXAGC_MCS15_MCS12(x). */
+#define R92C_TXAGC_MCS12_M 0x000000ff
+#define R92C_TXAGC_MCS12_S 0
+#define R92C_TXAGC_MCS13_M 0x0000ff00
+#define R92C_TXAGC_MCS13_S 8
+#define R92C_TXAGC_MCS14_M 0x00ff0000
+#define R92C_TXAGC_MCS14_S 16
+#define R92C_TXAGC_MCS15_M 0xff000000
+#define R92C_TXAGC_MCS15_S 24
+
+/* Bits for R92C_LSSI_PARAM(i). */
+#define R92C_LSSI_PARAM_DATA_M 0x000fffff
+#define R92C_LSSI_PARAM_DATA_S 0
+#define R92C_LSSI_PARAM_ADDR_M 0x03f00000
+#define R92C_LSSI_PARAM_ADDR_S 20
+
+/* Bits for R92C_FPGA0_RFIFACEOE(0). */
+#define R92C_FPGA0_RFIFACEOE0_ANT_M 0x00000300
+#define R92C_FPGA0_RFIFACEOE0_ANT_S 8
+
+/* Bits for R92C_FPGA0_ANAPARAM2. */
+#define R92C_FPGA0_ANAPARAM2_CBW20 0x00000400
+
+/* Bits for R92C_LSSI_READBACK(i). */
+#define R92C_LSSI_READBACK_DATA_M 0x000fffff
+#define R92C_LSSI_READBACK_DATA_S 0
+
+/* Bits for R92C_OFDM0_AGCCORE1(i). */
+#define R92C_OFDM0_AGCCORE1_GAIN_M 0x0000007f
+#define R92C_OFDM0_AGCCORE1_GAIN_S 0
+
+
+/*
+ * RF (6052) registers.
+ */
+#define R92C_RF_AC 0x00
+#define R92C_RF_IQADJ_G(i) (0x01 + (i))
+#define R92C_RF_POW_TRSW 0x05
+#define R92C_RF_GAIN_RX 0x06
+#define R92C_RF_GAIN_TX 0x07
+#define R92C_RF_TXM_IDAC 0x08
+#define R92C_RF_BS_IQGEN 0x0f
+#define R92C_RF_MODE1 0x10
+#define R92C_RF_MODE2 0x11
+#define R92C_RF_RX_AGC_HP 0x12
+#define R92C_RF_TX_AGC 0x13
+#define R92C_RF_BIAS 0x14
+#define R92C_RF_IPA 0x15
+#define R92C_RF_POW_ABILITY 0x17
+#define R92C_RF_CHNLBW 0x18
+#define R92C_RF_RX_G1 0x1a
+#define R92C_RF_RX_G2 0x1b
+#define R92C_RF_RX_BB2 0x1c
+#define R92C_RF_RX_BB1 0x1d
+#define R92C_RF_RCK1 0x1e
+#define R92C_RF_RCK2 0x1f
+#define R92C_RF_TX_G(i) (0x20 + (i))
+#define R92C_RF_TX_BB1 0x23
+#define R92C_RF_T_METER 0x24
+#define R92C_RF_SYN_G(i) (0x25 + (i))
+#define R92C_RF_RCK_OS 0x30
+#define R92C_RF_TXPA_G(i) (0x31 + (i))
+
+/* Bits for R92C_RF_AC. */
+#define R92C_RF_AC_MODE_M 0x70000
+#define R92C_RF_AC_MODE_S 16
+#define R92C_RF_AC_MODE_STANDBY 1
+
+/* Bits for R92C_RF_CHNLBW. */
+#define R92C_RF_CHNLBW_CHNL_M 0x003ff
+#define R92C_RF_CHNLBW_CHNL_S 0
+#define R92C_RF_CHNLBW_BW20 0x00400
+#define R92C_RF_CHNLBW_LCSTART 0x08000
+
+/* Bits for R92C_RF_T_METER. */
+#define R92C_RF_T_METER_START 0x60
+#define R92C_RF_T_METER_VAL_M 0x1f
+#define R92C_RF_T_METER_VAL_S 0
+
+#endif /* R92C_REG_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rf.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rf.c
new file mode 100644
index 00000000..22507e6c
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rf.c
@@ -0,0 +1,95 @@
+#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_reg.h>
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+#include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
+
+
+uint32_t
+r92c_rf_read(struct rtwn_softc *sc, int chain, uint8_t addr)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ uint32_t reg[R92C_MAX_CHAINS], val;
+
+ reg[0] = rtwn_bb_read(sc, R92C_HSSI_PARAM2(0));
+ if (chain != 0)
+ reg[chain] = rtwn_bb_read(sc, R92C_HSSI_PARAM2(chain));
+
+ rtwn_bb_write(sc, R92C_HSSI_PARAM2(0),
+ reg[0] & ~R92C_HSSI_PARAM2_READ_EDGE);
+ rtwn_delay(sc, rs->rf_read_delay[0]);
+
+ rtwn_bb_write(sc, R92C_HSSI_PARAM2(chain),
+ RW(reg[chain], R92C_HSSI_PARAM2_READ_ADDR, addr) |
+ R92C_HSSI_PARAM2_READ_EDGE);
+ rtwn_delay(sc, rs->rf_read_delay[1]);
+
+ rtwn_bb_write(sc, R92C_HSSI_PARAM2(0),
+ reg[0] | R92C_HSSI_PARAM2_READ_EDGE);
+ rtwn_delay(sc, rs->rf_read_delay[2]);
+
+ if (rtwn_bb_read(sc, R92C_HSSI_PARAM1(chain)) & R92C_HSSI_PARAM1_PI)
+ val = rtwn_bb_read(sc, R92C_HSPI_READBACK(chain));
+ else
+ val = rtwn_bb_read(sc, R92C_LSSI_READBACK(chain));
+ return (MS(val, R92C_LSSI_READBACK_DATA));
+}
+
+void
+r92c_rf_write(struct rtwn_softc *sc, int chain, uint8_t addr,
+ uint32_t val)
+{
+ rtwn_bb_write(sc, R92C_LSSI_PARAM(chain),
+ SM(R92C_LSSI_PARAM_ADDR, addr) |
+ SM(R92C_LSSI_PARAM_DATA, val));
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom.c
new file mode 100644
index 00000000..1c1595fc
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom.c
@@ -0,0 +1,141 @@
+#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_efuse.h>
+
+#include <dev/rtwn/rtl8192c/r92c.h>
+#include <dev/rtwn/rtl8192c/r92c_priv.h>
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+#include <dev/rtwn/rtl8192c/r92c_rom_image.h>
+
+
+static void
+r92c_set_chains(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+
+ if (rs->chip & R92C_CHIP_92C) {
+ sc->ntxchains = (rs->chip & R92C_CHIP_92C_1T2R) ? 1 : 2;
+ sc->nrxchains = 2;
+ } else {
+ sc->ntxchains = 1;
+ sc->nrxchains = 1;
+ }
+}
+
+void
+r92c_efuse_postread(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+
+ /* XXX Weird but this is what the vendor driver does. */
+ sc->next_rom_addr = 0x1fa;
+ (void) rtwn_efuse_read_next(sc, &rs->pa_setting);
+ RTWN_DPRINTF(sc, RTWN_DEBUG_ROM, "%s: PA setting=0x%x\n", __func__,
+ rs->pa_setting);
+}
+
+void
+r92c_parse_rom(struct rtwn_softc *sc, uint8_t *buf)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ struct rtwn_r92c_txpwr *rt = rs->rs_txpwr;
+ struct r92c_rom *rom = (struct r92c_rom *)buf;
+ int i, j;
+
+ rs->board_type = MS(rom->rf_opt1, R92C_ROM_RF1_BOARD_TYPE);
+ rs->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY);
+ RTWN_DPRINTF(sc, RTWN_DEBUG_ROM, "%s: regulatory type=%d\n",
+ __func__, rs->regulatory);
+
+ /* Need to be set before postinit() (but after preinit()). */
+ rtwn_r92c_set_name(sc);
+ r92c_set_chains(sc);
+
+ for (j = 0; j < R92C_GROUP_2G; j++) {
+ for (i = 0; i < sc->ntxchains; i++) {
+ rt->cck_tx_pwr[i][j] = rom->cck_tx_pwr[i][j];
+ rt->ht40_1s_tx_pwr[i][j] = rom->ht40_1s_tx_pwr[i][j];
+ }
+
+ rt->ht40_2s_tx_pwr_diff[0][j] =
+ MS(rom->ht40_2s_tx_pwr_diff[j], LOW_PART);
+ rt->ht20_tx_pwr_diff[0][j] =
+ RTWN_SIGN4TO8(MS(rom->ht20_tx_pwr_diff[j],
+ LOW_PART));
+ rt->ofdm_tx_pwr_diff[0][j] =
+ MS(rom->ofdm_tx_pwr_diff[j], LOW_PART);
+ rt->ht40_max_pwr[0][j] =
+ MS(rom->ht40_max_pwr[j], LOW_PART);
+ rt->ht20_max_pwr[0][j] =
+ MS(rom->ht20_max_pwr[j], LOW_PART);
+
+ if (sc->ntxchains > 1) {
+ rt->ht40_2s_tx_pwr_diff[1][j] =
+ MS(rom->ht40_2s_tx_pwr_diff[j], HIGH_PART);
+ rt->ht20_tx_pwr_diff[1][j] =
+ RTWN_SIGN4TO8(MS(rom->ht20_tx_pwr_diff[j],
+ HIGH_PART));
+ rt->ofdm_tx_pwr_diff[1][j] =
+ MS(rom->ofdm_tx_pwr_diff[j], HIGH_PART);
+ rt->ht40_max_pwr[1][j] =
+ MS(rom->ht40_max_pwr[j], HIGH_PART);
+ rt->ht20_max_pwr[1][j] =
+ MS(rom->ht20_max_pwr[j], HIGH_PART);
+ }
+ }
+
+ sc->thermal_meter = MS(rom->thermal_meter, R92C_ROM_THERMAL_METER);
+ if (sc->thermal_meter == R92C_ROM_THERMAL_METER_M)
+ sc->thermal_meter = 0xff;
+ IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr);
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_defs.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_defs.h
new file mode 100644
index 00000000..35fc42df
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_defs.h
@@ -0,0 +1,57 @@
+/*-
+ * 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 R92C_ROM_DEFS_H
+#define R92C_ROM_DEFS_H
+
+#define R92C_MAX_CHAINS 2
+#define R92C_GROUP_2G 3
+
+#define R92C_EFUSE_MAX_LEN 512
+#define R92C_EFUSE_MAP_LEN 128
+
+/*
+ * Some generic rom parsing macros.
+ */
+#define RTWN_GET_ROM_VAR(var, def) (((var) != 0xff) ? (var) : (def))
+#define RTWN_SIGN4TO8(val) (((val) & 0x08) ? (val) | 0xf0 : (val))
+
+#define LOW_PART_M 0x0f
+#define LOW_PART_S 0
+#define HIGH_PART_M 0xf0
+#define HIGH_PART_S 4
+
+/* Bits for rf_board_opt (rf_opt1) field. */
+#define R92C_ROM_RF1_REGULATORY_M 0x07
+#define R92C_ROM_RF1_REGULATORY_S 0
+#define R92C_ROM_RF1_BOARD_TYPE_M 0xe0
+#define R92C_ROM_RF1_BOARD_TYPE_S 5
+
+/* Generic board types. */
+#define R92C_BOARD_TYPE_DONGLE 0
+#define R92C_BOARD_TYPE_HIGHPA 1
+#define R92C_BOARD_TYPE_MINICARD 2
+#define R92C_BOARD_TYPE_SOLO 3
+#define R92C_BOARD_TYPE_COMBO 4
+
+/* Bits for channel_plan field. */
+#define R92C_CHANNEL_PLAN_BY_HW 0x80
+
+#endif /* R92C_ROM_DEFS_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_image.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_image.h
new file mode 100644
index 00000000..304324e6
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_image.h
@@ -0,0 +1,71 @@
+/*-
+ * 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 R92C_ROM_IMAGE_H
+#define R92C_ROM_IMAGE_H
+
+#include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
+
+/*
+ * RTL8192CU ROM image.
+ */
+struct r92c_rom {
+ uint16_t id; /* 0x8192 */
+ uint8_t reserved1[5];
+ uint8_t dbg_sel;
+ uint16_t reserved2;
+ uint16_t vid;
+ uint16_t pid;
+ uint8_t usb_opt;
+ uint8_t ep_setting;
+ uint16_t reserved3;
+ uint8_t usb_phy;
+ uint8_t reserved4[3];
+ uint8_t macaddr[IEEE80211_ADDR_LEN];
+ uint8_t string[61]; /* "Realtek" */
+ uint8_t subcustomer_id;
+ uint8_t cck_tx_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
+ uint8_t ht40_1s_tx_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
+ uint8_t ht40_2s_tx_pwr_diff[R92C_GROUP_2G];
+ uint8_t ht20_tx_pwr_diff[R92C_GROUP_2G];
+ uint8_t ofdm_tx_pwr_diff[R92C_GROUP_2G];
+ uint8_t ht40_max_pwr[R92C_GROUP_2G];
+ uint8_t ht20_max_pwr[R92C_GROUP_2G];
+ uint8_t xtal_calib;
+ uint8_t tssi[R92C_MAX_CHAINS];
+ uint8_t thermal_meter;
+#define R92C_ROM_THERMAL_METER_M 0x1f
+#define R92C_ROM_THERMAL_METER_S 0
+
+ uint8_t rf_opt1;
+ uint8_t rf_opt2;
+ uint8_t rf_opt3;
+ uint8_t rf_opt4;
+ uint8_t channel_plan;
+#define R92C_CHANNEL_PLAN_BY_HW 0x80
+
+ uint8_t version;
+ uint8_t customer_id;
+} __packed;
+
+_Static_assert(sizeof(struct r92c_rom) == R92C_EFUSE_MAP_LEN,
+ "R92C_EFUSE_MAP_LEN must be equal to sizeof(struct r92c_rom)!");
+
+#endif /* R92C_ROM_IMAGE_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c
new file mode 100644
index 00000000..b77c76f6
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c
@@ -0,0 +1,104 @@
+#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_ridx.h>
+
+#include <dev/rtwn/rtl8192c/r92c.h>
+#include <dev/rtwn/rtl8192c/r92c_rx_desc.h>
+
+
+int8_t
+r92c_get_rssi_cck(struct rtwn_softc *sc, void *physt)
+{
+ static const int8_t cckoff[] = { 16, -12, -26, -46 };
+ struct r92c_rx_cck *cck = (struct r92c_rx_cck *)physt;
+ uint8_t rpt;
+ int8_t rssi;
+
+ if (sc->sc_flags & RTWN_FLAG_CCK_HIPWR) {
+ rpt = (cck->agc_rpt >> 5) & 0x03;
+ rssi = (cck->agc_rpt & 0x1f) << 1;
+ } else {
+ rpt = (cck->agc_rpt >> 6) & 0x03;
+ rssi = cck->agc_rpt & 0x3e;
+ }
+ rssi = cckoff[rpt] - rssi;
+
+ return (rssi);
+}
+
+int8_t
+r92c_get_rssi_ofdm(struct rtwn_softc *sc, void *physt)
+{
+ struct r92c_rx_phystat *phy = (struct r92c_rx_phystat *)physt;
+ int rssi;
+
+ /* Get average RSSI. */
+ rssi = ((phy->pwdb_all >> 1) & 0x7f) - 110;
+
+ return (rssi);
+}
+
+uint8_t
+r92c_rx_radiotap_flags(const void *buf)
+{
+ const struct r92c_rx_stat *stat = buf;
+ uint8_t flags, rate;
+
+ if (!(stat->rxdw3 & htole32(R92C_RXDW3_SPLCP)))
+ return (0);
+
+ rate = MS(le32toh(stat->rxdw3), R92C_RXDW3_RATE);
+ if (RTWN_RATE_IS_CCK(rate))
+ flags = IEEE80211_RADIOTAP_F_SHORTPRE;
+ else
+ flags = IEEE80211_RADIOTAP_F_SHORTGI;
+ return (flags);
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h
new file mode 100644
index 00000000..7fec70be
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h
@@ -0,0 +1,95 @@
+/*-
+ * 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 R92C_RX_DESC_H
+#define R92C_RX_DESC_H
+
+/* Rx MAC descriptor (common parts / USB). */
+struct r92c_rx_stat {
+ uint32_t rxdw0;
+#define R92C_RXDW0_PKTLEN_M 0x00003fff
+#define R92C_RXDW0_PKTLEN_S 0
+#define R92C_RXDW0_CRCERR 0x00004000
+#define R92C_RXDW0_ICVERR 0x00008000
+#define R92C_RXDW0_INFOSZ_M 0x000f0000
+#define R92C_RXDW0_INFOSZ_S 16
+#define R92C_RXDW0_CIPHER_M 0x00700000
+#define R92C_RXDW0_CIPHER_S 20
+#define R92C_RXDW0_QOS 0x00800000
+#define R92C_RXDW0_SHIFT_M 0x03000000
+#define R92C_RXDW0_SHIFT_S 24
+#define R92C_RXDW0_PHYST 0x04000000
+#define R92C_RXDW0_SWDEC 0x08000000
+#define R92C_RXDW0_LS 0x10000000
+#define R92C_RXDW0_FS 0x20000000
+#define R92C_RXDW0_EOR 0x40000000
+#define R92C_RXDW0_OWN 0x80000000
+
+ uint32_t rxdw1;
+#define R92C_RXDW1_MACID_M 0x0000001f
+#define R92C_RXDW1_MACID_S 0
+#define R92C_RXDW1_MC 0x40000000
+#define R92C_RXDW1_BC 0x80000000
+
+ uint32_t rxdw2;
+ uint32_t rxdw3;
+#define R92C_RXDW3_RATE_M 0x0000003f
+#define R92C_RXDW3_RATE_S 0
+#define R92C_RXDW3_HT 0x00000040
+#define R92C_RXDW3_SPLCP 0x00000100
+#define R92C_RXDW3_HT40 0x00000200
+#define R92C_RXDW3_HTC 0x00000400
+
+ uint32_t rxdw4;
+ uint32_t tsf_low;
+} __packed __attribute__((aligned(4)));
+
+/* Rx PHY CCK descriptor. */
+struct r92c_rx_cck {
+ uint8_t adc_pwdb[4];
+ uint8_t sq_rpt;
+ uint8_t agc_rpt;
+} __packed;
+
+/* Rx PHY descriptor. */
+struct r92c_rx_phystat {
+ uint8_t trsw_gain[4];
+ uint8_t pwdb_all;
+ uint8_t cfosho[4];
+ uint8_t cfotail[4];
+ uint8_t rxevm[2];
+ uint8_t rxsnr[4];
+ uint8_t pdsnr[2];
+ uint8_t csi_current[2];
+ uint8_t csi_target[2];
+ uint8_t sigevm;
+ uint8_t max_ex_pwr;
+ uint8_t phy_byte28;
+#define R92C_PHY_BYTE28_ANTSEL 0x01
+#define R92C_PHY_BYTE28_ANTSEL_B 0x02
+#define R92C_PHY_BYTE28_ANT_TRAIN_EN 0x04
+#define R92C_PHY_BYTE28_IDLE_LONG 0x08
+#define R92C_PHY_BYTE28_RXSC_M 0x30
+#define R92C_PHY_BYTE28_RXSC_S 4
+#define R92C_PHY_BYTE28_SGI_EN 0x40
+#define R92C_PHY_BYTE28_EX_INTF_FLG 0x80
+} __packed;
+
+#endif /* R92C_RX_DESC_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c
new file mode 100644
index 00000000..0e3c408d
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c
@@ -0,0 +1,438 @@
+#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_ridx.h>
+#include <dev/rtwn/if_rtwn_tx.h>
+
+#include <dev/rtwn/rtl8192c/r92c.h>
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
+
+
+static int
+r92c_tx_get_sco(struct rtwn_softc *sc, struct ieee80211_channel *c)
+{
+ if (IEEE80211_IS_CHAN_HT40U(c))
+ return (R92C_TXDW4_SCO_SCA);
+ else
+ return (R92C_TXDW4_SCO_SCB);
+}
+
+static void
+r92c_tx_set_ht40(struct rtwn_softc *sc, void *buf, struct ieee80211_node *ni)
+{
+ struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
+
+ if (ni->ni_chan != IEEE80211_CHAN_ANYC &&
+ IEEE80211_IS_CHAN_HT40(ni->ni_chan)) {
+ int extc_offset;
+
+ extc_offset = r92c_tx_get_sco(sc, ni->ni_chan);
+ txd->txdw4 |= htole32(R92C_TXDW4_DATA_BW40);
+ txd->txdw4 |= htole32(SM(R92C_TXDW4_DATA_SCO, extc_offset));
+ }
+}
+
+static void
+r92c_tx_protection(struct rtwn_softc *sc, struct r92c_tx_desc *txd,
+ enum ieee80211_protmode mode, uint8_t ridx)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint8_t rate;
+
+ switch (mode) {
+ case IEEE80211_PROT_CTSONLY:
+ txd->txdw4 |= htole32(R92C_TXDW4_CTS2SELF);
+ break;
+ case IEEE80211_PROT_RTSCTS:
+ txd->txdw4 |= htole32(R92C_TXDW4_RTSEN);
+ break;
+ default:
+ break;
+ }
+
+ if (mode == IEEE80211_PROT_CTSONLY ||
+ mode == IEEE80211_PROT_RTSCTS) {
+ if (ridx >= RTWN_RIDX_MCS(0))
+ rate = rtwn_ctl_mcsrate(ic->ic_rt, ridx);
+ else
+ rate = ieee80211_ctl_rate(ic->ic_rt, ridx2rate[ridx]);
+ ridx = rate2ridx(rate);
+
+ txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, ridx));
+ /* RTS rate fallback limit (max). */
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_RTSRATE_FB_LMT, 0xf));
+
+ if (RTWN_RATE_IS_CCK(ridx) && ridx != RTWN_RIDX_CCK1 &&
+ (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
+ txd->txdw4 |= htole32(R92C_TXDW4_RTS_SHORT);
+ }
+}
+
+static void
+r92c_tx_raid(struct rtwn_softc *sc, struct r92c_tx_desc *txd,
+ struct ieee80211_node *ni, int ismcast)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211_channel *chan;
+ enum ieee80211_phymode mode;
+ uint8_t raid;
+
+ chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ?
+ ni->ni_chan : ic->ic_curchan;
+ mode = ieee80211_chan2mode(chan);
+
+ /* NB: group addressed frames are done at 11bg rates for now */
+ if (ismcast || !(ni->ni_flags & IEEE80211_NODE_HT)) {
+ switch (mode) {
+ case IEEE80211_MODE_11B:
+ case IEEE80211_MODE_11G:
+ break;
+ case IEEE80211_MODE_11NG:
+ mode = IEEE80211_MODE_11G;
+ break;
+ default:
+ device_printf(sc->sc_dev, "unknown mode(1) %d!\n",
+ ic->ic_curmode);
+ return;
+ }
+ }
+
+ switch (mode) {
+ case IEEE80211_MODE_11B:
+ raid = R92C_RAID_11B;
+ break;
+ case IEEE80211_MODE_11G:
+ if (vap->iv_flags & IEEE80211_F_PUREG)
+ raid = R92C_RAID_11G;
+ else
+ raid = R92C_RAID_11BG;
+ break;
+ case IEEE80211_MODE_11NG:
+ if (vap->iv_flags_ht & IEEE80211_FHT_PUREN)
+ raid = R92C_RAID_11N;
+ else
+ raid = R92C_RAID_11BGN;
+ break;
+ default:
+ device_printf(sc->sc_dev, "unknown mode(2) %d!\n", mode);
+ return;
+ }
+
+ txd->txdw1 |= htole32(SM(R92C_TXDW1_RAID, raid));
+}
+
+/* XXX move to device-independent layer */
+static void
+r92c_tx_set_sgi(struct rtwn_softc *sc, void *buf, struct ieee80211_node *ni)
+{
+ struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
+ struct ieee80211vap *vap = ni->ni_vap;
+
+ if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) && /* HT20 */
+ (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20))
+ txd->txdw5 |= htole32(R92C_TXDW5_SGI);
+ else if (ni->ni_chan != IEEE80211_CHAN_ANYC && /* HT40 */
+ IEEE80211_IS_CHAN_HT40(ni->ni_chan) &&
+ (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) &&
+ (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40))
+ txd->txdw5 |= htole32(R92C_TXDW5_SGI);
+}
+
+void
+r92c_tx_enable_ampdu(void *buf, int enable)
+{
+ struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
+
+ if (enable)
+ txd->txdw1 |= htole32(R92C_TXDW1_AGGEN);
+ else
+ txd->txdw1 |= htole32(R92C_TXDW1_AGGBK);
+}
+
+void
+r92c_tx_setup_hwseq(void *buf)
+{
+ struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
+
+ txd->txdw4 |= htole32(R92C_TXDW4_HWSEQ_EN);
+}
+
+void
+r92c_tx_setup_macid(void *buf, int id)
+{
+ struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
+
+ txd->txdw1 |= htole32(SM(R92C_TXDW1_MACID, id));
+}
+
+void
+r92c_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
+ struct mbuf *m, void *buf, uint8_t ridx, int maxretry)
+{
+#ifndef RTWN_WITHOUT_UCODE
+ struct r92c_softc *rs = sc->sc_priv;
+#endif
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct rtwn_vap *uvp = RTWN_VAP(vap);
+ struct ieee80211_frame *wh;
+ struct r92c_tx_desc *txd;
+ enum ieee80211_protmode prot;
+ uint8_t type, tid, qos, qsel;
+ int hasqos, ismcast, macid;
+
+ wh = mtod(m, struct ieee80211_frame *);
+ type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+ hasqos = IEEE80211_QOS_HAS_SEQ(wh);
+ ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
+
+ /* Select TX ring for this frame. */
+ if (hasqos) {
+ qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
+ tid = qos & IEEE80211_QOS_TID;
+ } else {
+ qos = 0;
+ tid = 0;
+ }
+
+ /* Fill Tx descriptor. */
+ txd = (struct r92c_tx_desc *)buf;
+ txd->flags0 |= R92C_FLAGS0_LSG | R92C_FLAGS0_FSG;
+ if (ismcast)
+ txd->flags0 |= R92C_FLAGS0_BMCAST;
+
+ if (!ismcast) {
+ /* Unicast frame, check if an ACK is expected. */
+ if (!qos || (qos & IEEE80211_QOS_ACKPOLICY) !=
+ IEEE80211_QOS_ACKPOLICY_NOACK) {
+ txd->txdw5 |= htole32(R92C_TXDW5_RTY_LMT_ENA);
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_RTY_LMT,
+ maxretry));
+ }
+
+ struct rtwn_node *un = RTWN_NODE(ni);
+ macid = un->id;
+
+ if (type == IEEE80211_FC0_TYPE_DATA) {
+ qsel = tid % RTWN_MAX_TID;
+
+ rtwn_r92c_tx_enable_ampdu(sc, buf,
+ (m->m_flags & M_AMPDU_MPDU) != 0);
+ if (m->m_flags & M_AMPDU_MPDU) {
+ txd->txdw2 |= htole32(SM(R92C_TXDW2_AMPDU_DEN,
+ vap->iv_ampdu_density));
+ txd->txdw6 |= htole32(SM(R92C_TXDW6_MAX_AGG,
+ 0x1f)); /* XXX */
+ }
+ if (sc->sc_ratectl == RTWN_RATECTL_NET80211) {
+ txd->txdw2 |= htole32(R92C_TXDW2_CCX_RPT);
+ sc->sc_tx_n_active++;
+#ifndef RTWN_WITHOUT_UCODE
+ rs->rs_c2h_pending++;
+#endif
+ }
+
+ if (RTWN_RATE_IS_CCK(ridx) && ridx != RTWN_RIDX_CCK1 &&
+ (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
+ txd->txdw4 |= htole32(R92C_TXDW4_DATA_SHPRE);
+
+ prot = IEEE80211_PROT_NONE;
+ if (ridx >= RTWN_RIDX_MCS(0)) {
+ r92c_tx_set_ht40(sc, txd, ni);
+ r92c_tx_set_sgi(sc, txd, ni);
+ prot = ic->ic_htprotmode;
+ } else if (ic->ic_flags & IEEE80211_F_USEPROT)
+ prot = ic->ic_protmode;
+
+ /* XXX fix last comparison for A-MSDU (in net80211) */
+ /* XXX A-MPDU? */
+ if (m->m_pkthdr.len + IEEE80211_CRC_LEN >
+ vap->iv_rtsthreshold &&
+ vap->iv_rtsthreshold != IEEE80211_RTS_MAX)
+ prot = IEEE80211_PROT_RTSCTS;
+
+ /* NB: checks for ht40 / short bits (set above). */
+ if (prot != IEEE80211_PROT_NONE)
+ r92c_tx_protection(sc, txd, prot, ridx);
+ } else /* IEEE80211_FC0_TYPE_MGT */
+ qsel = R92C_TXDW1_QSEL_MGNT;
+ } else {
+ macid = RTWN_MACID_BC;
+ qsel = R92C_TXDW1_QSEL_MGNT;
+ }
+
+ txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL, qsel));
+
+ rtwn_r92c_tx_setup_macid(sc, txd, macid);
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, ridx));
+ /* Data rate fallback limit (max). */
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE_FB_LMT, 0x1f));
+ txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, uvp->id));
+ r92c_tx_raid(sc, txd, ni, ismcast);
+
+ /* Force this rate if needed. */
+ if (sc->sc_ratectl != RTWN_RATECTL_FW)
+ txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
+
+ if (!hasqos) {
+ /* Use HW sequence numbering for non-QoS frames. */
+ rtwn_r92c_tx_setup_hwseq(sc, txd);
+ txd->txdw4 |= htole32(SM(R92C_TXDW4_SEQ_SEL, uvp->id));
+ } else {
+ uint16_t seqno;
+
+ if (m->m_flags & M_AMPDU_MPDU) {
+ seqno = ni->ni_txseqs[tid];
+ /* NB: clear Fragment Number field. */
+ *(uint16_t *)wh->i_seq = 0;
+ ni->ni_txseqs[tid]++;
+ } else
+ seqno = M_SEQNO_GET(m) % IEEE80211_SEQ_RANGE;
+
+ /* Set sequence number. */
+ txd->txdseq = htole16(seqno);
+ }
+}
+
+void
+r92c_fill_tx_desc_raw(struct rtwn_softc *sc, struct ieee80211_node *ni,
+ struct mbuf *m, void *buf, const struct ieee80211_bpf_params *params)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct rtwn_vap *uvp = RTWN_VAP(vap);
+ struct ieee80211_frame *wh;
+ struct r92c_tx_desc *txd;
+ uint8_t ridx;
+ int ismcast;
+
+ /* XXX TODO: 11n checks, matching r92c_fill_tx_desc() */
+
+ wh = mtod(m, struct ieee80211_frame *);
+ ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
+ ridx = rate2ridx(params->ibp_rate0);
+
+ /* Fill Tx descriptor. */
+ txd = (struct r92c_tx_desc *)buf;
+ txd->flags0 |= R92C_FLAGS0_LSG | R92C_FLAGS0_FSG;
+ if (ismcast)
+ txd->flags0 |= R92C_FLAGS0_BMCAST;
+
+ if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) {
+ txd->txdw5 |= htole32(R92C_TXDW5_RTY_LMT_ENA);
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_RTY_LMT,
+ params->ibp_try0));
+ }
+ if (params->ibp_flags & IEEE80211_BPF_RTS)
+ r92c_tx_protection(sc, txd, IEEE80211_PROT_RTSCTS, ridx);
+ if (params->ibp_flags & IEEE80211_BPF_CTS)
+ r92c_tx_protection(sc, txd, IEEE80211_PROT_CTSONLY, ridx);
+
+ rtwn_r92c_tx_setup_macid(sc, txd, RTWN_MACID_BC);
+ txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT));
+
+ /* Set TX rate index. */
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, ridx));
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE_FB_LMT, 0x1f));
+ txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, uvp->id));
+ txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
+ r92c_tx_raid(sc, txd, ni, ismcast);
+
+ if (!IEEE80211_QOS_HAS_SEQ(wh)) {
+ /* Use HW sequence numbering for non-QoS frames. */
+ rtwn_r92c_tx_setup_hwseq(sc, txd);
+ txd->txdw4 |= htole32(SM(R92C_TXDW4_SEQ_SEL, uvp->id));
+ } else {
+ /* Set sequence number. */
+ txd->txdseq |= htole16(M_SEQNO_GET(m) % IEEE80211_SEQ_RANGE);
+ }
+}
+
+void
+r92c_fill_tx_desc_null(struct rtwn_softc *sc, void *buf, int is11b,
+ int qos, int id)
+{
+ struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
+
+ txd->flags0 = R92C_FLAGS0_FSG | R92C_FLAGS0_LSG | R92C_FLAGS0_OWN;
+ txd->txdw1 = htole32(
+ SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT));
+
+ txd->txdw4 = htole32(R92C_TXDW4_DRVRATE);
+ txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, id));
+ if (is11b) {
+ txd->txdw5 = htole32(SM(R92C_TXDW5_DATARATE,
+ RTWN_RIDX_CCK1));
+ } else {
+ txd->txdw5 = htole32(SM(R92C_TXDW5_DATARATE,
+ RTWN_RIDX_OFDM6));
+ }
+
+ if (!qos) {
+ rtwn_r92c_tx_setup_hwseq(sc, txd);
+ txd->txdw4 |= htole32(SM(R92C_TXDW4_SEQ_SEL, id));
+ }
+}
+
+uint8_t
+r92c_tx_radiotap_flags(const void *buf)
+{
+ const struct r92c_tx_desc *txd = buf;
+ uint8_t flags;
+
+ flags = 0;
+ if (txd->txdw4 & htole32(R92C_TXDW4_DATA_SHPRE))
+ flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+ if (txd->txdw5 & htole32(R92C_TXDW5_SGI))
+ flags |= IEEE80211_RADIOTAP_F_SHORTGI;
+ return (flags);
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h
new file mode 100644
index 00000000..037ac0e2
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h
@@ -0,0 +1,122 @@
+/*-
+ * 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 R92C_TX_DESC_H
+#define R92C_TX_DESC_H
+
+/* Tx MAC descriptor (common part). */
+struct r92c_tx_desc {
+ uint16_t pktlen;
+ uint8_t offset;
+ uint8_t flags0;
+#define R92C_FLAGS0_BMCAST 0x01
+#define R92C_FLAGS0_LSG 0x04
+#define R92C_FLAGS0_FSG 0x08
+#define R92C_FLAGS0_OWN 0x80
+
+ uint32_t txdw1;
+#define R92C_TXDW1_MACID_M 0x0000001f
+#define R92C_TXDW1_MACID_S 0
+#define R92C_TXDW1_AGGEN 0x00000020
+#define R92C_TXDW1_AGGBK 0x00000040
+
+#define R92C_TXDW1_QSEL_M 0x00001f00
+#define R92C_TXDW1_QSEL_S 8
+
+#define R92C_TXDW1_QSEL_BE 0x00 /* or 0x03 */
+#define R92C_TXDW1_QSEL_BK 0x01 /* or 0x02 */
+#define R92C_TXDW1_QSEL_VI 0x04 /* or 0x05 */
+#define R92C_TXDW1_QSEL_VO 0x06 /* or 0x07 */
+#define RTWN_MAX_TID 8
+
+#define R92C_TXDW1_QSEL_BEACON 0x10
+#define R92C_TXDW1_QSEL_MGNT 0x12
+
+#define R92C_TXDW1_RAID_M 0x000f0000
+#define R92C_TXDW1_RAID_S 16
+#define R92C_TXDW1_CIPHER_M 0x00c00000
+#define R92C_TXDW1_CIPHER_S 22
+#define R92C_TXDW1_CIPHER_NONE 0
+#define R92C_TXDW1_CIPHER_RC4 1
+#define R92C_TXDW1_CIPHER_AES 3
+#define R92C_TXDW1_PKTOFF_M 0x7c000000
+#define R92C_TXDW1_PKTOFF_S 26
+
+ uint32_t txdw2;
+#define R92C_TXDW2_CCX_RPT 0x00080000
+#define R92C_TXDW2_AMPDU_DEN_M 0x00700000
+#define R92C_TXDW2_AMPDU_DEN_S 20
+
+ uint16_t txdw3;
+ uint16_t txdseq;
+
+ uint32_t txdw4;
+#define R92C_TXDW4_RTSRATE_M 0x0000003f
+#define R92C_TXDW4_RTSRATE_S 0
+#define R92C_TXDW4_SEQ_SEL_M 0x00000040
+#define R92C_TXDW4_SEQ_SEL_S 6
+#define R92C_TXDW4_HWSEQ_EN 0x00000080
+#define R92C_TXDW4_DRVRATE 0x00000100
+#define R92C_TXDW4_CTS2SELF 0x00000800
+#define R92C_TXDW4_RTSEN 0x00001000
+#define R92C_TXDW4_HWRTSEN 0x00002000
+#define R92C_TXDW4_PORT_ID_M 0x00004000
+#define R92C_TXDW4_PORT_ID_S 14
+#define R92C_TXDW4_DATA_SCO_M 0x00300000
+#define R92C_TXDW4_DATA_SCO_S 20
+#define R92C_TXDW4_SCO_SCA 1
+#define R92C_TXDW4_SCO_SCB 2
+#define R92C_TXDW4_DATA_SHPRE 0x01000000
+#define R92C_TXDW4_DATA_BW40 0x02000000
+#define R92C_TXDW4_RTS_SHORT 0x04000000
+#define R92C_TXDW4_RTS_BW40 0x08000000
+#define R92C_TXDW4_RTS_SCO_M 0x30000000
+#define R92C_TXDW4_RTS_SCO_S 28
+
+ uint32_t txdw5;
+#define R92C_TXDW5_DATARATE_M 0x0000003f
+#define R92C_TXDW5_DATARATE_S 0
+#define R92C_TXDW5_SGI 0x00000040
+#define R92C_TXDW5_DATARATE_FB_LMT_M 0x00001f00
+#define R92C_TXDW5_DATARATE_FB_LMT_S 8
+#define R92C_TXDW5_RTSRATE_FB_LMT_M 0x0001e000
+#define R92C_TXDW5_RTSRATE_FB_LMT_S 13
+#define R92C_TXDW5_RTY_LMT_ENA 0x00020000
+#define R92C_TXDW5_RTY_LMT_M 0x00fc0000
+#define R92C_TXDW5_RTY_LMT_S 18
+#define R92C_TXDW5_AGGNUM_M 0xff000000
+#define R92C_TXDW5_AGGNUM_S 24
+
+ uint32_t txdw6;
+#define R92C_TXDW6_MAX_AGG_M 0x0000f800
+#define R92C_TXDW6_MAX_AGG_S 11
+} __packed __attribute__((aligned(4)));
+
+
+/* Rate adaptation modes. */
+#define R92C_RAID_11BGN 0
+#define R92C_RAID_11GN 1
+#define R92C_RAID_11BN 2
+#define R92C_RAID_11N 3
+#define R92C_RAID_11BG 4
+#define R92C_RAID_11G 5 /* "pure" 11g */
+#define R92C_RAID_11B 6
+
+#endif /* R92C_TX_DESC_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_var.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_var.h
new file mode 100644
index 00000000..c48318d9
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_var.h
@@ -0,0 +1,83 @@
+/*-
+ * 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 R92C_VAR_H
+#define R92C_VAR_H
+
+#include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
+
+struct r92c_softc {
+ uint8_t rs_flags;
+#define R92C_FLAG_ASSOCIATED 0x01
+
+ uint8_t chip;
+#define R92C_CHIP_92C 0x01
+#define R92C_CHIP_92C_1T2R 0x02
+#define R92C_CHIP_UMC_A_CUT 0x04
+
+#ifndef RTWN_WITHOUT_UCODE
+ struct callout rs_c2h_report;
+ int rs_c2h_timeout;
+ int rs_c2h_pending;
+ int rs_c2h_paused;
+#endif
+#define R92C_TX_PAUSED_THRESHOLD 20
+
+ void *rs_txpwr;
+ const void *rs_txagc;
+
+ uint8_t board_type;
+ uint8_t regulatory;
+ uint8_t crystalcap;
+ uint8_t pa_setting;
+
+ void (*rs_scan_start)(struct ieee80211com *);
+ void (*rs_scan_end)(struct ieee80211com *);
+
+ void (*rs_set_bw20)(struct rtwn_softc *, uint8_t);
+ void (*rs_get_txpower)(struct rtwn_softc *, int,
+ struct ieee80211_channel *, uint16_t[]);
+ void (*rs_set_gain)(struct rtwn_softc *, uint8_t);
+ void (*rs_tx_enable_ampdu)(void *, int);
+ void (*rs_tx_setup_hwseq)(void *);
+ void (*rs_tx_setup_macid)(void *, int);
+ void (*rs_set_name)(struct rtwn_softc *);
+
+ int rf_read_delay[3];
+ uint32_t rf_chnlbw[R92C_MAX_CHAINS];
+};
+#define R92C_SOFTC(_sc) ((struct r92c_softc *)((_sc)->sc_priv))
+
+#define rtwn_r92c_set_bw20(_sc, _chan) \
+ ((R92C_SOFTC(_sc)->rs_set_bw20)((_sc), (_chan)))
+#define rtwn_r92c_get_txpower(_sc, _chain, _c, _power) \
+ ((R92C_SOFTC(_sc)->rs_get_txpower)((_sc), (_chain), (_c), (_power)))
+#define rtwn_r92c_set_gain(_sc, _gain) \
+ ((R92C_SOFTC(_sc)->rs_set_gain)((_sc), (_gain)))
+#define rtwn_r92c_tx_enable_ampdu(_sc, _buf, _enable) \
+ ((R92C_SOFTC(_sc)->rs_tx_enable_ampdu)((_buf), (_enable)))
+#define rtwn_r92c_tx_setup_hwseq(_sc, _buf) \
+ ((R92C_SOFTC(_sc)->rs_tx_setup_hwseq)((_buf)))
+#define rtwn_r92c_tx_setup_macid(_sc, _buf, _id) \
+ ((R92C_SOFTC(_sc)->rs_tx_setup_macid)((_buf), (_id)))
+#define rtwn_r92c_set_name(_sc) \
+ ((R92C_SOFTC(_sc)->rs_set_name)((_sc)))
+
+#endif /* R92C_VAR_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu.h b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu.h
new file mode 100644
index 00000000..2486d7fa
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu.h
@@ -0,0 +1,56 @@
+/*-
+ * 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 RTL8192CU_H
+#define RTL8192CU_H
+
+#include <dev/rtwn/rtl8192c/r92c.h>
+
+
+/*
+ * Global definitions.
+ */
+#define R92CU_PUBQ_NPAGES 231
+#define R92CU_TX_PAGE_COUNT 248
+
+
+/*
+ * Function declarations.
+ */
+/* r92cu_init.c */
+void r92cu_init_bb(struct rtwn_softc *);
+int r92cu_power_on(struct rtwn_softc *);
+void r92cu_power_off(struct rtwn_softc *);
+void r92cu_init_intr(struct rtwn_softc *);
+void r92cu_init_tx_agg(struct rtwn_softc *);
+void r92cu_init_rx_agg(struct rtwn_softc *);
+void r92cu_post_init(struct rtwn_softc *);
+
+/* r92cu_led.c */
+void r92cu_set_led(struct rtwn_softc *, int, int);
+
+/* r92cu_rx.c */
+int r92cu_classify_intr(struct rtwn_softc *, void *, int);
+int r92cu_align_rx(int, int);
+
+/* r92cu_tx.c */
+void r92cu_dump_tx_desc(struct rtwn_softc *, const void *);
+
+#endif /* RTL8192CU_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
new file mode 100644
index 00000000..ce3f7a1a
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
@@ -0,0 +1,247 @@
+#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/if_rtwn_nop.h>
+
+#include <dev/rtwn/usb/rtwn_usb_var.h>
+
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+
+#include <dev/rtwn/rtl8192c/usb/r92cu.h>
+#include <dev/rtwn/rtl8192c/usb/r92cu_priv.h>
+#include <dev/rtwn/rtl8192c/usb/r92cu_reg.h>
+#include <dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h>
+
+
+static struct rtwn_r92c_txpwr r92c_txpwr;
+
+void r92cu_attach(struct rtwn_usb_softc *);
+
+static void
+r92cu_postattach(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+ struct ieee80211com *ic = &sc->sc_ic;
+
+ if (!(rs->chip & R92C_CHIP_92C) &&
+ rs->board_type == R92C_BOARD_TYPE_HIGHPA) {
+ sc->agc_prog = &rtl8188ru_agc[0];
+ sc->agc_size = nitems(rtl8188ru_agc);
+ rs->rs_txagc = &rtl8188ru_txagc[0];
+ } else {
+ sc->agc_prog = &rtl8192ce_agc[0];
+ sc->agc_size = nitems(rtl8192ce_agc);
+ rs->rs_txagc = &rtl8192cu_txagc[0];
+ }
+
+ if ((rs->chip & (R92C_CHIP_UMC_A_CUT | R92C_CHIP_92C)) ==
+ R92C_CHIP_UMC_A_CUT) {
+ sc->fwname = "rtwn-rtl8192cfwU";
+ } else {
+ sc->fwname = "rtwn-rtl8192cfwT";
+ }
+ sc->fwsig = 0x88c;
+
+ 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
+r92cu_set_name(struct rtwn_softc *sc)
+{
+ struct r92c_softc *rs = sc->sc_priv;
+
+ if (!(rs->chip & R92C_CHIP_92C)) {
+ if (rs->board_type == R92C_BOARD_TYPE_HIGHPA)
+ sc->name = "RTL8188RU";
+ else if (rs->board_type == R92C_BOARD_TYPE_MINICARD)
+ sc->name = "RTL8188CU-VAU";
+ else
+ sc->name = "RTL8188CUS";
+ } else
+ sc->name = "RTL8192CU";
+}
+
+static void
+r92cu_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 = &r92c_txpwr;
+
+ rs->rs_set_bw20 = r92c_set_bw20;
+ rs->rs_get_txpower = r92c_get_txpower;
+ rs->rs_set_gain = r92c_set_gain;
+ rs->rs_tx_enable_ampdu = r92c_tx_enable_ampdu;
+ rs->rs_tx_setup_hwseq = r92c_tx_setup_hwseq;
+ rs->rs_tx_setup_macid = r92c_tx_setup_macid;
+ rs->rs_set_name = r92cu_set_name;
+
+#ifndef RTWN_WITHOUT_UCODE
+ rs->rs_c2h_timeout = hz;
+
+ callout_init_mtx(&rs->rs_c2h_report, &sc->sc_mtx, 0);
+#endif
+
+ rs->rf_read_delay[0] = 10;
+ rs->rf_read_delay[1] = 100;
+ rs->rf_read_delay[2] = 10;
+
+ sc->sc_priv = rs;
+}
+
+static void
+r92cu_adj_devcaps(struct rtwn_softc *sc)
+{
+ /* XXX Currently broken / incomplete. */
+ sc->sc_ic.ic_caps &= ~IEEE80211_C_PMGT;
+}
+
+void
+r92cu_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_CAM_FIXED;
+
+ 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 = r92c_get_rssi_cck;
+ sc->sc_get_rssi_ofdm = r92c_get_rssi_ofdm;
+ sc->sc_classify_intr = r92cu_classify_intr;
+ sc->sc_handle_tx_report = rtwn_nop_softc_uint8_int;
+ sc->sc_handle_c2h_report = rtwn_nop_softc_uint8_int;
+ sc->sc_check_frame = rtwn_nop_int_softc_mbuf;
+ sc->sc_rf_read = r92c_rf_read;
+ sc->sc_rf_write = r92c_rf_write;
+ sc->sc_check_condition = r92c_check_condition;
+ sc->sc_efuse_postread = r92c_efuse_postread;
+ sc->sc_parse_rom = r92c_parse_rom;
+ sc->sc_set_led = r92cu_set_led;
+ sc->sc_power_on = r92cu_power_on;
+ sc->sc_power_off = r92cu_power_off;
+#ifndef RTWN_WITHOUT_UCODE
+ sc->sc_fw_reset = r92c_fw_reset;
+ sc->sc_fw_download_enable = r92c_fw_download_enable;
+#endif
+ sc->sc_set_page_size = r92c_set_page_size;
+ sc->sc_lc_calib = r92c_lc_calib;
+ sc->sc_iq_calib = r92c_iq_calib; /* XXX TODO */
+ sc->sc_read_chipid_vendor = r92c_read_chipid_vendor;
+ sc->sc_adj_devcaps = r92cu_adj_devcaps;
+ sc->sc_vap_preattach = rtwn_nop_softc_vap;
+ sc->sc_postattach = r92cu_postattach;
+ sc->sc_detach_private = r92c_detach_private;
+ sc->sc_set_media_status = r92c_joinbss_rpt;
+#ifndef RTWN_WITHOUT_UCODE
+ sc->sc_set_rsvd_page = r92c_set_rsvd_page;
+ sc->sc_set_pwrmode = r92c_set_pwrmode;
+ sc->sc_set_rssi = r92c_set_rssi;
+#endif
+ sc->sc_beacon_init = r92c_beacon_init;
+ sc->sc_beacon_enable = r92c_beacon_enable;
+ sc->sc_beacon_set_rate = rtwn_nop_void_int;
+ sc->sc_beacon_select = rtwn_nop_softc_int;
+ sc->sc_temp_measure = r92c_temp_measure;
+ sc->sc_temp_read = r92c_temp_read;
+ sc->sc_init_tx_agg = r92cu_init_tx_agg;
+ sc->sc_init_rx_agg = r92cu_init_rx_agg;
+ sc->sc_init_ampdu = r92c_init_ampdu;
+ sc->sc_init_intr = r92cu_init_intr;
+ sc->sc_init_edca = r92c_init_edca;
+ sc->sc_init_bb = r92cu_init_bb;
+ sc->sc_init_rf = r92c_init_rf;
+ sc->sc_init_antsel = r92c_init_antsel;
+ sc->sc_post_init = r92cu_post_init;
+ sc->sc_init_bcnq1_boundary = rtwn_nop_int_softc;
+
+ sc->mac_prog = &rtl8192cu_mac[0];
+ sc->mac_size = nitems(rtl8192cu_mac);
+ sc->bb_prog = &rtl8192cu_bb[0];
+ sc->bb_size = nitems(rtl8192cu_bb);
+ sc->rf_prog = &rtl8192c_rf[0];
+
+ sc->page_count = R92CU_TX_PAGE_COUNT;
+ sc->pktbuf_count = R92C_TXPKTBUF_COUNT;
+
+ sc->ackto = 0x40;
+ sc->npubqpages = R92CU_PUBQ_NPAGES;
+ sc->page_size = R92C_TX_PAGE_SIZE;
+
+ sc->txdesc_len = sizeof(struct r92cu_tx_desc);
+ sc->efuse_maxlen = R92C_EFUSE_MAX_LEN;
+ sc->efuse_maplen = R92C_EFUSE_MAP_LEN;
+ sc->rx_dma_size = R92C_RX_DMA_BUFFER_SIZE;
+
+ sc->macid_limit = R92C_MACID_MAX + 1;
+ sc->cam_entry_limit = R92C_CAM_ENTRY_COUNT;
+ sc->fwsize_limit = R92C_MAX_FW_SIZE;
+ sc->temp_delta = R92C_CALIB_THRESHOLD;
+
+ sc->bcn_status_reg[0] = R92C_TDECTRL;
+ sc->bcn_status_reg[1] = R92C_TDECTRL;
+ sc->rcr = 0;
+
+ r92cu_attach_private(sc);
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_init.c b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_init.c
new file mode 100644
index 00000000..44b3a509
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_init.c
@@ -0,0 +1,393 @@
+#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/usb/rtwn_usb_var.h>
+
+#include <dev/rtwn/rtl8192c/r92c_var.h>
+
+#include <dev/rtwn/rtl8192c/usb/r92cu.h>
+#include <dev/rtwn/rtl8192c/usb/r92cu_reg.h>
+
+
+void
+r92cu_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_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
+
+ 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);
+
+ rtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
+ rtwn_write_1(sc, 0x15, 0xe9);
+ rtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
+
+ r92c_init_bb_common(sc);
+}
+
+int
+r92cu_power_on(struct rtwn_softc *sc)
+{
+#define RTWN_CHK(res) do { \
+ if (res != 0) \
+ return (EIO); \
+} while(0)
+ uint32_t reg;
+ int ntries;
+
+ /* Wait for autoload done bit. */
+ for (ntries = 0; ntries < 5000; ntries++) {
+ if (rtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN)
+ break;
+ rtwn_delay(sc, 10);
+ }
+ if (ntries == 5000) {
+ device_printf(sc->sc_dev,
+ "timeout waiting for chip autoload\n");
+ return (ETIMEDOUT);
+ }
+
+ /* Unlock ISO/CLK/Power control register. */
+ RTWN_CHK(rtwn_write_1(sc, R92C_RSV_CTRL, 0));
+
+ /* Move SPS into PWM mode. */
+ RTWN_CHK(rtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b));
+
+ /* just in case if power_off() was not properly executed. */
+ rtwn_delay(sc, 100);
+
+ reg = rtwn_read_1(sc, R92C_LDOV12D_CTRL);
+ if (!(reg & R92C_LDOV12D_CTRL_LDV12_EN)) {
+ RTWN_CHK(rtwn_write_1(sc, R92C_LDOV12D_CTRL,
+ reg | R92C_LDOV12D_CTRL_LDV12_EN));
+
+ rtwn_delay(sc, 100);
+
+ RTWN_CHK(rtwn_setbits_1(sc, R92C_SYS_ISO_CTRL,
+ R92C_SYS_ISO_CTRL_MD2PP, 0));
+ }
+
+ /* Auto enable WLAN. */
+ 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) {
+ device_printf(sc->sc_dev,
+ "timeout waiting for MAC auto ON\n");
+ return (ETIMEDOUT);
+ }
+
+ /* Enable radio, GPIO and LED functions. */
+ RTWN_CHK(rtwn_write_2(sc, R92C_APS_FSMCO,
+ R92C_APS_FSMCO_AFSM_HSUS |
+ R92C_APS_FSMCO_PDN_EN |
+ R92C_APS_FSMCO_PFM_ALDN));
+
+ /* Release RF digital isolation. */
+ RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_SYS_ISO_CTRL,
+ R92C_SYS_ISO_CTRL_DIOR, 0, 1));
+
+ /* Initialize MAC. */
+ RTWN_CHK(rtwn_setbits_1(sc, R92C_APSD_CTRL,
+ R92C_APSD_CTRL_OFF, 0));
+ for (ntries = 0; ntries < 1000; ntries++) {
+ if (!(rtwn_read_1(sc, R92C_APSD_CTRL) &
+ R92C_APSD_CTRL_OFF_STATUS))
+ break;
+ rtwn_delay(sc, 50);
+ }
+ if (ntries == 1000) {
+ device_printf(sc->sc_dev,
+ "timeout waiting for MAC initialization\n");
+ return (ETIMEDOUT);
+ }
+
+ /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
+ 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));
+
+ RTWN_CHK(rtwn_write_1(sc, 0xfe10, 0x19));
+
+ return (0);
+#undef RTWN_CHK
+}
+
+void
+r92cu_power_off(struct rtwn_softc *sc)
+{
+#ifndef RTWN_WITHOUT_UCODE
+ struct r92c_softc *rs = sc->sc_priv;
+#endif
+ uint32_t reg;
+ int error;
+
+ /* Deinit C2H event handler. */
+#ifndef RTWN_WITHOUT_UCODE
+ callout_stop(&rs->rs_c2h_report);
+ rs->rs_c2h_paused = 0;
+ rs->rs_c2h_pending = 0;
+ rs->rs_c2h_timeout = hz;
+#endif
+
+ /* Block all Tx queues. */
+ error = rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
+ if (error == ENXIO) /* hardware gone */
+ return;
+
+ /* Disable RF */
+ rtwn_rf_write(sc, 0, 0, 0);
+
+ rtwn_write_1(sc, R92C_APSD_CTRL, R92C_APSD_CTRL_OFF);
+
+ /* Reset BB state machine */
+ rtwn_write_1(sc, R92C_SYS_FUNC_EN,
+ R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA |
+ R92C_SYS_FUNC_EN_BB_GLB_RST);
+ rtwn_write_1(sc, R92C_SYS_FUNC_EN,
+ R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA);
+
+ /*
+ * Reset digital sequence
+ */
+#ifndef RTWN_WITHOUT_UCODE
+ if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY) {
+ /* Reset MCU ready status */
+ rtwn_write_1(sc, R92C_MCUFWDL, 0);
+
+ /* If firmware in ram code, do reset */
+ r92c_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN);
+ }
+#endif
+
+ /* Reset MAC and Enable 8051 */
+ rtwn_write_1(sc, R92C_SYS_FUNC_EN + 1,
+ (R92C_SYS_FUNC_EN_CPUEN |
+ R92C_SYS_FUNC_EN_ELDR |
+ R92C_SYS_FUNC_EN_HWPDN) >> 8);
+
+ /* Reset MCU ready status */
+ rtwn_write_1(sc, R92C_MCUFWDL, 0);
+
+ /* Disable MAC clock */
+ rtwn_write_2(sc, R92C_SYS_CLKR,
+ R92C_SYS_CLKR_ANAD16V_EN |
+ R92C_SYS_CLKR_ANA8M |
+ R92C_SYS_CLKR_LOADER_EN |
+ R92C_SYS_CLKR_80M_SSC_DIS |
+ R92C_SYS_CLKR_SYS_EN |
+ R92C_SYS_CLKR_RING_EN |
+ 0x4000);
+
+ /* Disable AFE PLL */
+ rtwn_write_1(sc, R92C_AFE_PLL_CTRL, 0x80);
+
+ /* Gated AFE DIG_CLOCK */
+ rtwn_write_2(sc, R92C_AFE_XTAL_CTRL, 0x880F);
+
+ /* Isolated digital to PON */
+ rtwn_write_1(sc, R92C_SYS_ISO_CTRL,
+ R92C_SYS_ISO_CTRL_MD2PP |
+ R92C_SYS_ISO_CTRL_PA2PCIE |
+ R92C_SYS_ISO_CTRL_PD2CORE |
+ R92C_SYS_ISO_CTRL_IP2MAC |
+ R92C_SYS_ISO_CTRL_DIOP |
+ R92C_SYS_ISO_CTRL_DIOE);
+
+ /*
+ * Pull GPIO PIN to balance level and LED control
+ */
+ /* 1. Disable GPIO[7:0] */
+ rtwn_write_2(sc, R92C_GPIO_IOSEL, 0x0000);
+
+ reg = rtwn_read_4(sc, R92C_GPIO_PIN_CTRL) & ~0x0000ff00;
+ reg |= ((reg << 8) & 0x0000ff00) | 0x00ff0000;
+ rtwn_write_4(sc, R92C_GPIO_PIN_CTRL, reg);
+
+ /* Disable GPIO[10:8] */
+ rtwn_write_1(sc, R92C_MAC_PINMUX_CFG, 0x00);
+
+ reg = rtwn_read_2(sc, R92C_GPIO_IO_SEL) & ~0x00f0;
+ reg |= (((reg & 0x000f) << 4) | 0x0780);
+ rtwn_write_2(sc, R92C_GPIO_IO_SEL, reg);
+
+ /* Disable LED0 & 1 */
+ rtwn_write_2(sc, R92C_LEDCFG0, 0x8080);
+
+ /*
+ * Reset digital sequence
+ */
+ /* Disable ELDR clock */
+ rtwn_write_2(sc, R92C_SYS_CLKR,
+ R92C_SYS_CLKR_ANAD16V_EN |
+ R92C_SYS_CLKR_ANA8M |
+ R92C_SYS_CLKR_LOADER_EN |
+ R92C_SYS_CLKR_80M_SSC_DIS |
+ R92C_SYS_CLKR_SYS_EN |
+ R92C_SYS_CLKR_RING_EN |
+ 0x4000);
+
+ /* Isolated ELDR to PON */
+ rtwn_write_1(sc, R92C_SYS_ISO_CTRL + 1,
+ (R92C_SYS_ISO_CTRL_DIOR |
+ R92C_SYS_ISO_CTRL_PWC_EV12V) >> 8);
+
+ /*
+ * Disable analog sequence
+ */
+ /* Disable A15 power */
+ rtwn_write_1(sc, R92C_LDOA15_CTRL, R92C_LDOA15_CTRL_OBUF);
+ /* Disable digital core power */
+ rtwn_setbits_1(sc, R92C_LDOV12D_CTRL,
+ R92C_LDOV12D_CTRL_LDV12_EN, 0);
+
+ /* Enter PFM mode */
+ rtwn_write_1(sc, R92C_SPS0_CTRL, 0x23);
+
+ /* Set USB suspend */
+ rtwn_write_2(sc, R92C_APS_FSMCO,
+ R92C_APS_FSMCO_APDM_HOST |
+ R92C_APS_FSMCO_AFSM_HSUS |
+ R92C_APS_FSMCO_PFM_ALDN);
+
+ /* Lock ISO/CLK/Power control register. */
+ rtwn_write_1(sc, R92C_RSV_CTRL, 0x0E);
+}
+
+void
+r92cu_init_intr(struct rtwn_softc *sc)
+{
+ rtwn_write_4(sc, R92C_HISR, 0xffffffff);
+ rtwn_write_4(sc, R92C_HIMR, 0xffffffff);
+}
+
+void
+r92cu_init_tx_agg(struct rtwn_softc *sc)
+{
+ struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc);
+ uint32_t reg;
+
+ reg = rtwn_read_4(sc, R92C_TDECTRL);
+ reg = RW(reg, R92C_TDECTRL_BLK_DESC_NUM, uc->tx_agg_desc_num);
+ rtwn_write_4(sc, R92C_TDECTRL, reg);
+}
+
+void
+r92cu_init_rx_agg(struct rtwn_softc *sc)
+{
+
+ /* Rx aggregation (DMA & USB). */
+ rtwn_setbits_1(sc, R92C_TRXDMA_CTRL, 0,
+ R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
+ rtwn_setbits_1(sc, R92C_USB_SPECIAL_OPTION, 0,
+ R92C_USB_SPECIAL_OPTION_AGG_EN);
+
+ /* XXX dehardcode */
+ rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
+ rtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
+ rtwn_write_1(sc, R92C_USB_AGG_TH, 8);
+ rtwn_write_1(sc, R92C_USB_AGG_TO, 6);
+}
+
+void
+r92cu_post_init(struct rtwn_softc *sc)
+{
+
+ /* Perform LO and IQ calibrations. */
+ r92c_iq_calib(sc);
+ /* Perform LC calibration. */
+ r92c_lc_calib(sc);
+
+ /* Fix USB interference issue. */
+ rtwn_write_1(sc, 0xfe40, 0xe0);
+ rtwn_write_1(sc, 0xfe41, 0x8d);
+ rtwn_write_1(sc, 0xfe42, 0x80);
+
+ r92c_pa_bias_init(sc);
+
+ /* Fix for lower temperature. */
+ rtwn_write_1(sc, 0x15, 0xe9);
+
+#ifndef RTWN_WITHOUT_UCODE
+ if (sc->sc_flags & RTWN_FW_LOADED) {
+ struct r92c_softc *rs = sc->sc_priv;
+
+ if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) {
+ /* XXX firmware RA does not work yet */
+ sc->sc_ratectl = RTWN_RATECTL_NET80211;
+ } else
+ sc->sc_ratectl = sc->sc_ratectl_sysctl;
+
+ /* Start C2H event handling. */
+ callout_reset(&rs->rs_c2h_report, rs->rs_c2h_timeout,
+ r92c_handle_c2h_report, sc);
+ } else
+#endif
+ sc->sc_ratectl = RTWN_RATECTL_NONE;
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_led.c b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_led.c
new file mode 100644
index 00000000..4db6b167
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_led.c
@@ -0,0 +1,68 @@
+#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/rtl8192c/r92c_reg.h>
+
+#include <dev/rtwn/rtl8192c/usb/r92cu.h>
+
+
+void
+r92cu_set_led(struct rtwn_softc *sc, int led, int on)
+{
+ uint8_t reg;
+
+ if (led == RTWN_LED_LINK) {
+ reg = rtwn_read_1(sc, R92C_LEDCFG0) & 0x70;
+ if (!on)
+ reg |= R92C_LEDCFG0_DIS;
+ rtwn_write_1(sc, R92C_LEDCFG0, reg);
+ sc->ledlink = on; /* Save LED state. */
+ }
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_priv.h b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_priv.h
new file mode 100644
index 00000000..8e3203f0
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_priv.h
@@ -0,0 +1,322 @@
+/*-
+ * 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 R92CU_PRIV_H
+#define R92CU_PRIV_H
+
+#include <dev/rtwn/rtl8192c/r92c_priv.h>
+
+
+/*
+ * MAC initialization values.
+ */
+static const struct rtwn_mac_prog rtl8192cu_mac[] = {
+ { 0x420, 0x80 }, { 0x423, 0x00 }, { 0x430, 0x00 }, { 0x431, 0x00 },
+ { 0x432, 0x00 }, { 0x433, 0x01 }, { 0x434, 0x04 }, { 0x435, 0x05 },
+ { 0x436, 0x06 }, { 0x437, 0x07 }, { 0x438, 0x00 }, { 0x439, 0x00 },
+ { 0x43a, 0x00 }, { 0x43b, 0x01 }, { 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 }, { 0x462, 0x08 },
+ { 0x463, 0x03 }, { 0x4c8, 0xff }, { 0x4c9, 0x08 }, { 0x4cc, 0xff },
+ { 0x4cd, 0xff }, { 0x4ce, 0x01 }, { 0x500, 0x26 }, { 0x501, 0xa2 },
+ { 0x502, 0x2f }, { 0x503, 0x00 }, { 0x504, 0x28 }, { 0x505, 0xa3 },
+ { 0x506, 0x5e }, { 0x507, 0x00 }, { 0x508, 0x2b }, { 0x509, 0xa4 },
+ { 0x50a, 0x5e }, { 0x50b, 0x00 }, { 0x50c, 0x4f }, { 0x50d, 0xa4 },
+ { 0x50e, 0x00 }, { 0x50f, 0x00 }, { 0x512, 0x1c }, { 0x514, 0x0a },
+ { 0x515, 0x10 }, { 0x516, 0x0a }, { 0x517, 0x10 }, { 0x51a, 0x16 },
+ { 0x524, 0x0f }, { 0x525, 0x4f }, { 0x546, 0x40 }, { 0x547, 0x00 },
+ { 0x550, 0x10 }, { 0x551, 0x10 }, { 0x559, 0x02 }, { 0x55a, 0x02 },
+ { 0x55d, 0xff }, { 0x605, 0x30 }, { 0x608, 0x0e }, { 0x609, 0x2a },
+ { 0x652, 0x20 }, { 0x63c, 0x0a }, { 0x63d, 0x0e }, { 0x63e, 0x0a },
+ { 0x63f, 0x0e }, { 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 rtl8192cu_bb_regs0_88ru[] = {
+ 0x024, 0x028, 0x040, 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, 0xa00, 0xa04, 0xa08, 0xa0c, 0xa10, 0xa14, 0xa18,
+ 0xa1c, 0xa20, 0xa24, 0xa28, 0xa2c, 0xa70, 0xa74, 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
+}, rtl8192cu_bb_regs0[] = {
+ 0x024, 0x028, 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, 0xa00, 0xa04, 0xa08, 0xa0c, 0xa10, 0xa14, 0xa18, 0xa1c,
+ 0xa20, 0xa24, 0xa28, 0xa2c, 0xa70, 0xa74, 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
+}, rtl8192cu_bb_regs1[] = {
+ 0xc74, 0xc78, 0xc7c, 0xc80, 0xc84, 0xc88
+}, rtl8192cu_bb_regs2[] = {
+ 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
+}, rtl8192cu_bb_regs5_88ru[] = {
+ 0xe60, 0xe68, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,
+ 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec, 0xee8,
+ 0xf14, 0xf4c, 0xf00
+};
+
+static const uint32_t rtl8192cu_bb_vals0_88cu[] = {
+ 0x0011800d, 0x00ffdb83, 0x80040000, 0x00000001, 0x0000fc00,
+ 0x0000000a, 0x10005388, 0x020c3d10, 0x02200385, 0x00000000,
+ 0x01000100, 0x00390004, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x569a569a,
+ 0x001b25a4, 0x66e60230, 0x061f0130, 0x00000000, 0x32323200,
+ 0x07000700, 0x22004000, 0x00000808, 0x00000000, 0xc0083070,
+ 0x000004d5, 0x00000000, 0xccc000c0, 0x00000800, 0xfffffffe,
+ 0x40302010, 0x00706050, 0x00000000, 0x00000023, 0x00000000,
+ 0x81121111, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e68120f,
+ 0x9500bb78, 0x11144028, 0x00881117, 0x89140f00, 0x1a1b0000,
+ 0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
+ 0x48071d40, 0x03a05611, 0x000000e4, 0x6c6c6c6c, 0x08800000,
+ 0x40000100, 0x08800000, 0x40000100, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x69e9ac44, 0x469652cf, 0x49795994,
+ 0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f,
+ 0x6954341e, 0x43bc0094, 0x6954341e, 0x433c0094, 0x00000000,
+ 0x5116848b, 0x47c00bff, 0x00000036, 0x2c7f000d
+}, rtl8192cu_bb_vals0_88ru[] = {
+ 0x0011800d, 0x00ffdb83, 0x000c0004, 0x80040000, 0x00000001,
+ 0x0000fc00, 0x0000000a, 0x10005388, 0x020c3d10, 0x02200385,
+ 0x00000000, 0x01000100, 0x00390204, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x569a569a, 0x001b25a4, 0x66e60230, 0x061f0130, 0x00000000,
+ 0x32323200, 0x03000300, 0x22004000, 0x00000808, 0x00ffc3f1,
+ 0xc0083070, 0x000004d5, 0x00000000, 0xccc000c0, 0x00000800,
+ 0xfffffffe, 0x40302010, 0x00706050, 0x00000000, 0x00000023,
+ 0x00000000, 0x81121111, 0x00d047c8, 0x80ff000c, 0x8c838300,
+ 0x2e68120f, 0x9500bb78, 0x11144028, 0x00881117, 0x89140f00,
+ 0x15160000, 0x070b0f12, 0x00000104, 0x00d30000, 0x101fbf00,
+ 0x00000007, 0x48071d40, 0x03a05611, 0x000000e4, 0x6c6c6c6c,
+ 0x08800000, 0x40000100, 0x08800000, 0x40000100, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x69e9ac44, 0x469652cf,
+ 0x49795994, 0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107,
+ 0x007f037f, 0x6954342e, 0x43bc0094, 0x6954342f, 0x433c0094,
+ 0x00000000, 0x5116848b, 0x47c00bff, 0x00000036, 0x2c56000d
+}, rtl8192cu_bb_vals0_92ce_92cu[] = {
+ 0x0011800d, 0x00ffdb83, 0x80040002, 0x00000003, 0x0000fc00,
+ 0x0000000a, 0x10005388, 0x020c3d10, 0x02200385, 0x00000000,
+ 0x01000100, 0x00390004, 0x01000100, 0x00390004, 0x27272727,
+ 0x27272727, 0x27272727, 0x27272727, 0x00010000, 0x00010000,
+ 0x27272727, 0x27272727, 0x00000000, 0x00000000, 0x569a569a,
+ 0x0c1b25a4, 0x66e60230, 0x061f0130, 0x27272727, 0x2b2b2b27,
+ 0x07000700, 0x22184000, 0x08080808, 0x00000000, 0xc0083070,
+ 0x000004d5, 0x00000000, 0xcc0000c0, 0x00000800, 0xfffffffe,
+ 0x40302010, 0x00706050, 0x00000000, 0x00000023, 0x00000000,
+ 0x81121313, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e68120f,
+ 0x9500bb78, 0x11144028, 0x00881117, 0x89140f00, 0x1a1b0000,
+ 0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
+ 0x48071d40, 0x03a05633, 0x000000e4, 0x6c6c6c6c, 0x08800000,
+ 0x40000100, 0x08800000, 0x40000100, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x69e9ac44, 0x469652cf, 0x49795994,
+ 0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f,
+ 0x6954341e, 0x43bc0094, 0x6954341e, 0x433c0094, 0x00000000,
+ 0x5116848b, 0x47c00bff, 0x00000036, 0x2c7f000d
+}, rtl8192cu_bb_vals1_88ru[] = {
+ 0x018610db, 0x0000001f, 0x00b91612, 0x24000090, 0x20f60000,
+ 0x24000090
+}, rtl8192cu_bb_vals1_92cu[] = {
+ 0x0186115b, 0x0000001f, 0x00b99612, 0x40000100, 0x20f60000,
+ 0x40000100
+}, rtl8192cu_bb_vals1_88cu_92ce[] = {
+ 0x018610db, 0x0000001f, 0x00b91612, 0x40000100, 0x20f60000,
+ 0x40000100
+}, rtl8192cu_bb_vals2[] = {
+ 0x20200000, 0x00121820, 0x00000000, 0x00121820, 0x00007f7f,
+ 0x00000000, 0x00000080, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x28000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x64b22427,
+ 0x00766932, 0x00222222, 0x00000000, 0x37644302, 0x2f97d40c,
+ 0x00080740
+}, rtl8192cu_bb_vals5_88cu[] = {
+ 0x00000008, 0x001b25a4, 0x631b25a0, 0x631b25a0, 0x081b25a0,
+ 0x081b25a0, 0x081b25a0, 0x081b25a0, 0x631b25a0, 0x081b25a0,
+ 0x631b25a0, 0x631b25a0, 0x631b25a0, 0x631b25a0, 0x001b25a0,
+ 0x001b25a0, 0x6b1b25a0, 0x00000003, 0x00000000, 0x00000300
+}, rtl8192cu_bb_vals5_88ru[] = {
+ 0x00000010, 0x001b25a4, 0x631b25a0, 0x631b25a0, 0x081b25a0,
+ 0x081b25a0, 0x081b25a0, 0x081b25a0, 0x631b25a0, 0x081b25a0,
+ 0x631b25a0, 0x631b25a0, 0x631b25a0, 0x631b25a0, 0x001b25a0,
+ 0x001b25a0, 0x6b1b25a0, 0x31555448, 0x00000003, 0x00000000,
+ 0x00000300
+};
+
+static const struct rtwn_bb_prog rtl8192cu_bb[] = {
+ /* RTL8188CE / RTL8188CU. */
+ {
+ nitems(rtl8192cu_bb_regs0),
+ rtl8192cu_bb_regs0,
+ rtl8192cu_bb_vals0_88cu,
+ { R92C_COND_RTL8188CU | R92C_COND_RTL8188CE },
+ /* RTL8188RU. */
+ &(const struct rtwn_bb_prog){
+ nitems(rtl8192cu_bb_regs0_88ru),
+ rtl8192cu_bb_regs0_88ru,
+ rtl8192cu_bb_vals0_88ru,
+ { R92C_COND_RTL8188RU },
+ /* Others. */
+ &(const struct rtwn_bb_prog){
+ nitems(rtl8192cu_bb_regs0),
+ rtl8192cu_bb_regs0,
+ rtl8192cu_bb_vals0_92ce_92cu,
+ { 0 },
+ NULL
+ }
+ }
+ },
+ /* RTL8188RU. */
+ {
+ nitems(rtl8192cu_bb_regs1),
+ rtl8192cu_bb_regs1,
+ rtl8192cu_bb_vals1_88ru,
+ { R92C_COND_RTL8188RU },
+ /* RTL8192CU. */
+ &(const struct rtwn_bb_prog){
+ nitems(rtl8192cu_bb_regs1),
+ rtl8192cu_bb_regs1,
+ rtl8192cu_bb_vals1_92cu,
+ { R92C_COND_RTL8192CU },
+ /* Others. */
+ &(const struct rtwn_bb_prog){
+ nitems(rtl8192cu_bb_regs1),
+ rtl8192cu_bb_regs1,
+ rtl8192cu_bb_vals1_88cu_92ce,
+ { 0 },
+ NULL
+ }
+ }
+ },
+ {
+ nitems(rtl8192cu_bb_regs2),
+ rtl8192cu_bb_regs2,
+ rtl8192cu_bb_vals2,
+ { 0 },
+ NULL
+ },
+ /* RTL8192CE / RTL8192CU. */
+ {
+ nitems(rtl8192c_bb_regs3),
+ rtl8192c_bb_regs3,
+ rtl8192c_bb_vals3_92ce_92cu,
+ { R92C_COND_RTL8192C },
+ /* Others. */
+ &(const struct rtwn_bb_prog){
+ nitems(rtl8192c_bb_regs3),
+ rtl8192c_bb_regs3,
+ rtl8192c_bb_vals3_88cu_88ru,
+ { 0 },
+ NULL
+ }
+ },
+ {
+ nitems(rtl8192c_bb_regs4),
+ rtl8192c_bb_regs4,
+ rtl8192c_bb_vals4,
+ { 0 },
+ NULL
+ },
+ /* RTL8188CE / RTL8188CU. */
+ {
+ nitems(rtl8192c_bb_regs5),
+ rtl8192c_bb_regs5,
+ rtl8192cu_bb_vals5_88cu,
+ { R92C_COND_RTL8188CU | R92C_COND_RTL8188CE },
+ /* RTL8188RU. */
+ &(const struct rtwn_bb_prog){
+ nitems(rtl8192cu_bb_regs5_88ru),
+ rtl8192cu_bb_regs5_88ru,
+ rtl8192cu_bb_vals5_88ru,
+ { R92C_COND_RTL8188RU },
+ /* Others. */
+ &(const struct rtwn_bb_prog){
+ nitems(rtl8192c_bb_regs5),
+ rtl8192c_bb_regs5,
+ rtl8192c_bb_vals5_92ce_92cu,
+ { 0 },
+ NULL
+ }
+ }
+ }
+};
+
+
+static const uint32_t rtl8188ru_agc_vals[] = {
+ 0x7b000001, 0x7b010001, 0x7b020001, 0x7b030001, 0x7b040001,
+ 0x7b050001, 0x7b060001, 0x7b070001, 0x7b080001, 0x7a090001,
+ 0x790a0001, 0x780b0001, 0x770c0001, 0x760d0001, 0x750e0001,
+ 0x740f0001, 0x73100001, 0x72110001, 0x71120001, 0x70130001,
+ 0x6f140001, 0x6e150001, 0x6d160001, 0x6c170001, 0x6b180001,
+ 0x6a190001, 0x691a0001, 0x681b0001, 0x671c0001, 0x661d0001,
+ 0x651e0001, 0x641f0001, 0x63200001, 0x62210001, 0x61220001,
+ 0x60230001, 0x46240001, 0x45250001, 0x44260001, 0x43270001,
+ 0x42280001, 0x41290001, 0x402a0001, 0x262b0001, 0x252c0001,
+ 0x242d0001, 0x232e0001, 0x222f0001, 0x21300001, 0x20310001,
+ 0x06320001, 0x05330001, 0x04340001, 0x03350001, 0x02360001,
+ 0x01370001, 0x00380001, 0x00390001, 0x003a0001, 0x003b0001,
+ 0x003c0001, 0x003d0001, 0x003e0001, 0x003f0001, 0x7b400001,
+ 0x7b410001, 0x7b420001, 0x7b430001, 0x7b440001, 0x7b450001,
+ 0x7b460001, 0x7b470001, 0x7b480001, 0x7a490001, 0x794a0001,
+ 0x784b0001, 0x774c0001, 0x764d0001, 0x754e0001, 0x744f0001,
+ 0x73500001, 0x72510001, 0x71520001, 0x70530001, 0x6f540001,
+ 0x6e550001, 0x6d560001, 0x6c570001, 0x6b580001, 0x6a590001,
+ 0x695a0001, 0x685b0001, 0x675c0001, 0x665d0001, 0x655e0001,
+ 0x645f0001, 0x63600001, 0x62610001, 0x61620001, 0x60630001,
+ 0x46640001, 0x45650001, 0x44660001, 0x43670001, 0x42680001,
+ 0x41690001, 0x406a0001, 0x266b0001, 0x256c0001, 0x246d0001,
+ 0x236e0001, 0x226f0001, 0x21700001, 0x20710001, 0x06720001,
+ 0x05730001, 0x04740001, 0x03750001, 0x02760001, 0x01770001,
+ 0x00780001, 0x00790001, 0x007a0001, 0x007b0001, 0x007c0001,
+ 0x007d0001, 0x007e0001, 0x007f0001, 0x3800001e, 0x3801001e,
+ 0x3802001e, 0x3803001e, 0x3804001e, 0x3805001e, 0x3806001e,
+ 0x3807001e, 0x3808001e, 0x3c09001e, 0x3e0a001e, 0x400b001e,
+ 0x440c001e, 0x480d001e, 0x4c0e001e, 0x500f001e, 0x5210001e,
+ 0x5611001e, 0x5a12001e, 0x5e13001e, 0x6014001e, 0x6015001e,
+ 0x6016001e, 0x6217001e, 0x6218001e, 0x6219001e, 0x621a001e,
+ 0x621b001e, 0x621c001e, 0x621d001e, 0x621e001e, 0x621f001e
+};
+
+static const struct rtwn_agc_prog rtl8188ru_agc[] = {
+ {
+ nitems(rtl8188ru_agc_vals),
+ rtl8188ru_agc_vals,
+ { 0 },
+ NULL
+ }
+};
+
+#endif /* R92CU_PRIV_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_reg.h b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_reg.h
new file mode 100644
index 00000000..a9db29cc
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_reg.h
@@ -0,0 +1,65 @@
+/*-
+ * 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 R92CU_REG_H
+#define R92CU_REG_H
+
+#include <dev/rtwn/rtl8192c/r92c_reg.h>
+
+
+/*
+ * MAC registers.
+ */
+/* System Configuration. */
+#define R92C_USB_SIE_INTF 0x0e0
+
+
+/*
+ * USB registers.
+ */
+#define R92C_USB_SUSPEND 0xfe10
+#define R92C_USB_INFO 0xfe17
+#define R92C_USB_SPECIAL_OPTION 0xfe55
+#define R92C_USB_HCPWM 0xfe57
+#define R92C_USB_HRPWM 0xfe58
+#define R92C_USB_DMA_AGG_TO 0xfe5b
+#define R92C_USB_AGG_TO 0xfe5c
+#define R92C_USB_AGG_TH 0xfe5d
+#define R92C_USB_VID 0xfe60
+#define R92C_USB_PID 0xfe62
+#define R92C_USB_OPTIONAL 0xfe64
+#define R92C_USB_EP 0xfe65
+#define R92C_USB_PHY 0xfe68
+#define R92C_USB_MAC_ADDR 0xfe70
+#define R92C_USB_STRING 0xfe80
+
+/* Bits for R92C_USB_SPECIAL_OPTION. */
+#define R92C_USB_SPECIAL_OPTION_AGG_EN 0x08
+#define R92C_USB_SPECIAL_OPTION_INT_BULK_SEL 0x10
+
+/* Bits for R92C_USB_EP. */
+#define R92C_USB_EP_HQ_M 0x000f
+#define R92C_USB_EP_HQ_S 0
+#define R92C_USB_EP_NQ_M 0x00f0
+#define R92C_USB_EP_NQ_S 4
+#define R92C_USB_EP_LQ_M 0x0f00
+#define R92C_USB_EP_LQ_S 8
+
+#endif /* R92CU_REG_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_rx.c b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_rx.c
new file mode 100644
index 00000000..ec55da6d
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_rx.c
@@ -0,0 +1,65 @@
+#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_rtwnvar.h>
+
+#include <dev/rtwn/rtl8192c/usb/r92cu.h>
+
+
+int
+r92cu_classify_intr(struct rtwn_softc *sc, void *buf, int len)
+{
+ /* NB: reports are fetched from C2H_MSG register. */
+ return (RTWN_RX_DATA);
+}
+
+int
+r92cu_align_rx(int totlen, int len)
+{
+ return (roundup2(totlen, 128));
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_tx.c b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_tx.c
new file mode 100644
index 00000000..0954316d
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_tx.c
@@ -0,0 +1,66 @@
+#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_rtwnvar.h>
+#include <dev/rtwn/if_rtwn_debug.h>
+
+#include <dev/rtwn/rtl8192c/usb/r92cu.h>
+#include <dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h>
+
+
+void
+r92cu_dump_tx_desc(struct rtwn_softc *sc, const void *desc)
+{
+#ifdef RTWN_DEBUG
+ const struct r92cu_tx_desc *txd = desc;
+
+ RTWN_DPRINTF(sc, RTWN_DEBUG_XMIT_DESC,
+ "%s: len %d, off %d, flags0 %02X, dw: 1 %08X, 2 %08X, 3 %04X "
+ "(seq %04X), 4 %08X, 5 %08X, 6 %08X, sum %04X, pad %04X\n",
+ __func__, le16toh(txd->pktlen), txd->offset, txd->flags0,
+ le32toh(txd->txdw1), le32toh(txd->txdw2), le16toh(txd->txdw3),
+ le16toh(txd->txdseq), le32toh(txd->txdw4), le32toh(txd->txdw5),
+ le32toh(txd->txdw6), le16toh(txd->txdsum), le16toh(txd->pad));
+#endif
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h
new file mode 100644
index 00000000..16c2d058
--- /dev/null
+++ b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h
@@ -0,0 +1,45 @@
+/*-
+ * 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 R92CU_TX_DESC_H
+#define R92CU_TX_DESC_H
+
+#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
+
+/* Tx MAC descriptor (USB). */
+struct r92cu_tx_desc {
+ uint16_t pktlen;
+ uint8_t offset;
+ uint8_t flags0;
+
+ uint32_t txdw1;
+ uint32_t txdw2;
+ uint16_t txdw3;
+ uint16_t txdseq;
+
+ uint32_t txdw4;
+ uint32_t txdw5;
+ uint32_t txdw6;
+
+ uint16_t txdsum;
+ uint16_t pad;
+} __packed __attribute__((aligned(4)));
+
+#endif /* R92CU_TX_DESC_H */ \ No newline at end of file