summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/rtwn
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-07 14:56:50 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:37 +0200
commitc37f9fba70085fedc8eede7559489d2321393005 (patch)
tree042455ebf1fa89a277a825f72e1ed805d0b4d296 /freebsd/sys/dev/rtwn
parentUpdate to FreeBSD head 2017-06-01 (diff)
downloadrtems-libbsd-c37f9fba70085fedc8eede7559489d2321393005.tar.bz2
Update to FreeBSD head 2017-08-01
Git mirror commit f5002f5e5f78cae9f0269d812dc0aedb0339312c. Update #3472.
Diffstat (limited to 'freebsd/sys/dev/rtwn')
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwn_rx.c22
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwnreg.h54
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwnvar.h2
-rw-r--r--freebsd/sys/dev/rtwn/pci/rtwn_pci_attach.c3
-rw-r--r--freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.c28
-rw-r--r--freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.h2
-rw-r--r--freebsd/sys/dev/rtwn/pci/rtwn_pci_var.h5
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c28
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_priv.h43
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_defs.h2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_image.h6
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c2
-rw-r--r--freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.c57
-rw-r--r--freebsd/sys/dev/rtwn/usb/rtwn_usb_ep.c11
-rw-r--r--freebsd/sys/dev/rtwn/usb/rtwn_usb_rx.c191
-rw-r--r--freebsd/sys/dev/rtwn/usb/rtwn_usb_tx.c3
-rw-r--r--freebsd/sys/dev/rtwn/usb/rtwn_usb_var.h14
20 files changed, 323 insertions, 156 deletions
diff --git a/freebsd/sys/dev/rtwn/if_rtwn_rx.c b/freebsd/sys/dev/rtwn/if_rtwn_rx.c
index 5dd72605..7b3f1c2e 100644
--- a/freebsd/sys/dev/rtwn/if_rtwn_rx.c
+++ b/freebsd/sys/dev/rtwn/if_rtwn_rx.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/if_rtwn_rx.h>
#include <dev/rtwn/rtl8192c/r92c_reg.h>
-#include <dev/rtwn/rtl8192c/r92c_rx_desc.h>
void
@@ -192,7 +191,8 @@ rtwn_get_tsf(struct rtwn_softc *sc, uint64_t *buf, int id)
}
static uint64_t
-rtwn_extend_rx_tsf(struct rtwn_softc *sc, const struct r92c_rx_stat *stat)
+rtwn_extend_rx_tsf(struct rtwn_softc *sc,
+ const struct rtwn_rx_stat_common *stat)
{
uint64_t tsft;
uint32_t rxdw3, tsfl, tsfl_curr;
@@ -200,7 +200,7 @@ rtwn_extend_rx_tsf(struct rtwn_softc *sc, const struct r92c_rx_stat *stat)
rxdw3 = le32toh(stat->rxdw3);
tsfl = le32toh(stat->tsf_low);
- id = MS(rxdw3, R92C_RXDW3_BSSID_FIT);
+ id = MS(rxdw3, RTWN_RXDW3_BSSID01_FIT);
switch (id) {
case 1:
@@ -243,7 +243,7 @@ rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc)
struct ieee80211_frame_min *wh;
struct ieee80211_rx_stats rxs;
struct rtwn_node *un;
- struct r92c_rx_stat *stat;
+ struct rtwn_rx_stat_common *stat;
void *physt;
uint32_t rxdw0;
int8_t rssi;
@@ -252,10 +252,10 @@ rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc)
stat = desc;
rxdw0 = le32toh(stat->rxdw0);
- 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);
+ cipher = MS(rxdw0, RTWN_RXDW0_CIPHER);
+ infosz = MS(rxdw0, RTWN_RXDW0_INFOSZ) * 8;
+ pktlen = MS(rxdw0, RTWN_RXDW0_PKTLEN);
+ shift = MS(rxdw0, RTWN_RXDW0_SHIFT);
wh = (struct ieee80211_frame_min *)(mtodo(m, shift + infosz));
if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
@@ -270,7 +270,7 @@ rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc)
ni = NULL;
un = RTWN_NODE(ni);
- if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST))
+ if (infosz != 0 && (rxdw0 & RTWN_RXDW0_PHYST))
physt = (void *)mtodo(m, shift);
else
physt = (un != NULL) ? &un->last_physt : &sc->last_physt;
@@ -286,7 +286,7 @@ rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc)
/* Add some common bits. */
/* NB: should not happen. */
- if (rxdw0 & R92C_RXDW0_CRCERR)
+ if (rxdw0 & RTWN_RXDW0_CRCERR)
rxs.c_pktflags |= IEEE80211_RX_F_FAIL_FCSCRC;
rxs.r_flags |= IEEE80211_R_TSF_START; /* XXX undocumented */
@@ -300,7 +300,7 @@ rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc)
/* 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)) {
+ if (un != NULL && infosz != 0 && (rxdw0 & RTWN_RXDW0_PHYST)) {
/* Update our average RSSI. */
rtwn_update_avgrssi(sc, un, rssi, is_cck);
}
diff --git a/freebsd/sys/dev/rtwn/if_rtwnreg.h b/freebsd/sys/dev/rtwn/if_rtwnreg.h
index 9dc830a2..00903d88 100644
--- a/freebsd/sys/dev/rtwn/if_rtwnreg.h
+++ b/freebsd/sys/dev/rtwn/if_rtwnreg.h
@@ -18,6 +18,9 @@
* $FreeBSD$
*/
+#ifndef IF_RTWNREG_H
+#define IF_RTWNREG_H
+
#define R92C_MIN_TX_PWR 0x00
#define R92C_MAX_TX_PWR 0x3f
@@ -48,6 +51,55 @@ struct rtwn_tx_desc_common {
} txdw7;
} __packed __attribute__((aligned(4)));
+/* Common part of Rx descriptor. */
+struct rtwn_rx_stat_common {
+ uint32_t rxdw0;
+#define RTWN_RXDW0_PKTLEN_M 0x00003fff
+#define RTWN_RXDW0_PKTLEN_S 0
+#define RTWN_RXDW0_CRCERR 0x00004000
+#define RTWN_RXDW0_ICVERR 0x00008000
+#define RTWN_RXDW0_INFOSZ_M 0x000f0000
+#define RTWN_RXDW0_INFOSZ_S 16
+#define RTWN_RXDW0_CIPHER_M 0x00700000
+#define RTWN_RXDW0_CIPHER_S 20
+#define RTWN_RXDW0_QOS 0x00800000
+#define RTWN_RXDW0_SHIFT_M 0x03000000
+#define RTWN_RXDW0_SHIFT_S 24
+#define RTWN_RXDW0_PHYST 0x04000000
+#define RTWN_RXDW0_SWDEC 0x08000000
+#define RTWN_RXDW0_LS 0x10000000
+#define RTWN_RXDW0_FS 0x20000000
+#define RTWN_RXDW0_EOR 0x40000000
+#define RTWN_RXDW0_OWN 0x80000000
+
+ uint32_t rxdw1;
+#define RTWN_RXDW1_AMSDU 0x00002000
+#define RTWN_RXDW1_MC 0x40000000
+#define RTWN_RXDW1_BC 0x80000000
+
+ uint32_t rxdw2;
+ uint32_t rxdw3;
+#define RTWN_RXDW3_HTC 0x00000400
+#define RTWN_RXDW3_BSSID01_FIT_M 0x00003000
+#define RTWN_RXDW3_BSSID01_FIT_S 12
+
+ uint32_t rxdw4;
+ uint32_t tsf_low;
+} __packed __attribute__((aligned(4)));
+
+/* Rx descriptor for PCIe devices. */
+struct rtwn_rx_stat_pci {
+ 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)));
+
/*
* Macros to access subfields in registers.
*/
@@ -116,3 +168,5 @@ rtwn_chan2centieee(const struct ieee80211_channel *c)
return (chan);
}
+
+#endif /* IF_RTWNREG_H */
diff --git a/freebsd/sys/dev/rtwn/if_rtwnvar.h b/freebsd/sys/dev/rtwn/if_rtwnvar.h
index d8754024..3ebcba52 100644
--- a/freebsd/sys/dev/rtwn/if_rtwnvar.h
+++ b/freebsd/sys/dev/rtwn/if_rtwnvar.h
@@ -25,8 +25,6 @@
#define RTWN_TX_DESC_SIZE 64
-#define RTWN_TXBUFSZ (16 * 1024)
-
#define RTWN_BCN_MAX_SIZE 512
#define RTWN_CAM_ENTRY_LIMIT 64
diff --git a/freebsd/sys/dev/rtwn/pci/rtwn_pci_attach.c b/freebsd/sys/dev/rtwn/pci/rtwn_pci_attach.c
index 85ede40a..c121c5a5 100644
--- a/freebsd/sys/dev/rtwn/pci/rtwn_pci_attach.c
+++ b/freebsd/sys/dev/rtwn/pci/rtwn_pci_attach.c
@@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/pci/rtwn_pci_tx.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
-#include <dev/rtwn/rtl8192c/pci/r92ce_rx_desc.h>
static device_probe_t rtwn_pci_probe;
@@ -135,7 +134,7 @@ rtwn_pci_alloc_rx_list(struct rtwn_softc *sc)
int i, error;
/* Allocate Rx descriptors. */
- size = sizeof(struct r92ce_rx_stat) * RTWN_PCI_RX_LIST_COUNT;
+ size = sizeof(struct rtwn_rx_stat_pci) * RTWN_PCI_RX_LIST_COUNT;
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
size, 1, size, 0, NULL, NULL, &rx_ring->desc_dmat);
diff --git a/freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.c b/freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.c
index 150500d8..1934b741 100644
--- a/freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.c
+++ b/freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.c
@@ -58,8 +58,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/pci/rtwn_pci_var.h>
#include <dev/rtwn/pci/rtwn_pci_rx.h>
-#include <dev/rtwn/rtl8192c/pci/r92ce_rx_desc.h>
-
void
rtwn_pci_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs,
@@ -73,21 +71,21 @@ rtwn_pci_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs,
}
void
-rtwn_pci_setup_rx_desc(struct rtwn_pci_softc *pc, struct r92ce_rx_stat *desc,
- bus_addr_t addr, size_t len, int idx)
+rtwn_pci_setup_rx_desc(struct rtwn_pci_softc *pc,
+ struct rtwn_rx_stat_pci *desc, bus_addr_t addr, size_t len, int idx)
{
memset(desc, 0, sizeof(*desc));
- desc->rxdw0 = htole32(SM(R92C_RXDW0_PKTLEN, len) |
- ((idx == RTWN_PCI_RX_LIST_COUNT - 1) ? R92C_RXDW0_EOR : 0));
+ desc->rxdw0 = htole32(SM(RTWN_RXDW0_PKTLEN, len) |
+ ((idx == RTWN_PCI_RX_LIST_COUNT - 1) ? RTWN_RXDW0_EOR : 0));
desc->rxbufaddr = htole32(addr);
bus_space_barrier(pc->pc_st, pc->pc_sh, 0, pc->pc_mapsize,
BUS_SPACE_BARRIER_WRITE);
- desc->rxdw0 |= htole32(R92C_RXDW0_OWN);
+ desc->rxdw0 |= htole32(RTWN_RXDW0_OWN);
}
static void
-rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc,
+rtwn_pci_rx_frame(struct rtwn_softc *sc, struct rtwn_rx_stat_pci *rx_desc,
int desc_idx)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
@@ -109,18 +107,18 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc,
le32toh(rx_desc->rxbufaddr), le32toh(rx_desc->rxbufaddr64));
rxdw0 = le32toh(rx_desc->rxdw0);
- if (__predict_false(rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR))) {
+ if (__predict_false(rxdw0 & (RTWN_RXDW0_CRCERR | RTWN_RXDW0_ICVERR))) {
/*
* This should not happen since we setup our Rx filter
* to not receive these frames.
*/
RTWN_DPRINTF(sc, RTWN_DEBUG_RECV,
"%s: RX flags error (%s)\n", __func__,
- rxdw0 & R92C_RXDW0_CRCERR ? "CRC" : "ICV");
+ rxdw0 & RTWN_RXDW0_CRCERR ? "CRC" : "ICV");
goto fail;
}
- pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
+ pktlen = MS(rxdw0, RTWN_RXDW0_PKTLEN);
if (__predict_false(pktlen < sizeof(struct ieee80211_frame_ack) ||
pktlen > MJUMPAGESIZE)) {
RTWN_DPRINTF(sc, RTWN_DEBUG_RECV,
@@ -128,8 +126,8 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc,
goto fail;
}
- infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
- shift = MS(rxdw0, R92C_RXDW0_SHIFT);
+ infosz = MS(rxdw0, RTWN_RXDW0_INFOSZ) * 8;
+ shift = MS(rxdw0, RTWN_RXDW0_SHIFT);
m1 = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
if (__predict_false(m1 == NULL)) {
@@ -270,9 +268,9 @@ rtwn_pci_rx_done(struct rtwn_softc *sc)
bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_POSTREAD);
for (;;) {
- struct r92ce_rx_stat *rx_desc = &ring->desc[ring->cur];
+ struct rtwn_rx_stat_pci *rx_desc = &ring->desc[ring->cur];
- if (le32toh(rx_desc->rxdw0) & R92C_RXDW0_OWN)
+ if (le32toh(rx_desc->rxdw0) & RTWN_RXDW0_OWN)
break;
rtwn_pci_rx_frame(sc, rx_desc, ring->cur);
diff --git a/freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.h b/freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.h
index 265d32d8..30dd785a 100644
--- a/freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.h
+++ b/freebsd/sys/dev/rtwn/pci/rtwn_pci_rx.h
@@ -21,7 +21,7 @@
void rtwn_pci_dma_map_addr(void *, bus_dma_segment_t *, int, int);
void rtwn_pci_setup_rx_desc(struct rtwn_pci_softc *,
- struct r92ce_rx_stat *, bus_addr_t, size_t, int);
+ struct rtwn_rx_stat_pci *, bus_addr_t, size_t, int);
void rtwn_pci_intr(void *);
#endif /* RTWN_PCI_RX_H */
diff --git a/freebsd/sys/dev/rtwn/pci/rtwn_pci_var.h b/freebsd/sys/dev/rtwn/pci/rtwn_pci_var.h
index 5a9e64e7..194fab4a 100644
--- a/freebsd/sys/dev/rtwn/pci/rtwn_pci_var.h
+++ b/freebsd/sys/dev/rtwn/pci/rtwn_pci_var.h
@@ -23,9 +23,6 @@
#ifndef RTWN_PCI_VAR_H
#define RTWN_PCI_VAR_H
-#include <dev/rtwn/rtl8192c/pci/r92ce_rx_desc.h>
-
-
#define RTWN_PCI_RX_LIST_COUNT 256
#define RTWN_PCI_TX_LIST_COUNT 256
@@ -36,7 +33,7 @@ struct rtwn_rx_data {
};
struct rtwn_rx_ring {
- struct r92ce_rx_stat *desc;
+ struct rtwn_rx_stat_pci *desc;
bus_addr_t paddr;
bus_dma_tag_t desc_dmat;
bus_dmamap_t desc_map;
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c
index fe9d58b7..903398a4 100644
--- a/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c
@@ -91,8 +91,7 @@ r88e_get_txpower(struct rtwn_softc *sc, int chain,
{
struct r92c_softc *rs = sc->sc_priv;
const struct rtwn_r88e_txpwr *rt = rs->rs_txpwr;
- const struct rtwn_r88e_txagc *base = rs->rs_txagc;
- uint16_t cckpow, ofdmpow, bw20pow, htpow;
+ uint8_t cckpow, ofdmpow, bw20pow, htpow = 0;
int max_mcs, ridx, group;
/* Determine channel group. */
@@ -108,35 +107,24 @@ r88e_get_txpower(struct rtwn_softc *sc, int chain,
KASSERT(max_mcs <= RTWN_RIDX_COUNT, ("increase ridx limit\n"));
memset(power, 0, max_mcs * sizeof(power[0]));
- if (rs->regulatory == 0) {
- for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++)
- power[ridx] = base->pwr[0][ridx];
- }
- for (ridx = RTWN_RIDX_OFDM6; ridx <= max_mcs; ridx++) {
- if (rs->regulatory == 3)
- power[ridx] = base->pwr[0][ridx];
- else if (rs->regulatory == 1) {
- if (!IEEE80211_IS_CHAN_HT40(c))
- power[ridx] = base->pwr[group][ridx];
- } else if (rs->regulatory != 2)
- power[ridx] = base->pwr[0][ridx];
- }
/* Compute per-CCK rate Tx power. */
cckpow = rt->cck_tx_pwr[group];
- for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++)
- power[ridx] += cckpow;
+ for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++) {
+ power[ridx] = (ridx == RTWN_RIDX_CCK2) ? cckpow - 9 : cckpow;
+ }
- htpow = rt->ht40_tx_pwr[group];
+ if (group < 5)
+ htpow = rt->ht40_tx_pwr[group];
/* Compute per-OFDM rate Tx power. */
ofdmpow = htpow + rt->ofdm_tx_pwr_diff;
for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++)
- power[ridx] += ofdmpow;
+ power[ridx] = ofdmpow;
bw20pow = htpow + rt->bw20_tx_pwr_diff;
for (ridx = RTWN_RIDX_MCS(0); ridx <= max_mcs; ridx++)
- power[ridx] += bw20pow;
+ power[ridx] = bw20pow;
/* Apply max limit. */
for (ridx = RTWN_RIDX_CCK1; ridx <= max_mcs; ridx++) {
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_priv.h b/freebsd/sys/dev/rtwn/rtl8188e/r88e_priv.h
index cb4f7edb..28f4b1fb 100644
--- a/freebsd/sys/dev/rtwn/rtl8188e/r88e_priv.h
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_priv.h
@@ -227,47 +227,4 @@ static const struct rtwn_rf_prog rtl8188eu_rf[] = {
{ 0, NULL, NULL, { 0 }, NULL }
};
-
-struct rtwn_r88e_txagc {
- uint8_t pwr[R88E_GROUP_2G][20]; /* RTWN_RIDX_MCS(7) + 1 */
-};
-
-/*
- * Per RF chain/group/rate Tx gain values.
- */
-static const struct rtwn_r88e_txagc r88e_txagc[] = {
- { { /* Chain 0. */
- { /* Group 0. */
- 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
- },
- { /* Group 1. */
- 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
- },
- { /* Group 2. */
- 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
- },
- { /* Group 3. */
- 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
- },
- { /* Group 4. */
- 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
- },
- { /* Group 5. */
- 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
- }
- } }
-};
-
#endif /* R88E_PRIV_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_defs.h b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_defs.h
index 5734246f..c6033678 100644
--- a/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_defs.h
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rom_defs.h
@@ -23,7 +23,7 @@
#define R88E_GROUP_2G 6
-#define R88E_EFUSE_MAX_LEN 512
+#define R88E_EFUSE_MAX_LEN 256
#define R88E_EFUSE_MAP_LEN 512
#endif /* R88E_ROM_DEFS_H */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c
index 88159876..856ec88b 100644
--- a/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_rx.c
@@ -223,7 +223,7 @@ r88e_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
if (!sc->sc_ht40) { /* XXX center channel */
rxs->r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
- rxs->c_ieee = le16toh(physt->chan);
+ rxs->c_ieee = 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 f5ac1d9d..73cc7856 100644
--- a/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
+++ b/freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
@@ -87,7 +87,7 @@ r88eu_attach_private(struct rtwn_softc *sc)
rs = malloc(sizeof(struct r92c_softc), M_RTWN_PRIV, M_WAITOK | M_ZERO);
rs->rs_txpwr = &r88e_txpwr;
- rs->rs_txagc = &r88e_txagc;
+ rs->rs_txagc = NULL;
rs->rs_set_bw20 = r88e_set_bw20;
rs->rs_get_txpower = r88e_get_txpower;
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_image.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_image.h
index 304324e6..5c2880bb 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_image.h
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rom_image.h
@@ -48,7 +48,7 @@ struct r92c_rom {
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 channel_plan;
uint8_t tssi[R92C_MAX_CHAINS];
uint8_t thermal_meter;
#define R92C_ROM_THERMAL_METER_M 0x1f
@@ -58,9 +58,7 @@ struct r92c_rom {
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 reserved5;
uint8_t version;
uint8_t customer_id;
} __packed;
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c
index 454da87c..c2a6eab0 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c
@@ -333,8 +333,6 @@ r92c_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
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;
diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c b/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c
index c5a9e465..895f71e4 100644
--- a/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c
+++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c
@@ -340,8 +340,6 @@ r12a_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
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;
diff --git a/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.c b/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.c
index 93e1f768..8626d0a3 100644
--- a/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.c
+++ b/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.c
@@ -79,12 +79,14 @@ static void rtwn_usb_reset_lists(struct rtwn_softc *,
struct ieee80211vap *);
static void rtwn_usb_reset_tx_list(struct rtwn_usb_softc *,
rtwn_datahead *, struct ieee80211vap *);
+static void rtwn_usb_reset_rx_list(struct rtwn_usb_softc *);
static void rtwn_usb_start_xfers(struct rtwn_softc *);
static void rtwn_usb_abort_xfers(struct rtwn_softc *);
static int rtwn_usb_fw_write_block(struct rtwn_softc *,
const uint8_t *, uint16_t, int);
static void rtwn_usb_drop_incorrect_tx(struct rtwn_softc *);
static void rtwn_usb_attach_methods(struct rtwn_softc *);
+static void rtwn_usb_sysctlattach(struct rtwn_softc *);
#define RTWN_CONFIG_INDEX 0
@@ -135,9 +137,8 @@ rtwn_usb_alloc_rx_list(struct rtwn_softc *sc)
struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc);
int error, i;
- /* XXX recheck */
error = rtwn_usb_alloc_list(sc, uc->uc_rx, RTWN_USB_RX_LIST_COUNT,
- sc->rx_dma_size + 1024);
+ uc->uc_rx_buf_size * RTWN_USB_RXBUFSZ_UNIT);
if (error != 0)
return (error);
@@ -157,7 +158,7 @@ rtwn_usb_alloc_tx_list(struct rtwn_softc *sc)
int error, i;
error = rtwn_usb_alloc_list(sc, uc->uc_tx, RTWN_USB_TX_LIST_COUNT,
- RTWN_TXBUFSZ);
+ RTWN_USB_TXBUFSZ);
if (error != 0)
return (error);
@@ -201,6 +202,9 @@ rtwn_usb_free_rx_list(struct rtwn_softc *sc)
rtwn_usb_free_list(sc, uc->uc_rx, RTWN_USB_RX_LIST_COUNT);
+ uc->uc_rx_stat_len = 0;
+ uc->uc_rx_off = 0;
+
STAILQ_INIT(&uc->uc_rx_active);
STAILQ_INIT(&uc->uc_rx_inactive);
}
@@ -226,8 +230,10 @@ rtwn_usb_reset_lists(struct rtwn_softc *sc, struct ieee80211vap *vap)
rtwn_usb_reset_tx_list(uc, &uc->uc_tx_active, vap);
rtwn_usb_reset_tx_list(uc, &uc->uc_tx_pending, vap);
- if (vap == NULL)
+ if (vap == NULL) {
+ rtwn_usb_reset_rx_list(uc);
sc->qfullmsk = 0;
+ }
}
static void
@@ -261,6 +267,23 @@ rtwn_usb_reset_tx_list(struct rtwn_usb_softc *uc,
}
static void
+rtwn_usb_reset_rx_list(struct rtwn_usb_softc *uc)
+{
+ int i;
+
+ for (i = 0; i < RTWN_USB_RX_LIST_COUNT; i++) {
+ struct rtwn_data *dp = &uc->uc_rx[i];
+
+ if (dp->m != NULL) {
+ m_freem(dp->m);
+ dp->m = NULL;
+ }
+ }
+ uc->uc_rx_stat_len = 0;
+ uc->uc_rx_off = 0;
+}
+
+static void
rtwn_usb_start_xfers(struct rtwn_softc *sc)
{
struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc);
@@ -329,6 +352,31 @@ rtwn_usb_attach_methods(struct rtwn_softc *sc)
sc->bcn_check_interval = 100;
}
+static void
+rtwn_usb_sysctlattach(struct rtwn_softc *sc)
+{
+ struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc);
+ struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
+ struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
+ char str[64];
+ int ret;
+
+ ret = snprintf(str, sizeof(str),
+ "Rx buffer size, 512-byte units [%d...%d]",
+ RTWN_USB_RXBUFSZ_MIN, RTWN_USB_RXBUFSZ_MAX);
+ KASSERT(ret > 0, ("ret (%d) <= 0!\n", ret));
+ (void) ret;
+
+ uc->uc_rx_buf_size = RTWN_USB_RXBUFSZ_DEF;
+ SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "rx_buf_size", CTLFLAG_RDTUN, &uc->uc_rx_buf_size,
+ uc->uc_rx_buf_size, str);
+ if (uc->uc_rx_buf_size < RTWN_USB_RXBUFSZ_MIN)
+ uc->uc_rx_buf_size = RTWN_USB_RXBUFSZ_MIN;
+ if (uc->uc_rx_buf_size > RTWN_USB_RXBUFSZ_MAX)
+ uc->uc_rx_buf_size = RTWN_USB_RXBUFSZ_MAX;
+}
+
static int
rtwn_usb_attach(device_t self)
{
@@ -345,6 +393,7 @@ rtwn_usb_attach(device_t self)
/* Need to be initialized early. */
rtwn_sysctlattach(sc);
+ rtwn_usb_sysctlattach(sc);
mtx_init(&sc->sc_mtx, ic->ic_name, MTX_NETWORK_LOCK, MTX_DEF);
rtwn_usb_attach_methods(sc);
diff --git a/freebsd/sys/dev/rtwn/usb/rtwn_usb_ep.c b/freebsd/sys/dev/rtwn/usb/rtwn_usb_ep.c
index ef7d1ffc..f56e96c0 100644
--- a/freebsd/sys/dev/rtwn/usb/rtwn_usb_ep.c
+++ b/freebsd/sys/dev/rtwn/usb/rtwn_usb_ep.c
@@ -75,7 +75,7 @@ static const struct usb_config rtwn_config_common[RTWN_N_TRANSFER] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
- .bufsize = RTWN_TXBUFSZ,
+ .bufsize = RTWN_USB_TXBUFSZ,
.flags = {
.ext_buffer = 1,
.pipe_bof = 1,
@@ -88,7 +88,7 @@ static const struct usb_config rtwn_config_common[RTWN_N_TRANSFER] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
- .bufsize = RTWN_TXBUFSZ,
+ .bufsize = RTWN_USB_TXBUFSZ,
.flags = {
.ext_buffer = 1,
.pipe_bof = 1,
@@ -101,7 +101,7 @@ static const struct usb_config rtwn_config_common[RTWN_N_TRANSFER] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
- .bufsize = RTWN_TXBUFSZ,
+ .bufsize = RTWN_USB_TXBUFSZ,
.flags = {
.ext_buffer = 1,
.pipe_bof = 1,
@@ -114,7 +114,7 @@ static const struct usb_config rtwn_config_common[RTWN_N_TRANSFER] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
- .bufsize = RTWN_TXBUFSZ,
+ .bufsize = RTWN_USB_TXBUFSZ,
.flags = {
.ext_buffer = 1,
.pipe_bof = 1,
@@ -227,7 +227,8 @@ rtwn_usb_setup_endpoints(struct rtwn_usb_softc *uc)
break;
}
- rtwn_config[RTWN_BULK_RX].bufsize = sc->rx_dma_size + 1024;
+ rtwn_config[RTWN_BULK_RX].bufsize =
+ uc->uc_rx_buf_size * RTWN_USB_RXBUFSZ_UNIT;
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);
diff --git a/freebsd/sys/dev/rtwn/usb/rtwn_usb_rx.c b/freebsd/sys/dev/rtwn/usb/rtwn_usb_rx.c
index 4f39b580..9de8fca4 100644
--- a/freebsd/sys/dev/rtwn/usb/rtwn_usb_rx.c
+++ b/freebsd/sys/dev/rtwn/usb/rtwn_usb_rx.c
@@ -65,57 +65,69 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/usb/rtwn_usb_var.h>
#include <dev/rtwn/usb/rtwn_usb_rx.h>
-#include <dev/rtwn/rtl8192c/r92c_reg.h> /* for CAM_ALGO_NONE */
-#include <dev/rtwn/rtl8192c/r92c_rx_desc.h>
+static struct mbuf * rtwn_rxeof(struct rtwn_softc *, struct rtwn_data *,
+ uint8_t *, int);
-
-static struct mbuf *
-rtwn_rx_copy_to_mbuf(struct rtwn_softc *sc, struct r92c_rx_stat *stat,
- int totlen)
+static int
+rtwn_rx_check_pre_alloc(struct rtwn_softc *sc,
+ struct rtwn_rx_stat_common *stat)
{
- struct ieee80211com *ic = &sc->sc_ic;
- struct mbuf *m;
uint32_t rxdw0;
int pktlen;
RTWN_ASSERT_LOCKED(sc);
- /* Dump Rx descriptor. */
- RTWN_DPRINTF(sc, RTWN_DEBUG_RECV_DESC,
- "%s: dw: 0 %08X, 1 %08X, 2 %08X, 3 %08X, 4 %08X, tsfl %08X\n",
- __func__, le32toh(stat->rxdw0), le32toh(stat->rxdw1),
- le32toh(stat->rxdw2), le32toh(stat->rxdw3), le32toh(stat->rxdw4),
- le32toh(stat->tsf_low));
-
/*
* don't pass packets to the ieee80211 framework if the driver isn't
* RUNNING.
*/
if (!(sc->sc_flags & RTWN_RUNNING))
- return (NULL);
+ return (-1);
rxdw0 = le32toh(stat->rxdw0);
- if (__predict_false(rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR))) {
+ if (__predict_false(rxdw0 & (RTWN_RXDW0_CRCERR | RTWN_RXDW0_ICVERR))) {
/*
* This should not happen since we setup our Rx filter
* to not receive these frames.
*/
RTWN_DPRINTF(sc, RTWN_DEBUG_RECV,
"%s: RX flags error (%s)\n", __func__,
- rxdw0 & R92C_RXDW0_CRCERR ? "CRC" : "ICV");
- goto fail;
+ rxdw0 & RTWN_RXDW0_CRCERR ? "CRC" : "ICV");
+ return (-1);
}
- pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
+ pktlen = MS(rxdw0, RTWN_RXDW0_PKTLEN);
if (__predict_false(pktlen < sizeof(struct ieee80211_frame_ack))) {
/*
* Should not happen (because of Rx filter setup).
*/
RTWN_DPRINTF(sc, RTWN_DEBUG_RECV,
"%s: frame is too short: %d\n", __func__, pktlen);
- goto fail;
+ return (-1);
}
+ return (0);
+}
+
+static struct mbuf *
+rtwn_rx_copy_to_mbuf(struct rtwn_softc *sc, struct rtwn_rx_stat_common *stat,
+ int totlen)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct mbuf *m;
+
+ RTWN_ASSERT_LOCKED(sc);
+
+ /* Dump Rx descriptor. */
+ RTWN_DPRINTF(sc, RTWN_DEBUG_RECV_DESC,
+ "%s: dw: 0 %08X, 1 %08X, 2 %08X, 3 %08X, 4 %08X, tsfl %08X\n",
+ __func__, le32toh(stat->rxdw0), le32toh(stat->rxdw1),
+ le32toh(stat->rxdw2), le32toh(stat->rxdw3), le32toh(stat->rxdw4),
+ le32toh(stat->tsf_low));
+
+ if (rtwn_rx_check_pre_alloc(sc, stat) != 0)
+ goto fail;
+
m = m_get2(totlen, M_NOWAIT, MT_DATA, M_PKTHDR);
if (__predict_false(m == NULL)) {
device_printf(sc->sc_dev, "%s: could not allocate RX mbuf\n",
@@ -139,30 +151,124 @@ fail:
}
static struct mbuf *
-rtwn_rxeof(struct rtwn_softc *sc, uint8_t *buf, int len)
+rtwn_rxeof_fragmented(struct rtwn_usb_softc *uc, struct rtwn_data *data,
+ uint8_t *buf, int len)
+{
+ struct rtwn_softc *sc = &uc->uc_sc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct rtwn_rx_stat_common *stat = &uc->uc_rx_stat;
+ uint32_t rxdw0;
+ int totlen, pktlen, infosz, min_len;
+ int orig_len = len;
+ int alloc_mbuf = 0;
+
+ /* Check if Rx descriptor is not truncated. */
+ if (uc->uc_rx_stat_len < sizeof(*stat)) {
+ min_len = min(sizeof(*stat) - uc->uc_rx_stat_len, len);
+ memcpy((uint8_t *)stat + uc->uc_rx_stat_len, buf, min_len);
+
+ uc->uc_rx_stat_len += min_len;
+ buf += min_len;
+ len -= min_len;
+
+ if (uc->uc_rx_stat_len < sizeof(*stat))
+ goto end;
+
+ KASSERT(data->m == NULL, ("%s: data->m != NULL!\n", __func__));
+ alloc_mbuf = 1;
+
+ /* Dump Rx descriptor. */
+ RTWN_DPRINTF(sc, RTWN_DEBUG_RECV_DESC,
+ "%s: dw: 0 %08X, 1 %08X, 2 %08X, 3 %08X, 4 %08X, "
+ "tsfl %08X\n", __func__, le32toh(stat->rxdw0),
+ le32toh(stat->rxdw1), le32toh(stat->rxdw2),
+ le32toh(stat->rxdw3), le32toh(stat->rxdw4),
+ le32toh(stat->tsf_low));
+ }
+
+ rxdw0 = le32toh(stat->rxdw0);
+ pktlen = MS(rxdw0, RTWN_RXDW0_PKTLEN);
+ infosz = MS(rxdw0, RTWN_RXDW0_INFOSZ) * 8;
+ totlen = sizeof(*stat) + infosz + pktlen;
+ if (alloc_mbuf) {
+ if (rtwn_rx_check_pre_alloc(sc, stat) == 0) {
+ data->m = m_getm(NULL, totlen, M_NOWAIT, MT_DATA);
+ if (data->m != NULL) {
+ m_copyback(data->m, 0, uc->uc_rx_stat_len,
+ (caddr_t)stat);
+
+ if (rtwn_check_frame(sc, data->m) != 0) {
+ m_freem(data->m);
+ data->m = NULL;
+ counter_u64_add(ic->ic_ierrors, 1);
+ }
+ } else
+ counter_u64_add(ic->ic_ierrors, 1);
+ } else
+ counter_u64_add(ic->ic_ierrors, 1);
+
+ uc->uc_rx_off = sizeof(*stat);
+ }
+
+ /* If mbuf allocation fails just discard the data. */
+ min_len = min(totlen - uc->uc_rx_off, len);
+ if (data->m != NULL)
+ m_copyback(data->m, uc->uc_rx_off, min_len, buf);
+
+ uc->uc_rx_off += min_len;
+ if (uc->uc_rx_off == totlen) {
+ /* Align next frame. */
+ min_len = rtwn_usb_align_rx(uc,
+ orig_len - len + min_len, orig_len);
+ min_len -= (orig_len - len);
+ KASSERT(len >= min_len, ("%s: len (%d) < min_len (%d)!\n",
+ __func__, len, min_len));
+
+ /* Clear mbuf stats. */
+ uc->uc_rx_stat_len = 0;
+ uc->uc_rx_off = 0;
+ }
+ len -= min_len;
+ buf += min_len;
+end:
+ if (uc->uc_rx_stat_len == 0)
+ return (rtwn_rxeof(sc, data, buf, len));
+ else
+ return (NULL);
+}
+
+static struct mbuf *
+rtwn_rxeof(struct rtwn_softc *sc, struct rtwn_data *data, uint8_t *buf,
+ int len)
{
struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc);
- struct r92c_rx_stat *stat;
+ struct rtwn_rx_stat_common *stat;
struct mbuf *m, *m0 = NULL;
uint32_t rxdw0;
int totlen, pktlen, infosz;
+ /* Prepend defragmented frame (if any). */
+ if (data->m != NULL) {
+ m0 = m = data->m;
+ data->m = NULL;
+ }
+
/* Process packets. */
while (len >= sizeof(*stat)) {
- stat = (struct r92c_rx_stat *)buf;
+ stat = (struct rtwn_rx_stat_common *)buf;
rxdw0 = le32toh(stat->rxdw0);
- pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
+ pktlen = MS(rxdw0, RTWN_RXDW0_PKTLEN);
if (__predict_false(pktlen == 0))
break;
- infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
+ infosz = MS(rxdw0, RTWN_RXDW0_INFOSZ) * 8;
/* Make sure everything fits in xfer. */
totlen = sizeof(*stat) + infosz + pktlen;
if (totlen > len) {
- device_printf(sc->sc_dev,
- "%s: totlen (%d) > len (%d)!\n",
+ RTWN_DPRINTF(sc, RTWN_DEBUG_RECV,
+ "%s: frame is fragmented (totlen %d len %d)\n",
__func__, totlen, len);
break;
}
@@ -170,9 +276,9 @@ rtwn_rxeof(struct rtwn_softc *sc, uint8_t *buf, int len)
if (m0 == NULL)
m0 = m = rtwn_rx_copy_to_mbuf(sc, stat, totlen);
else {
- m->m_next = rtwn_rx_copy_to_mbuf(sc, stat, totlen);
- if (m->m_next != NULL)
- m = m->m_next;
+ m->m_nextpkt = rtwn_rx_copy_to_mbuf(sc, stat, totlen);
+ if (m->m_nextpkt != NULL)
+ m = m->m_nextpkt;
}
/* Align next frame. */
@@ -181,6 +287,9 @@ rtwn_rxeof(struct rtwn_softc *sc, uint8_t *buf, int len)
len -= totlen;
}
+ if (len > 0)
+ (void)rtwn_rxeof_fragmented(uc, data, buf, len);
+
return (m0);
}
@@ -195,15 +304,19 @@ rtwn_report_intr(struct rtwn_usb_softc *uc, struct usb_xfer *xfer,
usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
- if (__predict_false(len < sizeof(struct r92c_rx_stat))) {
+ if (__predict_false(len < sizeof(struct rtwn_rx_stat_common) &&
+ uc->uc_rx_stat_len == 0)) {
counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
buf = data->buf;
+ if (uc->uc_rx_stat_len > 0)
+ return (rtwn_rxeof_fragmented(uc, data, data->buf, len));
+
switch (rtwn_classify_intr(sc, buf, len)) {
case RTWN_RX_DATA:
- return (rtwn_rxeof(sc, buf, len));
+ return (rtwn_rxeof(sc, data, buf, len));
case RTWN_RX_TX_REPORT:
if (sc->sc_ratectl != RTWN_RATECTL_NET80211) {
/* shouldn't happen */
@@ -240,11 +353,11 @@ 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)
{
- struct r92c_rx_stat stat;
+ struct rtwn_rx_stat_common stat;
/* Imitate PCIe layout. */
- m_copydata(m, 0, sizeof(struct r92c_rx_stat), (caddr_t)&stat);
- m_adj(m, sizeof(struct r92c_rx_stat));
+ m_copydata(m, 0, sizeof(stat), (caddr_t)&stat);
+ m_adj(m, sizeof(stat));
return (rtwn_rx_common(sc, m, &stat));
}
@@ -289,8 +402,8 @@ tr_setup:
* callback and safe to unlock.
*/
while (m != NULL) {
- next = m->m_next;
- m->m_next = NULL;
+ next = m->m_nextpkt;
+ m->m_nextpkt = NULL;
ni = rtwn_rx_frame(sc, m);
@@ -314,6 +427,8 @@ tr_setup:
STAILQ_INSERT_TAIL(&uc->uc_rx_inactive, data, next);
}
if (error != USB_ERR_CANCELLED) {
+ /* XXX restart device if frame was fragmented? */
+
usbd_xfer_set_stall(xfer);
counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
diff --git a/freebsd/sys/dev/rtwn/usb/rtwn_usb_tx.c b/freebsd/sys/dev/rtwn/usb/rtwn_usb_tx.c
index 7bede4dc..61f0ba43 100644
--- a/freebsd/sys/dev/rtwn/usb/rtwn_usb_tx.c
+++ b/freebsd/sys/dev/rtwn/usb/rtwn_usb_tx.c
@@ -235,6 +235,9 @@ rtwn_usb_tx_start(struct rtwn_softc *sc, struct ieee80211_node *ni,
RTWN_ASSERT_LOCKED(sc);
+ if (m->m_pkthdr.len + sc->txdesc_len > RTWN_USB_TXBUFSZ)
+ return (EINVAL);
+
data = rtwn_usb_getbuf(uc);
if (data == NULL)
return (ENOBUFS);
diff --git a/freebsd/sys/dev/rtwn/usb/rtwn_usb_var.h b/freebsd/sys/dev/rtwn/usb/rtwn_usb_var.h
index be7f8f19..7ef21463 100644
--- a/freebsd/sys/dev/rtwn/usb/rtwn_usb_var.h
+++ b/freebsd/sys/dev/rtwn/usb/rtwn_usb_var.h
@@ -21,6 +21,14 @@
#ifndef RTWN_USBVAR_H
#define RTWN_USBVAR_H
+#include <dev/rtwn/if_rtwnreg.h> /* for struct rtwn_rx_stat_common */
+
+#define RTWN_USB_RXBUFSZ_UNIT (512)
+#define RTWN_USB_RXBUFSZ_MIN ( 4)
+#define RTWN_USB_RXBUFSZ_DEF (24)
+#define RTWN_USB_RXBUFSZ_MAX (64)
+#define RTWN_USB_TXBUFSZ (16 * 1024)
+
#define RTWN_IFACE_INDEX 0
#define RTWN_USB_RX_LIST_COUNT 1
@@ -56,6 +64,12 @@ struct rtwn_usb_softc {
struct rtwn_data uc_rx[RTWN_USB_RX_LIST_COUNT];
rtwn_datahead uc_rx_active;
rtwn_datahead uc_rx_inactive;
+ int uc_rx_buf_size;
+
+ struct rtwn_rx_stat_common uc_rx_stat;
+ int uc_rx_stat_len;
+ int uc_rx_off;
+
struct rtwn_data uc_tx[RTWN_USB_TX_LIST_COUNT];
rtwn_datahead uc_tx_active;
rtwn_datahead uc_tx_inactive;