summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/rtwn
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/dev/rtwn')
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwn.c57
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwn_rx.c153
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwn_rx.h2
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwn_tx.c18
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwnvar.h23
-rw-r--r--freebsd/sys/dev/rtwn/pci/rtwn_pci_attach.c34
-rw-r--r--freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.c23
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e.h2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_fw.c2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c17
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c2
-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
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/r12a.h2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/r12a_beacon.c2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/r12a_fw.c4
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/r12a_rx.c91
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h8
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c12
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c12
-rw-r--r--freebsd/sys/dev/rtwn/rtl8821a/r21a_init.c2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c5
-rw-r--r--freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h13
-rw-r--r--freebsd/sys/dev/rtwn/usb/rtwn_usb_ep.c8
-rw-r--r--freebsd/sys/dev/rtwn/usb/rtwn_usb_rx.c26
32 files changed, 451 insertions, 182 deletions
diff --git a/freebsd/sys/dev/rtwn/if_rtwn.c b/freebsd/sys/dev/rtwn/if_rtwn.c
index a553814f..050d9960 100644
--- a/freebsd/sys/dev/rtwn/if_rtwn.c
+++ b/freebsd/sys/dev/rtwn/if_rtwn.c
@@ -123,9 +123,6 @@ static int rtwn_run(struct rtwn_softc *,
static void rtwn_watchdog(void *);
#endif
static void rtwn_parent(struct ieee80211com *);
-static int rtwn_llt_write(struct rtwn_softc *, uint32_t,
- uint32_t);
-static int rtwn_llt_init(struct rtwn_softc *);
static int rtwn_dma_init(struct rtwn_softc *);
static int rtwn_mac_init(struct rtwn_softc *);
static void rtwn_mrr_init(struct rtwn_softc *);
@@ -697,6 +694,7 @@ rtwn_ioctl_reset(struct ieee80211vap *vap, u_long cmd)
case IEEE80211_IOC_RTSTHRESHOLD:
case IEEE80211_IOC_PROTMODE:
case IEEE80211_IOC_HTPROTMODE:
+ case IEEE80211_IOC_LDPC:
error = 0;
break;
default:
@@ -1384,54 +1382,6 @@ rtwn_parent(struct ieee80211com *ic)
rtwn_stop(sc);
}
-
-static int
-rtwn_llt_write(struct rtwn_softc *sc, uint32_t addr, uint32_t data)
-{
- int ntries, error;
-
- error = rtwn_write_4(sc, R92C_LLT_INIT,
- SM(R92C_LLT_INIT_OP, R92C_LLT_INIT_OP_WRITE) |
- SM(R92C_LLT_INIT_ADDR, addr) |
- SM(R92C_LLT_INIT_DATA, data));
- if (error != 0)
- return (error);
- /* Wait for write operation to complete. */
- for (ntries = 0; ntries < 20; ntries++) {
- if (MS(rtwn_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) ==
- R92C_LLT_INIT_OP_NO_ACTIVE)
- return (0);
- rtwn_delay(sc, 10);
- }
- return (ETIMEDOUT);
-}
-
-static int
-rtwn_llt_init(struct rtwn_softc *sc)
-{
- int i, error;
-
- /* Reserve pages [0; page_count]. */
- for (i = 0; i < sc->page_count; i++) {
- if ((error = rtwn_llt_write(sc, i, i + 1)) != 0)
- return (error);
- }
- /* NB: 0xff indicates end-of-list. */
- if ((error = rtwn_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 = rtwn_llt_write(sc, i, i + 1)) != 0)
- return (error);
- }
- /* Make the last page point to the beginning of the ring buffer. */
- error = rtwn_llt_write(sc, i, sc->page_count + 1);
- return (error);
-}
-
static int
rtwn_dma_init(struct rtwn_softc *sc)
{
@@ -1770,13 +1720,13 @@ rtwn_node_alloc(struct ieee80211vap *vap,
}
static void
-rtwn_newassoc(struct ieee80211_node *ni, int isnew)
+rtwn_newassoc(struct ieee80211_node *ni, int isnew __unused)
{
struct rtwn_softc *sc = ni->ni_ic->ic_softc;
struct rtwn_node *un = RTWN_NODE(ni);
int id;
- if (!isnew)
+ if (un->id != RTWN_MACID_UNDEFINED)
return;
RTWN_NT_LOCK(sc);
@@ -2001,6 +1951,7 @@ rtwn_stop(struct rtwn_softc *sc)
sc->fwver = 0;
sc->thcal_temp = 0;
sc->cur_bcnq_id = RTWN_VAP_ID_INVALID;
+ bzero(&sc->last_physt, sizeof(sc->last_physt));
#ifdef D4054
ieee80211_tx_watchdog_stop(&sc->sc_ic);
diff --git a/freebsd/sys/dev/rtwn/if_rtwn_rx.c b/freebsd/sys/dev/rtwn/if_rtwn_rx.c
index 8d103dc7..31ab7e69 100644
--- a/freebsd/sys/dev/rtwn/if_rtwn_rx.c
+++ b/freebsd/sys/dev/rtwn/if_rtwn_rx.c
@@ -119,18 +119,19 @@ rtwn_set_basicrates(struct rtwn_softc *sc, uint32_t rates)
}
static void
-rtwn_update_avgrssi(struct rtwn_softc *sc, struct rtwn_node *un, int rate)
+rtwn_update_avgrssi(struct rtwn_softc *sc, struct rtwn_node *un, int8_t rssi,
+ int is_cck)
{
int pwdb;
/* Convert antenna signal to percentage. */
- if (un->last_rssi <= -100 || un->last_rssi >= 20)
+ if (rssi <= -100 || rssi >= 20)
pwdb = 0;
- else if (un->last_rssi >= 0)
+ else if (rssi >= 0)
pwdb = 100;
else
- pwdb = 100 + un->last_rssi;
- if (RTWN_RATE_IS_CCK(rate)) {
+ pwdb = 100 + rssi;
+ if (is_cck) {
/* CCK gain is smaller than OFDM/MCS gain. */
pwdb += 6;
if (pwdb > 100)
@@ -157,11 +158,11 @@ rtwn_update_avgrssi(struct rtwn_softc *sc, struct rtwn_node *un, int rate)
}
static int8_t
-rtwn_get_rssi(struct rtwn_softc *sc, int rate, void *physt)
+rtwn_get_rssi(struct rtwn_softc *sc, void *physt, int is_cck)
{
int8_t rssi;
- if (RTWN_RATE_IS_CCK(rate))
+ if (is_cck)
rssi = rtwn_get_rssi_cck(sc, physt);
else /* OFDM/HT. */
rssi = rtwn_get_rssi_ofdm(sc, physt);
@@ -190,81 +191,133 @@ rtwn_get_tsf(struct rtwn_softc *sc, uint64_t *buf, int id)
*buf += rtwn_get_tsf_low(sc, id);
}
+static uint64_t
+rtwn_extend_rx_tsf(struct rtwn_softc *sc, const struct r92c_rx_stat *stat)
+{
+ uint64_t tsft;
+ uint32_t rxdw3, tsfl, tsfl_curr;
+ int id;
+
+ rxdw3 = le32toh(stat->rxdw3);
+ tsfl = le32toh(stat->tsf_low);
+ id = MS(rxdw3, R92C_RXDW3_BSSID_FIT);
+
+ switch (id) {
+ case 1:
+ case 2:
+ id >>= 1;
+ tsfl_curr = rtwn_get_tsf_low(sc, id);
+ break;
+ default:
+ {
+ uint32_t tsfl0, tsfl1;
+
+ tsfl0 = rtwn_get_tsf_low(sc, 0);
+ tsfl1 = rtwn_get_tsf_low(sc, 1);
+
+ if (abs(tsfl0 - tsfl) < abs(tsfl1 - tsfl)) {
+ id = 0;
+ tsfl_curr = tsfl0;
+ } else {
+ id = 1;
+ tsfl_curr = tsfl1;
+ }
+ break;
+ }
+ }
+
+ tsft = rtwn_get_tsf_high(sc, id);
+ if (tsfl > tsfl_curr && tsfl > 0xffff0000)
+ tsft--;
+ tsft <<= 32;
+ tsft += tsfl;
+
+ return (tsft);
+}
+
struct ieee80211_node *
-rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc,
- int8_t *rssi)
+rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
struct ieee80211_frame_min *wh;
+ struct ieee80211_rx_stats rxs;
struct rtwn_node *un;
struct r92c_rx_stat *stat;
- uint32_t rxdw0, rxdw3;
- int cipher, infosz, pktlen, rate, shift;
+ void *physt;
+ uint32_t rxdw0;
+ int8_t rssi;
+ int cipher, infosz, is_cck, pktlen, shift;
stat = desc;
rxdw0 = le32toh(stat->rxdw0);
- rxdw3 = le32toh(stat->rxdw3);
cipher = MS(rxdw0, R92C_RXDW0_CIPHER);
infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
shift = MS(rxdw0, R92C_RXDW0_SHIFT);
- rate = MS(rxdw3, R92C_RXDW3_RATE);
wh = (struct ieee80211_frame_min *)(mtodo(m, shift + infosz));
if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
cipher != R92C_CAM_ALGO_NONE)
m->m_flags |= M_WEP;
- if (pktlen >= sizeof(*wh))
+ if (pktlen >= sizeof(*wh)) {
ni = ieee80211_find_rxnode(ic, wh);
- else
+ if (ni != NULL && (ni->ni_flags & IEEE80211_NODE_HT))
+ m->m_flags |= M_AMPDU;
+ } else
ni = NULL;
un = RTWN_NODE(ni);
- /* Get RSSI from PHY status descriptor if present. */
- if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
- *rssi = rtwn_get_rssi(sc, rate, mtod(m, void *));
- RTWN_DPRINTF(sc, RTWN_DEBUG_RSSI, "%s: rssi %d, ridx %d\n",
- __func__, *rssi, rate);
+ if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST))
+ physt = (void *)mtodo(m, shift);
+ else
+ physt = (un != NULL) ? &un->last_physt : &sc->last_physt;
+
+ bzero(&rxs, sizeof(rxs));
+ rtwn_get_rx_stats(sc, &rxs, desc, physt);
+ if (rxs.c_pktflags & IEEE80211_RX_F_AMPDU) {
+ /* Next MPDU will come without PHY info. */
+ memcpy(&sc->last_physt, physt, sizeof(sc->last_physt));
+ if (un != NULL)
+ memcpy(&un->last_physt, physt, sizeof(sc->last_physt));
+ }
- sc->last_rssi = *rssi;
- if (un != NULL) {
- un->last_rssi = *rssi;
+ /* Add some common bits. */
+ /* NB: should not happen. */
+ if (rxdw0 & R92C_RXDW0_CRCERR)
+ rxs.c_pktflags |= IEEE80211_RX_F_FAIL_FCSCRC;
+
+ rxs.r_flags |= IEEE80211_R_TSF_START; /* XXX undocumented */
+ rxs.r_flags |= IEEE80211_R_TSF64;
+ rxs.c_rx_tsf = rtwn_extend_rx_tsf(sc, stat);
+
+ /* Get RSSI from PHY status descriptor. */
+ is_cck = (rxs.c_pktflags & IEEE80211_RX_F_CCK) != 0;
+ rssi = rtwn_get_rssi(sc, physt, is_cck);
+
+ /* XXX TODO: we really need a rate-to-string method */
+ RTWN_DPRINTF(sc, RTWN_DEBUG_RSSI, "%s: rssi %d, rate %d\n",
+ __func__, rssi, rxs.c_rate);
+ if (un != NULL && infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
+ /* Update our average RSSI. */
+ rtwn_update_avgrssi(sc, un, rssi, is_cck);
+ }
- /* Update our average RSSI. */
- rtwn_update_avgrssi(sc, un, rate);
- }
- } else
- *rssi = (un != NULL) ? un->last_rssi : sc->last_rssi;
+ rxs.r_flags |= IEEE80211_R_NF | IEEE80211_R_RSSI;
+ rxs.c_nf = RTWN_NOISE_FLOOR;
+ rxs.c_rssi = rssi - rxs.c_nf;
+ (void) ieee80211_add_rx_params(m, &rxs);
if (ieee80211_radiotap_active(ic)) {
struct rtwn_rx_radiotap_header *tap = &sc->sc_rxtap;
- int id = RTWN_VAP_ID_INVALID;
-
- if (ni != NULL)
- id = RTWN_VAP(ni->ni_vap)->id;
- if (id == RTWN_VAP_ID_INVALID)
- id = 0;
tap->wr_flags = rtwn_rx_radiotap_flags(sc, desc);
- tap->wr_tsft = rtwn_get_tsf_high(sc, id);
- if (le32toh(stat->tsf_low) > rtwn_get_tsf_low(sc, id))
- tap->wr_tsft--;
- tap->wr_tsft = (uint64_t)htole32(tap->wr_tsft) << 32;
- tap->wr_tsft += stat->tsf_low;
-
- /* XXX 20/40? */
-
- /* Map HW rate index to 802.11 rate. */
- if (rate < RTWN_RIDX_MCS(0))
- tap->wr_rate = ridx2rate[rate];
- else /* MCS0~15. */
- tap->wr_rate = IEEE80211_RATE_MCS | (rate - 12);
-
- tap->wr_dbm_antsignal = *rssi;
- tap->wr_dbm_antnoise = RTWN_NOISE_FLOOR;
+ tap->wr_tsft = htole64(rxs.c_rx_tsf);
+ tap->wr_rate = rxs.c_rate;
+ tap->wr_dbm_antsignal = rssi;
+ tap->wr_dbm_antnoise = rxs.c_nf;
}
/* Drop PHY descriptor. */
diff --git a/freebsd/sys/dev/rtwn/if_rtwn_rx.h b/freebsd/sys/dev/rtwn/if_rtwn_rx.h
index dfdcc4bf..49897eb9 100644
--- a/freebsd/sys/dev/rtwn/if_rtwn_rx.h
+++ b/freebsd/sys/dev/rtwn/if_rtwn_rx.h
@@ -26,7 +26,7 @@ void rtwn_get_rates(struct rtwn_softc *, const struct ieee80211_rateset *,
const struct ieee80211_htrateset *, uint32_t *, int *, int);
void rtwn_set_basicrates(struct rtwn_softc *, uint32_t);
struct ieee80211_node * rtwn_rx_common(struct rtwn_softc *, struct mbuf *,
- void *, int8_t *);
+ void *);
void rtwn_adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
const struct ieee80211_rx_stats *, int, int);
void rtwn_set_multi(struct rtwn_softc *);
diff --git a/freebsd/sys/dev/rtwn/if_rtwn_tx.c b/freebsd/sys/dev/rtwn/if_rtwn_tx.c
index 1ea9a766..c48e2e0e 100644
--- a/freebsd/sys/dev/rtwn/if_rtwn_tx.c
+++ b/freebsd/sys/dev/rtwn/if_rtwn_tx.c
@@ -114,17 +114,16 @@ static int
rtwn_tx_data(struct rtwn_softc *sc, struct ieee80211_node *ni,
struct mbuf *m)
{
- const struct ieee80211_txparam *tp;
+ const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_key *k = NULL;
- struct ieee80211_channel *chan;
struct ieee80211_frame *wh;
struct rtwn_tx_desc_common *txd;
struct rtwn_tx_buf buf;
uint8_t rate, ridx, type;
u_int cipher;
- int ismcast, maxretry;
+ int ismcast;
RTWN_ASSERT_LOCKED(sc);
@@ -132,20 +131,15 @@ rtwn_tx_data(struct rtwn_softc *sc, struct ieee80211_node *ni,
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
- chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ?
- ni->ni_chan : ic->ic_curchan;
- tp = &vap->iv_txparms[ieee80211_chan2mode(chan)];
- maxretry = tp->maxretry;
-
/* Choose a TX rate index. */
- if (type == IEEE80211_FC0_TYPE_MGT)
+ if (type == IEEE80211_FC0_TYPE_MGT ||
+ type == IEEE80211_FC0_TYPE_CTL ||
+ (m->m_flags & M_EAPOL) != 0)
rate = tp->mgmtrate;
else if (ismcast)
rate = tp->mcastrate;
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = tp->ucastrate;
- else if (m->m_flags & M_EAPOL)
- rate = tp->mgmtrate;
else {
if (sc->sc_ratectl == RTWN_RATECTL_NET80211) {
/* XXX pass pktlen */
@@ -183,7 +177,7 @@ rtwn_tx_data(struct rtwn_softc *sc, struct ieee80211_node *ni,
memset(txd, 0, sc->txdesc_len);
txd->txdw1 = htole32(SM(RTWN_TXDW1_CIPHER, rtwn_get_cipher(cipher)));
- rtwn_fill_tx_desc(sc, ni, m, txd, ridx, maxretry);
+ rtwn_fill_tx_desc(sc, ni, m, txd, ridx, tp->maxretry);
if (ieee80211_radiotap_active_vap(vap)) {
struct rtwn_tx_radiotap_header *tap = &sc->sc_txtap;
diff --git a/freebsd/sys/dev/rtwn/if_rtwnvar.h b/freebsd/sys/dev/rtwn/if_rtwnvar.h
index 0c010adb..d8754024 100644
--- a/freebsd/sys/dev/rtwn/if_rtwnvar.h
+++ b/freebsd/sys/dev/rtwn/if_rtwnvar.h
@@ -76,6 +76,12 @@ struct rtwn_tx_buf {
uint8_t txd[RTWN_TX_DESC_SIZE];
} __attribute__((aligned(4)));
+#define RTWN_PHY_STATUS_SIZE 32
+struct rtwn_tx_phystat {
+ uint32_t phydw[RTWN_PHY_STATUS_SIZE / sizeof(uint32_t)];
+};
+
+
struct rtwn_softc;
union sec_param {
@@ -95,7 +101,8 @@ struct rtwn_cmdq {
struct rtwn_node {
struct ieee80211_node ni; /* must be the first */
int id;
- int8_t last_rssi;
+
+ struct rtwn_tx_phystat last_physt;
int avg_pwdb;
};
#define RTWN_NODE(ni) ((struct rtwn_node *)(ni))
@@ -195,7 +202,7 @@ struct rtwn_softc {
const char *name;
int sc_ant;
- int8_t last_rssi;
+ struct rtwn_tx_phystat last_physt;
uint8_t thcal_temp;
int cur_bcnq_id;
@@ -301,6 +308,7 @@ struct rtwn_softc {
void (*sc_fw_reset)(struct rtwn_softc *, int);
void (*sc_fw_download_enable)(struct rtwn_softc *, int);
#endif
+ int (*sc_llt_init)(struct rtwn_softc *);
int (*sc_set_page_size)(struct rtwn_softc *);
void (*sc_lc_calib)(struct rtwn_softc *);
void (*sc_iq_calib)(struct rtwn_softc *);
@@ -336,6 +344,9 @@ struct rtwn_softc {
struct ieee80211vap *, int);
void (*sc_set_rssi)(struct rtwn_softc *);
#endif
+ void (*sc_get_rx_stats)(struct rtwn_softc *,
+ struct ieee80211_rx_stats *, const void *,
+ const void *);
int8_t (*sc_get_rssi_cck)(struct rtwn_softc *, void *);
int8_t (*sc_get_rssi_ofdm)(struct rtwn_softc *, void *);
int (*sc_classify_intr)(struct rtwn_softc *, void *, int);
@@ -462,8 +473,8 @@ void rtwn_suspend(struct rtwn_softc *);
/* Aliases. */
#define rtwn_bb_write rtwn_write_4
-#define rtwn_bb_read rtwn_read_4
-#define rtwn_bb_setbits rtwn_setbits_4
+#define rtwn_bb_read rtwn_read_4
+#define rtwn_bb_setbits rtwn_setbits_4
/* Device-specific. */
#define rtwn_rf_read(_sc, _chain, _addr) \
@@ -478,6 +489,8 @@ void rtwn_suspend(struct rtwn_softc *);
(((_sc)->sc_parse_rom)((_sc), (_rom)))
#define rtwn_set_led(_sc, _led, _on) \
(((_sc)->sc_set_led)((_sc), (_led), (_on)))
+#define rtwn_get_rx_stats(_sc, _rxs, _desc, _physt) \
+ (((_sc)->sc_get_rx_stats((_sc), (_rxs), (_desc), (_physt))))
#define rtwn_get_rssi_cck(_sc, _physt) \
(((_sc)->sc_get_rssi_cck)((_sc), (_physt)))
#define rtwn_get_rssi_ofdm(_sc, _physt) \
@@ -492,6 +505,8 @@ void rtwn_suspend(struct rtwn_softc *);
#define rtwn_fw_download_enable(_sc, _enable) \
(((_sc)->sc_fw_download_enable)((_sc), (_enable)))
#endif
+#define rtwn_llt_init(_sc) \
+ (((_sc)->sc_llt_init)((_sc)))
#define rtwn_set_page_size(_sc) \
(((_sc)->sc_set_page_size)((_sc)))
#define rtwn_lc_calib(_sc) \
diff --git a/freebsd/sys/dev/rtwn/pci/rtwn_pci_attach.c b/freebsd/sys/dev/rtwn/pci/rtwn_pci_attach.c
index 5b28d27f..9813cb32 100644
--- a/freebsd/sys/dev/rtwn/pci/rtwn_pci_attach.c
+++ b/freebsd/sys/dev/rtwn/pci/rtwn_pci_attach.c
@@ -96,20 +96,31 @@ static void rtwn_pci_beacon_update_end(struct rtwn_softc *,
static void rtwn_pci_attach_methods(struct rtwn_softc *);
-static int matched_chip = RTWN_CHIP_MAX_PCI;
+static const struct rtwn_pci_ident *
+rtwn_pci_probe_sub(device_t dev)
+{
+ const struct rtwn_pci_ident *ident;
+ int vendor_id, device_id;
+
+ vendor_id = pci_get_vendor(dev);
+ device_id = pci_get_device(dev);
+
+ for (ident = rtwn_pci_ident_table; ident->name != NULL; ident++)
+ if (vendor_id == ident->vendor && device_id == ident->device)
+ return (ident);
+
+ return (NULL);
+}
static int
rtwn_pci_probe(device_t dev)
{
const struct rtwn_pci_ident *ident;
- for (ident = rtwn_pci_ident_table; ident->name != NULL; ident++) {
- if (pci_get_vendor(dev) == ident->vendor &&
- pci_get_device(dev) == ident->device) {
- matched_chip = ident->chip;
- device_set_desc(dev, ident->name);
- return (BUS_PROBE_DEFAULT);
- }
+ ident = rtwn_pci_probe_sub(dev);
+ if (ident != NULL) {
+ device_set_desc(dev, ident->name);
+ return (BUS_PROBE_DEFAULT);
}
return (ENXIO);
}
@@ -593,13 +604,15 @@ rtwn_pci_attach_methods(struct rtwn_softc *sc)
static int
rtwn_pci_attach(device_t dev)
{
+ const struct rtwn_pci_ident *ident;
struct rtwn_pci_softc *pc = device_get_softc(dev);
struct rtwn_softc *sc = &pc->pc_sc;
struct ieee80211com *ic = &sc->sc_ic;
uint32_t lcsr;
int cap_off, i, error, rid;
- if (matched_chip >= RTWN_CHIP_MAX_PCI)
+ ident = rtwn_pci_probe_sub(dev);
+ if (ident == NULL)
return (ENXIO);
/*
@@ -651,8 +664,7 @@ rtwn_pci_attach(device_t dev)
mtx_init(&sc->sc_mtx, ic->ic_name, MTX_NETWORK_LOCK, MTX_DEF);
rtwn_pci_attach_methods(sc);
- /* XXX something similar to USB_GET_DRIVER_INFO() */
- rtwn_pci_attach_private(pc, matched_chip);
+ rtwn_pci_attach_private(pc, ident->chip);
/* Allocate Tx/Rx buffers. */
error = rtwn_pci_alloc_rx_list(sc);
diff --git a/freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.c b/freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.c
index 8da0061b..292fb07f 100644
--- a/freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.c
+++ b/freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.c
@@ -97,7 +97,6 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc,
struct ieee80211_node *ni;
uint32_t rxdw0;
struct mbuf *m, *m1;
- int8_t rssi = 0, nf;
int infosz, pktlen, shift, error;
/* Dump Rx descriptor. */
@@ -164,12 +163,11 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc,
rx_data->m = m1;
m->m_pkthdr.len = m->m_len = pktlen + infosz + shift;
- nf = RTWN_NOISE_FLOOR;
- ni = rtwn_rx_common(sc, m, rx_desc, &rssi);
+ ni = rtwn_rx_common(sc, m, rx_desc);
RTWN_DPRINTF(sc, RTWN_DEBUG_RECV,
- "%s: Rx frame len %d, infosz %d, shift %d, rssi %d\n",
- __func__, pktlen, infosz, shift, rssi);
+ "%s: Rx frame len %d, infosz %d, shift %d\n",
+ __func__, pktlen, infosz, shift);
/* Update RX descriptor. */
rtwn_pci_setup_rx_desc(pc, rx_desc, rx_data->paddr, MJUMPAGESIZE,
@@ -178,11 +176,11 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc,
/* Send the frame to the 802.11 layer. */
RTWN_UNLOCK(sc);
if (ni != NULL) {
- (void)ieee80211_input(ni, m, rssi - nf, nf);
+ (void)ieee80211_input_mimo(ni, m);
/* Node is no longer needed. */
ieee80211_free_node(ni);
} else
- (void)ieee80211_input_all(ic, m, rssi - nf, nf);
+ (void)ieee80211_input_mimo_all(ic, m);
RTWN_LOCK(sc);
@@ -284,17 +282,6 @@ rtwn_pci_rx_done(struct rtwn_softc *sc)
ring->cur = (ring->cur + 1) % RTWN_PCI_RX_LIST_COUNT;
}
-
- /* Finished receive; age anything left on the FF queue by a little bump */
- /*
- * XXX TODO: just make this a callout timer schedule so we can
- * flush the FF staging queue if we're approaching idle.
- */
-#ifdef IEEE80211_SUPPORT_SUPERG
- if (!(sc->sc_flags & RTWN_FW_LOADED) ||
- sc->sc_ratectl != RTWN_RATECTL_NET80211)
- rtwn_cmd_sleepable(sc, NULL, 0, rtwn_ff_flush_all);
-#endif
}
void
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e.h b/freebsd/sys/dev/rtwn/rtl8188e/r88e.h
index 999ab400..1c03ddd3 100644
--- a/freebsd/sys/dev/rtwn/rtl8188e/r88e.h
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e.h
@@ -85,6 +85,8 @@ void r88e_ratectl_tx_complete(struct rtwn_softc *, uint8_t *, int);
void r88e_handle_c2h_report(struct rtwn_softc *, uint8_t *, int);
int8_t r88e_get_rssi_cck(struct rtwn_softc *, void *);
int8_t r88e_get_rssi_ofdm(struct rtwn_softc *, void *);
+void r88e_get_rx_stats(struct rtwn_softc *, struct ieee80211_rx_stats *,
+ const void *, const void *);
/* r88e_tx.c */
void r88e_tx_enable_ampdu(void *, int);
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_fw.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_fw.c
index 409084f6..fb7743ed 100644
--- a/freebsd/sys/dev/rtwn/rtl8188e/r88e_fw.c
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_fw.c
@@ -71,7 +71,7 @@ r88e_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/rtl8188e/r88e_rx.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c
index 464542b4..acffb40e 100644
--- a/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/if_rtwn_debug.h>
#include <dev/rtwn/if_rtwn_ridx.h>
+#include <dev/rtwn/rtl8192c/r92c.h>
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_rx_desc.h>
@@ -211,3 +212,19 @@ r88e_get_rssi_ofdm(struct rtwn_softc *sc, void *physt)
return (rssi);
}
+
+void
+r88e_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
+ const void *desc, const void *physt_ptr)
+{
+ const struct r88e_rx_phystat *physt = physt_ptr;
+
+ r92c_get_rx_stats(sc, rxs, desc, physt_ptr);
+
+ if (!sc->sc_ht40) { /* XXX center channel */
+ rxs->r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
+ rxs->c_ieee = le16toh(physt->chan);
+ rxs->c_freq = ieee80211_ieee2mhz(rxs->c_ieee,
+ IEEE80211_CHAN_2GHZ);
+ }
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
index 4d5452be..f834fb38 100644
--- a/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
+++ b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
@@ -129,6 +129,7 @@ r88eu_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 = r88e_get_rx_stats;
sc->sc_get_rssi_cck = r88e_get_rssi_cck;
sc->sc_get_rssi_ofdm = r88e_get_rssi_ofdm;
sc->sc_classify_intr = r88eu_classify_intr;
@@ -147,6 +148,7 @@ r88eu_attach(struct rtwn_usb_softc *uc)
sc->sc_fw_reset = r88e_fw_reset;
sc->sc_fw_download_enable = r88e_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 = r88e_iq_calib; /* XXX TODO */
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 */
diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a.h b/freebsd/sys/dev/rtwn/rtl8812a/r12a.h
index ec1d61e1..e8de45aa 100644
--- a/freebsd/sys/dev/rtwn/rtl8812a/r12a.h
+++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a.h
@@ -128,6 +128,8 @@ void r12a_ratectl_tx_complete(struct rtwn_softc *, uint8_t *, int);
void r12a_handle_c2h_report(struct rtwn_softc *, uint8_t *, int);
int r12a_check_frame_checksum(struct rtwn_softc *, struct mbuf *);
uint8_t r12a_rx_radiotap_flags(const void *);
+void r12a_get_rx_stats(struct rtwn_softc *, struct ieee80211_rx_stats *,
+ const void *, const void *);
/* r12a_tx.c */
void r12a_fill_tx_desc(struct rtwn_softc *, struct ieee80211_node *,
diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a_beacon.c b/freebsd/sys/dev/rtwn/rtl8812a/r12a_beacon.c
index 37b1a183..67714442 100644
--- a/freebsd/sys/dev/rtwn/rtl8812a/r12a_beacon.c
+++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a_beacon.c
@@ -79,6 +79,8 @@ r12a_beacon_init(struct rtwn_softc *sc, void *buf, int id)
txd->txdw3 = htole32(R12A_TXDW3_DRVRATE);
txd->txdw3 |= htole32(SM(R12A_TXDW3_SEQ_SEL, id));
+ txd->txdw4 = htole32(SM(R12A_TXDW4_DATARATE, RTWN_RIDX_CCK1));
+
txd->txdw6 = htole32(SM(R21A_TXDW6_MBSSID, id));
}
diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a_fw.c b/freebsd/sys/dev/rtwn/rtl8812a/r12a_fw.c
index 12a3d855..f3bbc099 100644
--- a/freebsd/sys/dev/rtwn/rtl8812a/r12a_fw.c
+++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a_fw.c
@@ -70,14 +70,14 @@ void
r12a_fw_reset(struct rtwn_softc *sc, int reason)
{
/* Reset MCU IO wrapper. */
- rtwn_setbits_1(sc, R92C_RSV_CTRL, 0x02, 0);
+ rtwn_setbits_1(sc, R92C_RSV_CTRL, R92C_RSV_CTRL_WLOCK_00, 0);
rtwn_setbits_1(sc, R92C_RSV_CTRL + 1, 0x08, 0);
rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN,
R92C_SYS_FUNC_EN_CPUEN, 0, 1);
/* Enable MCU IO wrapper. */
- rtwn_setbits_1(sc, R92C_RSV_CTRL, 0x02, 0);
+ rtwn_setbits_1(sc, R92C_RSV_CTRL, R92C_RSV_CTRL_WLOCK_00, 0);
rtwn_setbits_1(sc, R92C_RSV_CTRL + 1, 0, 0x08);
rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN,
diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a_rx.c b/freebsd/sys/dev/rtwn/rtl8812a/r12a_rx.c
index 049717a4..b9c3bbf8 100644
--- a/freebsd/sys/dev/rtwn/rtl8812a/r12a_rx.c
+++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a_rx.c
@@ -231,10 +231,99 @@ r12a_rx_radiotap_flags(const void *buf)
if (!(stat->rxdw4 & htole32(R12A_RXDW4_SPLCP)))
return (0);
- rate = MS(le32toh(stat->rxdw3), R92C_RXDW3_RATE);
+ rate = MS(le32toh(stat->rxdw3), R12A_RXDW3_RATE);
if (RTWN_RATE_IS_CCK(rate))
flags = IEEE80211_RADIOTAP_F_SHORTPRE;
else
flags = IEEE80211_RADIOTAP_F_SHORTGI;
return (flags);
}
+
+void
+r12a_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;
+ const struct r12a_rx_phystat *physt = physt_ptr;
+ uint32_t rxdw0, rxdw1, rxdw3, rxdw4;
+ uint8_t rate;
+
+ rxdw0 = le32toh(stat->rxdw0);
+ rxdw1 = le32toh(stat->rxdw1);
+ rxdw3 = le32toh(stat->rxdw3);
+ rxdw4 = le32toh(stat->rxdw4);
+ rate = MS(rxdw3, R12A_RXDW3_RATE);
+
+ /* TODO: STBC */
+ if (rxdw4 & R12A_RXDW4_LDPC)
+ rxs->c_pktflags |= IEEE80211_RX_F_LDPC;
+ if (rxdw1 & R12A_RXDW1_AMPDU) {
+ if (rxdw0 & R92C_RXDW0_PHYST)
+ rxs->c_pktflags |= IEEE80211_RX_F_AMPDU;
+ else
+ rxs->c_pktflags |= IEEE80211_RX_F_AMPDU_MORE;
+ }
+
+ if ((rxdw4 & R12A_RXDW4_SPLCP) && rate >= RTWN_RIDX_MCS(0))
+ rxs->c_pktflags |= IEEE80211_RX_F_SHORTGI;
+
+ switch (MS(rxdw4, R12A_RXDW4_BW)) {
+ case R12A_RXDW4_BW20:
+ rxs->c_width = IEEE80211_RX_FW_20MHZ;
+ break;
+ case R12A_RXDW4_BW40:
+ rxs->c_width = IEEE80211_RX_FW_40MHZ;
+ break;
+ case R12A_RXDW4_BW80:
+ rxs->c_width = IEEE80211_RX_FW_80MHZ;
+ break;
+ default:
+ break;
+ }
+
+ if (RTWN_RATE_IS_CCK(rate))
+ rxs->c_phytype = IEEE80211_RX_FP_11B;
+ else {
+ int is5ghz;
+
+ /* XXX magic */
+ /* XXX check with RTL8812AU */
+ is5ghz = (physt->cfosho[2] != 0x01);
+
+ if (rate < RTWN_RIDX_MCS(0)) {
+ if (is5ghz)
+ rxs->c_phytype = IEEE80211_RX_FP_11A;
+ else
+ rxs->c_phytype = IEEE80211_RX_FP_11G;
+ } else {
+ if (is5ghz)
+ rxs->c_phytype = IEEE80211_RX_FP_11NA;
+ 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. */
+ /* TODO: VHT rates */
+ rxs->c_rate = IEEE80211_RATE_MCS | (rate - 12);
+ rxs->c_pktflags |= IEEE80211_RX_F_HT;
+ }
+
+ /*
+ * XXX always zero for RTL8821AU
+ * (vendor driver does not check this field)
+ */
+#if 0
+ rxs->r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
+ rxs->c_ieee = MS(le16toh(physt->phyw1), R12A_PHYW1_CHAN);
+ rxs->c_freq = ieee80211_ieee2mhz(rxs->c_ieee,
+ (rxs->c_ieee < 36) ? IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ);
+#endif
+}
diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h b/freebsd/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h
index 8642ca85..c3d19527 100644
--- a/freebsd/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h
+++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a_rx_desc.h
@@ -34,18 +34,26 @@
/* Rx MAC descriptor defines (chip-specific). */
/* Rx dword 1 */
#define R12A_RXDW1_AMSDU 0x00002000
+#define R12A_RXDW1_AMPDU 0x00008000
#define R12A_RXDW1_CKSUM_ERR 0x00100000
#define R12A_RXDW1_IPV6 0x00200000
#define R12A_RXDW1_UDP 0x00400000
#define R12A_RXDW1_CKSUM 0x00800000
/* Rx dword 2 */
#define R12A_RXDW2_RPT_C2H 0x10000000
+/* Rx dword 3 */
+#define R12A_RXDW3_RATE_M 0x0000007f
+#define R12A_RXDW3_RATE_S 0
/* Rx dword 4 */
#define R12A_RXDW4_SPLCP 0x00000001
#define R12A_RXDW4_LDPC 0x00000002
#define R12A_RXDW4_STBC 0x00000004
#define R12A_RXDW4_BW_M 0x00000030
#define R12A_RXDW4_BW_S 4
+#define R12A_RXDW4_BW20 0
+#define R12A_RXDW4_BW40 1
+#define R12A_RXDW4_BW80 2
+#define R12A_RXDW4_BW160 3
/* Rx PHY descriptor. */
struct r12a_rx_phystat {
diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c b/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c
index f7bd3a8e..40d54634 100644
--- a/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c
+++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c
@@ -216,6 +216,17 @@ r12a_tx_set_sgi(struct rtwn_softc *sc, void *buf, struct ieee80211_node *ni)
txd->txdw5 |= htole32(R12A_TXDW5_DATA_SHORT);
}
+static void
+r12a_tx_set_ldpc(struct rtwn_softc *sc, struct r12a_tx_desc *txd,
+ struct ieee80211_node *ni)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+
+ if ((vap->iv_flags_ht & IEEE80211_FHT_LDPC_TX) &&
+ (ni->ni_htcap & IEEE80211_HTCAP_LDPC))
+ txd->txdw5 |= htole32(R12A_TXDW5_DATA_LDPC);
+}
+
void
r12a_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
struct mbuf *m, void *buf, uint8_t ridx, int maxretry)
@@ -286,6 +297,7 @@ r12a_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
if (ridx >= RTWN_RIDX_MCS(0)) {
r12a_tx_set_ht40(sc, txd, ni);
r12a_tx_set_sgi(sc, txd, ni);
+ r12a_tx_set_ldpc(sc, txd, ni);
prot = ic->ic_htprotmode;
} else if (ic->ic_flags & IEEE80211_F_USEPROT)
prot = ic->ic_protmode;
diff --git a/freebsd/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c b/freebsd/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
index 684076eb..97d966f0 100644
--- a/freebsd/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
+++ b/freebsd/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
@@ -170,7 +170,15 @@ r12a_read_chipid_vendor(struct rtwn_softc *sc, uint32_t reg_sys_cfg)
static void
r12au_adj_devcaps(struct rtwn_softc *sc)
{
- /* TODO: LDPC, STBC etc */
+ struct r12a_softc *rs = sc->sc_priv;
+ struct ieee80211com *ic = &sc->sc_ic;
+
+ if (rs->chip & R12A_CHIP_C_CUT) {
+ ic->ic_htcaps |= IEEE80211_HTCAP_LDPC |
+ IEEE80211_HTC_TXLDPC;
+ }
+
+ /* TODO: STBC, VHT etc */
}
void
@@ -192,6 +200,7 @@ r12au_attach(struct rtwn_usb_softc *uc)
sc->sc_dump_tx_desc = r12au_dump_tx_desc;
sc->sc_tx_radiotap_flags = r12a_tx_radiotap_flags;
sc->sc_rx_radiotap_flags = r12a_rx_radiotap_flags;
+ sc->sc_get_rx_stats = r12a_get_rx_stats;
sc->sc_get_rssi_cck = r88e_get_rssi_cck;
sc->sc_get_rssi_ofdm = r88e_get_rssi_ofdm;
sc->sc_classify_intr = r12au_classify_intr;
@@ -208,6 +217,7 @@ r12au_attach(struct rtwn_usb_softc *uc)
sc->sc_fw_reset = r12a_fw_reset;
sc->sc_fw_download_enable = r12a_fw_download_enable;
#endif
+ sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = r12a_set_page_size;
sc->sc_lc_calib = r12a_lc_calib;
sc->sc_iq_calib = r12a_iq_calib;
diff --git a/freebsd/sys/dev/rtwn/rtl8821a/r21a_init.c b/freebsd/sys/dev/rtwn/rtl8821a/r21a_init.c
index a3bcde77..e2c3972f 100644
--- a/freebsd/sys/dev/rtwn/rtl8821a/r21a_init.c
+++ b/freebsd/sys/dev/rtwn/rtl8821a/r21a_init.c
@@ -176,7 +176,7 @@ r21a_power_on(struct rtwn_softc *sc)
R92C_CR_CALTMR_EN));
if (rtwn_read_4(sc, R92C_SYS_CFG) & R92C_SYS_CFG_TRP_BT_EN)
- RTWN_CHK(rtwn_setbits_1(sc, 0x07C, 0, 0x40));
+ RTWN_CHK(rtwn_setbits_1(sc, R92C_LDO_SWR_CTRL, 0, 0x40));
return (0);
#undef RTWN_CHK
diff --git a/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c b/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
index 6f7129f8..145aca21 100644
--- a/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
+++ b/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
@@ -159,10 +159,11 @@ r21au_adj_devcaps(struct rtwn_softc *sc)
struct ieee80211com *ic = &sc->sc_ic;
struct r12a_softc *rs = sc->sc_priv;
+ ic->ic_htcaps |= IEEE80211_HTC_TXLDPC;
if (rs->rs_radar != 0)
ic->ic_caps |= IEEE80211_C_DFS;
- /* TODO: LDPC etc */
+ /* TODO: VHT */
}
void
@@ -184,6 +185,7 @@ r21au_attach(struct rtwn_usb_softc *uc)
sc->sc_dump_tx_desc = r12au_dump_tx_desc;
sc->sc_tx_radiotap_flags = r12a_tx_radiotap_flags;
sc->sc_rx_radiotap_flags = r12a_rx_radiotap_flags;
+ sc->sc_get_rx_stats = r12a_get_rx_stats;
sc->sc_get_rssi_cck = r21a_get_rssi_cck;
sc->sc_get_rssi_ofdm = r88e_get_rssi_ofdm;
sc->sc_classify_intr = r12au_classify_intr;
@@ -201,6 +203,7 @@ r21au_attach(struct rtwn_usb_softc *uc)
sc->sc_fw_reset = r21a_fw_reset;
sc->sc_fw_download_enable = r12a_fw_download_enable;
#endif
+ sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = rtwn_nop_int_softc;
sc->sc_lc_calib = rtwn_nop_softc; /* XXX not used */
sc->sc_iq_calib = r12a_iq_calib;
diff --git a/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h b/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h
index 48a4d6e5..ee6d9137 100644
--- a/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h
+++ b/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h
@@ -21,12 +21,14 @@
*/
void r92cu_attach(struct rtwn_usb_softc *);
+void r92eu_attach(struct rtwn_usb_softc *);
void r88eu_attach(struct rtwn_usb_softc *);
void r12au_attach(struct rtwn_usb_softc *);
void r21au_attach(struct rtwn_usb_softc *);
enum {
RTWN_CHIP_RTL8192CU,
+ RTWN_CHIP_RTL8192EU,
RTWN_CHIP_RTL8188EU,
RTWN_CHIP_RTL8812AU,
RTWN_CHIP_RTL8821AU,
@@ -92,7 +94,6 @@ static const STRUCT_USB_HOST_ID rtwn_devs[] = {
RTWN_RTL8192CU_DEV(REALTEK, RTL8191CU),
RTWN_RTL8192CU_DEV(REALTEK, RTL8192CE),
RTWN_RTL8192CU_DEV(REALTEK, RTL8192CU),
- RTWN_RTL8192CU_DEV(REALTEK, RTL8192CU_1),
RTWN_RTL8192CU_DEV(SITECOMEU, RTL8188CU_1),
RTWN_RTL8192CU_DEV(SITECOMEU, RTL8188CU_2),
RTWN_RTL8192CU_DEV(SITECOMEU, RTL8192CU),
@@ -101,6 +102,15 @@ static const STRUCT_USB_HOST_ID rtwn_devs[] = {
RTWN_RTL8192CU_DEV(ZYXEL, RTL8192CU),
#undef RTWN_RTL8192CU_DEV
+ /* RTL8192EU */
+#define RTWN_RTL8192EU_DEV(v,p) \
+ { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, RTWN_CHIP_RTL8192EU) }
+ RTWN_RTL8192EU_DEV(DLINK, DWA131E1),
+ RTWN_RTL8192EU_DEV(REALTEK, RTL8192EU),
+ RTWN_RTL8192EU_DEV(TPLINK, WN822NV4),
+ RTWN_RTL8192EU_DEV(TPLINK, WN823NV2),
+#undef RTWN_RTL8192EU_DEV
+
/* RTL8188EU */
#define RTWN_RTL8188EU_DEV(v,p) \
{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, RTWN_CHIP_RTL8188EU) }
@@ -148,6 +158,7 @@ typedef void (*chip_usb_attach)(struct rtwn_usb_softc *);
static const chip_usb_attach rtwn_chip_usb_attach[RTWN_CHIP_MAX_USB] = {
[RTWN_CHIP_RTL8192CU] = r92cu_attach,
+ [RTWN_CHIP_RTL8192EU] = r92eu_attach,
[RTWN_CHIP_RTL8188EU] = r88eu_attach,
[RTWN_CHIP_RTL8812AU] = r12au_attach,
[RTWN_CHIP_RTL8821AU] = r21au_attach
diff --git a/freebsd/sys/dev/rtwn/usb/rtwn_usb_ep.c b/freebsd/sys/dev/rtwn/usb/rtwn_usb_ep.c
index a1fafb46..b75aa3b9 100644
--- a/freebsd/sys/dev/rtwn/usb/rtwn_usb_ep.c
+++ b/freebsd/sys/dev/rtwn/usb/rtwn_usb_ep.c
@@ -60,7 +60,7 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/usb/r92cu_reg.h>
-static struct usb_config rtwn_config[RTWN_N_TRANSFER] = {
+static const struct usb_config rtwn_config_common[RTWN_N_TRANSFER] = {
[RTWN_BULK_RX] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
@@ -163,6 +163,7 @@ rtwn_usb_setup_queues(struct rtwn_usb_softc *uc)
int
rtwn_usb_setup_endpoints(struct rtwn_usb_softc *uc)
{
+ struct usb_config *rtwn_config;
struct rtwn_softc *sc = &uc->uc_sc;
const uint8_t iface_index = RTWN_IFACE_INDEX;
struct usb_endpoint *ep, *ep_end;
@@ -199,6 +200,9 @@ rtwn_usb_setup_endpoints(struct rtwn_usb_softc *uc)
return (EINVAL);
}
+ rtwn_config = malloc(sizeof(rtwn_config_common), M_TEMP, M_WAITOK);
+ memcpy(rtwn_config, rtwn_config_common, sizeof(rtwn_config_common));
+
/* NB: keep in sync with rtwn_dma_init(). */
rtwn_config[RTWN_BULK_TX_VO].endpoint = addr[0];
switch (uc->ntx) {
@@ -226,6 +230,8 @@ rtwn_usb_setup_endpoints(struct rtwn_usb_softc *uc)
rtwn_config[RTWN_BULK_RX].bufsize = sc->rx_dma_size + 1024;
error = usbd_transfer_setup(uc->uc_udev, &iface_index,
uc->uc_xfer, rtwn_config, RTWN_N_TRANSFER, uc, &sc->sc_mtx);
+ free(rtwn_config, M_TEMP);
+
if (error) {
device_printf(sc->sc_dev, "could not allocate USB transfers, "
"err=%s\n", usbd_errstr(error));
diff --git a/freebsd/sys/dev/rtwn/usb/rtwn_usb_rx.c b/freebsd/sys/dev/rtwn/usb/rtwn_usb_rx.c
index 8795e16d..4afa71af 100644
--- a/freebsd/sys/dev/rtwn/usb/rtwn_usb_rx.c
+++ b/freebsd/sys/dev/rtwn/usb/rtwn_usb_rx.c
@@ -238,7 +238,7 @@ rtwn_report_intr(struct rtwn_usb_softc *uc, struct usb_xfer *xfer,
}
static struct ieee80211_node *
-rtwn_rx_frame(struct rtwn_softc *sc, struct mbuf *m, int8_t *rssi)
+rtwn_rx_frame(struct rtwn_softc *sc, struct mbuf *m)
{
struct r92c_rx_stat stat;
@@ -246,7 +246,7 @@ rtwn_rx_frame(struct rtwn_softc *sc, struct mbuf *m, int8_t *rssi)
m_copydata(m, 0, sizeof(struct r92c_rx_stat), (caddr_t)&stat);
m_adj(m, sizeof(struct r92c_rx_stat));
- return (rtwn_rx_common(sc, m, &stat, rssi));
+ return (rtwn_rx_common(sc, m, &stat));
}
void
@@ -258,7 +258,6 @@ rtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
struct ieee80211_node *ni;
struct mbuf *m = NULL, *next;
struct rtwn_data *data;
- int8_t nf, rssi;
RTWN_ASSERT_LOCKED(sc);
@@ -293,19 +292,15 @@ tr_setup:
next = m->m_next;
m->m_next = NULL;
- ni = rtwn_rx_frame(sc, m, &rssi);
+ ni = rtwn_rx_frame(sc, m);
RTWN_UNLOCK(sc);
- nf = RTWN_NOISE_FLOOR;
if (ni != NULL) {
- if (ni->ni_flags & IEEE80211_NODE_HT)
- m->m_flags |= M_AMPDU;
- (void)ieee80211_input(ni, m, rssi - nf, nf);
+ (void)ieee80211_input_mimo(ni, m);
ieee80211_free_node(ni);
} else {
- (void)ieee80211_input_all(ic, m,
- rssi - nf, nf);
+ (void)ieee80211_input_mimo_all(ic, m);
}
RTWN_LOCK(sc);
m = next;
@@ -326,17 +321,6 @@ tr_setup:
break;
}
finish:
- /* Finished receive; age anything left on the FF queue by a little bump */
- /*
- * XXX TODO: just make this a callout timer schedule so we can
- * flush the FF staging queue if we're approaching idle.
- */
-#ifdef IEEE80211_SUPPORT_SUPERG
- if (!(sc->sc_flags & RTWN_FW_LOADED) ||
- sc->sc_ratectl != RTWN_RATECTL_NET80211)
- rtwn_cmd_sleepable(sc, NULL, 0, rtwn_ff_flush_all);
-#endif
-
/* Kick-start more transmit in case we stalled */
rtwn_start(sc);
}