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_attach.c2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c.h6
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_init.c26
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_reg.h26
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c44
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h5
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c2
9 files changed, 112 insertions, 3 deletions
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
index d53dbf98..225c69f5 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
+++ b/freebsd/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
@@ -174,6 +174,7 @@ r92ce_attach(struct rtwn_pci_softc *pc)
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_rx_stats = r92c_get_rx_stats;
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;
@@ -192,6 +193,7 @@ r92ce_attach(struct rtwn_pci_softc *pc)
sc->sc_fw_reset = r92ce_fw_reset;
sc->sc_fw_download_enable = r92c_fw_download_enable;
#endif
+ sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = r92c_set_page_size;
sc->sc_lc_calib = r92c_lc_calib;
sc->sc_iq_calib = r92ce_iq_calib;
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c.h
index 2b63179e..5ac666d0 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c.h
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c.h
@@ -77,6 +77,7 @@ void r92c_handle_c2h_report(void *);
/* r92c_init.c */
int r92c_check_condition(struct rtwn_softc *, const uint8_t[]);
+int r92c_llt_init(struct rtwn_softc *);
int r92c_set_page_size(struct rtwn_softc *);
void r92c_init_bb_common(struct rtwn_softc *);
int r92c_init_rf_chain(struct rtwn_softc *,
@@ -87,6 +88,9 @@ void r92c_init_ampdu(struct rtwn_softc *);
void r92c_init_antsel(struct rtwn_softc *);
void r92c_pa_bias_init(struct rtwn_softc *);
+/* r92c_llt.c */
+int r92c_llt_write(struct rtwn_softc *, uint32_t, uint32_t);
+
/* 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);
@@ -99,6 +103,8 @@ void r92c_parse_rom(struct rtwn_softc *, uint8_t *);
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 *);
+void r92c_get_rx_stats(struct rtwn_softc *, struct ieee80211_rx_stats *,
+ const void *, const void *);
/* r92c_tx.c */
void r92c_tx_enable_ampdu(void *, int);
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c
index 74c7d205..91bcfc0e 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c
@@ -82,7 +82,7 @@ r92c_fw_cmd(struct rtwn_softc *sc, uint8_t id, const void *buf, int len)
}
/* Wait for current FW box to be empty. */
- for (ntries = 0; ntries < 50; ntries++) {
+ for (ntries = 0; ntries < 100; ntries++) {
if (!(rtwn_read_1(sc, R92C_HMETFR) & (1 << sc->fwcur)))
break;
rtwn_delay(sc, 2000);
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_init.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_init.c
index d8db0286..4ec44045 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_init.c
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_init.c
@@ -92,6 +92,32 @@ r92c_check_condition(struct rtwn_softc *sc, const uint8_t cond[])
}
int
+r92c_llt_init(struct rtwn_softc *sc)
+{
+ int i, error;
+
+ /* Reserve pages [0; page_count]. */
+ for (i = 0; i < sc->page_count; i++) {
+ if ((error = r92c_llt_write(sc, i, i + 1)) != 0)
+ return (error);
+ }
+ /* NB: 0xff indicates end-of-list. */
+ if ((error = r92c_llt_write(sc, i, 0xff)) != 0)
+ return (error);
+ /*
+ * Use pages [page_count + 1; pktbuf_count - 1]
+ * as ring buffer.
+ */
+ for (++i; i < sc->pktbuf_count - 1; i++) {
+ if ((error = r92c_llt_write(sc, i, i + 1)) != 0)
+ return (error);
+ }
+ /* Make the last page point to the beginning of the ring buffer. */
+ error = r92c_llt_write(sc, i, sc->page_count + 1);
+ return (error);
+}
+
+int
r92c_set_page_size(struct rtwn_softc *sc)
{
return (rtwn_write_1(sc, R92C_PBP, SM(R92C_PBP_PSRX, R92C_PBP_128) |
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_reg.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_reg.h
index ff03d191..34a4b80c 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_reg.h
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_reg.h
@@ -66,6 +66,7 @@
#define R92C_HSIMR 0x058
#define R92C_HSISR 0x05c
#define R92C_MULTI_FUNC_CTRL 0x068
+#define R92C_LDO_SWR_CTRL 0x07c
#define R92C_MCUFWDL 0x080
#define R92C_HMEBOX_EXT(idx) (0x088 + (idx) * 2)
#define R92C_EFUSE_ACCESS 0x0cf
@@ -115,6 +116,7 @@
#define R92C_TXDMA_OFFSET_CHK 0x20c
#define R92C_TXDMA_STATUS 0x210
#define R92C_RQPN_NPQ 0x214
+#define R92C_AUTO_LLT 0x224
/* Rx DMA Configuration. */
#define R92C_RXDMA_AGG_PG_TH 0x280
#define R92C_RXPKT_NUM 0x284
@@ -297,6 +299,16 @@
#define R92C_SYS_CLKR_SYS_EN 0x00001000
#define R92C_SYS_CLKR_RING_EN 0x00002000
+/* Bits for R92C_RSV_CTRL. */
+#define R92C_RSV_CTRL_WLOCK_ALL 0x01
+#define R92C_RSV_CTRL_WLOCK_00 0x02
+#define R92C_RSV_CTRL_WLOCK_04 0x04
+#define R92C_RSV_CTRL_WLOCK_08 0x08
+#define R92C_RSV_CTRL_WLOCK_40 0x10
+#define R92C_RSV_CTRL_R_DIS_PRST_0 0x20
+#define R92C_RSV_CTRL_R_DIS_PRST_1 0x40
+#define R92C_RSV_CTRL_LOCK_ALL_EN 0x80
+
/* Bits for R92C_RF_CTRL. */
#define R92C_RF_CTRL_EN 0x01
#define R92C_RF_CTRL_RSTB 0x02
@@ -339,6 +351,9 @@
/* Bits for R92C_LEDCFG0. */
#define R92C_LEDCFG0_DIS 0x08
+/* Bits for R92C_LEDCFG1. */
+#define R92C_LEDCFG1_DIS 0x80
+
/* Bits for R92C_MULTI_FUNC_CTRL. */
#define R92C_MULTI_BT_FUNC_EN 0x00040000
@@ -420,6 +435,7 @@
#define R92C_PBP_1024 4
/* Bits for R92C_TRXDMA_CTRL. */
+#define R92C_TRXDMA_CTRL_RX_SHIFT_EN 0x0002
#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
@@ -476,6 +492,9 @@
/* Bits for R92C_TXDMA_OFFSET_CHK. */
#define R92C_TXDMA_OFFSET_DROP_DATA_EN 0x00000200
+/* Bits for R92C_AUTO_LLT. */
+#define R92C_AUTO_LLT_INIT 0x00010000
+
/* Bits for R92C_FWHW_TXQ_CTRL. */
#define R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW 0x80
#define R92C_FWHW_TXQ_CTRL_REAL_BEACON 0x400000
@@ -593,7 +612,8 @@
#define R92C_RCR_APPFCS 0x80000000
/* Bits for R92C_RX_DRVINFO_SZ. */
-#define R92C_RX_DRVINFO_SZ_DEF 4 /* XXX other values will not work */
+/* XXX other values will not work */
+#define R92C_RX_DRVINFO_SZ_DEF ((RTWN_PHY_STATUS_SIZE) / 8)
/* Bits for R92C_WMAC_TRXPTCL_CTL. */
#define R92C_WMAC_TRXPTCL_SHPRE 0x00020000
@@ -681,6 +701,7 @@
#define R92C_OFDM0_TXIQIMBALANCE(chain) (0xc80 + (chain) * 8)
#define R92C_OFDM0_TXAFE(chain) (0xc94 + (chain) * 8)
#define R92C_OFDM0_RXIQEXTANTA 0xca0
+#define R92C_OFDM0_TXPSEUDONOISEWGT 0xce4
#define R92C_OFDM1_LSTF 0xd00
/* Bits for R92C_FPGA[01]_RFMOD. */
@@ -800,6 +821,9 @@
#define R92C_LSSI_READBACK_DATA_M 0x000fffff
#define R92C_LSSI_READBACK_DATA_S 0
+/* Bits for R92C_CCK0_SYSTEM. */
+#define R92C_CCK0_SYSTEM_CCK_SIDEBAND 0x00000010
+
/* Bits for R92C_OFDM0_AGCCORE1(i). */
#define R92C_OFDM0_AGCCORE1_GAIN_M 0x0000007f
#define R92C_OFDM0_AGCCORE1_GAIN_S 0
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c
index b77c76f6..70dff0f6 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c
@@ -102,3 +102,47 @@ r92c_rx_radiotap_flags(const void *buf)
flags = IEEE80211_RADIOTAP_F_SHORTGI;
return (flags);
}
+
+void
+r92c_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
+ const void *desc, const void *physt_ptr)
+{
+ const struct r92c_rx_stat *stat = desc;
+ uint32_t rxdw1, rxdw3;
+ uint8_t rate;
+
+ rxdw1 = le32toh(stat->rxdw1);
+ rxdw3 = le32toh(stat->rxdw3);
+ rate = MS(rxdw3, R92C_RXDW3_RATE);
+
+ if (rxdw1 & R92C_RXDW1_AMPDU)
+ rxs->c_pktflags |= IEEE80211_RX_F_AMPDU;
+ else if (rxdw1 & R92C_RXDW1_AMPDU_MORE)
+ rxs->c_pktflags |= IEEE80211_RX_F_AMPDU_MORE;
+ if ((rxdw3 & R92C_RXDW3_SPLCP) && rate >= RTWN_RIDX_MCS(0))
+ rxs->c_pktflags |= IEEE80211_RX_F_SHORTGI;
+
+ if (rxdw3 & R92C_RXDW3_HT40)
+ rxs->c_width = IEEE80211_RX_FW_40MHZ;
+ else
+ rxs->c_width = IEEE80211_RX_FW_20MHZ;
+
+ if (RTWN_RATE_IS_CCK(rate))
+ rxs->c_phytype = IEEE80211_RX_FP_11B;
+ else if (rate < RTWN_RIDX_MCS(0))
+ rxs->c_phytype = IEEE80211_RX_FP_11G;
+ else
+ rxs->c_phytype = IEEE80211_RX_FP_11NG;
+
+ /* Map HW rate index to 802.11 rate. */
+ if (rate < RTWN_RIDX_MCS(0)) {
+ rxs->c_rate = ridx2rate[rate];
+ if (RTWN_RATE_IS_CCK(rate))
+ rxs->c_pktflags |= IEEE80211_RX_F_CCK;
+ else
+ rxs->c_pktflags |= IEEE80211_RX_F_OFDM;
+ } else { /* MCS0~15. */
+ rxs->c_rate = IEEE80211_RATE_MCS | (rate - 12);
+ rxs->c_pktflags |= IEEE80211_RX_F_HT;
+ }
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h
index 7fec70be..12dfd665 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx_desc.h
@@ -45,6 +45,9 @@ struct r92c_rx_stat {
uint32_t rxdw1;
#define R92C_RXDW1_MACID_M 0x0000001f
#define R92C_RXDW1_MACID_S 0
+#define R92C_RXDW1_AMSDU 0x00002000
+#define R92C_RXDW1_AMPDU_MORE 0x00004000
+#define R92C_RXDW1_AMPDU 0x00008000
#define R92C_RXDW1_MC 0x40000000
#define R92C_RXDW1_BC 0x80000000
@@ -56,6 +59,8 @@ struct r92c_rx_stat {
#define R92C_RXDW3_SPLCP 0x00000100
#define R92C_RXDW3_HT40 0x00000200
#define R92C_RXDW3_HTC 0x00000400
+#define R92C_RXDW3_BSSID_FIT_M 0x00003000
+#define R92C_RXDW3_BSSID_FIT_S 12
uint32_t rxdw4;
uint32_t tsf_low;
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h
index 037ac0e2..c3bc87ca 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h
@@ -68,7 +68,7 @@ struct r92c_tx_desc {
uint16_t txdseq;
uint32_t txdw4;
-#define R92C_TXDW4_RTSRATE_M 0x0000003f
+#define R92C_TXDW4_RTSRATE_M 0x0000001f
#define R92C_TXDW4_RTSRATE_S 0
#define R92C_TXDW4_SEQ_SEL_M 0x00000040
#define R92C_TXDW4_SEQ_SEL_S 6
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
index ce3f7a1a..aa6f7067 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
+++ b/freebsd/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
@@ -167,6 +167,7 @@ r92cu_attach(struct rtwn_usb_softc *uc)
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_rx_stats = r92c_get_rx_stats;
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;
@@ -185,6 +186,7 @@ r92cu_attach(struct rtwn_usb_softc *uc)
sc->sc_fw_reset = r92c_fw_reset;
sc->sc_fw_download_enable = r92c_fw_download_enable;
#endif
+ sc->sc_llt_init = r92c_llt_init;
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 */