diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2017-01-08 05:48:28 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2017-01-08 05:48:28 +0000 |
commit | 21de15f773be76ce845907d8c4e8e82753cc4b0e (patch) | |
tree | 9c2bcaeeb4da7720ce7e357df65f8143fb344557 /sys/dev | |
parent | 886be2b2bf09a8be00fb57a1aba46d42308ff89e (diff) |
Make urtwn(4) use AMRR instead of letting the firmware handle rate scaling.
For now this only affects RTL8188EU chips, perhaps because the author of this
patch does not own any devices containing any of the other chips (hint hint).
Patch by misha aka Mikhail / mp39590 at gmail
ok mpi@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/r92creg.h | 43 | ||||
-rw-r--r-- | sys/dev/ic/rtwn.c | 14 | ||||
-rw-r--r-- | sys/dev/usb/if_urtwn.c | 69 |
3 files changed, 113 insertions, 13 deletions
diff --git a/sys/dev/ic/r92creg.h b/sys/dev/ic/r92creg.h index db155381cdd..ed43bca6850 100644 --- a/sys/dev/ic/r92creg.h +++ b/sys/dev/ic/r92creg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: r92creg.h,v 1.3 2016/03/07 19:41:49 stsp Exp $ */ +/* $OpenBSD: r92creg.h,v 1.4 2017/01/08 05:48:27 stsp Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> @@ -1056,6 +1056,35 @@ struct r92c_rx_cck { uint8_t agc_rpt; } __packed; +/* Tx report (type 1). */ +struct r88e_tx_rpt_ccx { + uint8_t rptb0; +#define R88E_RPTB6_PKT_NUM_M 0x0e +#define R88E_RPTB6_PKT_NUM_S 1 +#define R88E_RPTB0_INT_CCX 0x80 + + uint8_t rptb1; +#define R88E_RPTB1_MACID_M 0x3f +#define R88E_RPTB1_MACID_S 0 +#define R88E_RPTB1_PKT_OK 0x40 +#define R88E_RPTB1_BMC 0x80 + + uint8_t rptb2; +#define R88E_RPTB2_RETRY_CNT_M 0x3f +#define R88E_RPTB2_RETRY_CNT_S 0 +#define R88E_RPTB2_LIFE_EXPIRE 0x40 +#define R88E_RPTB2_RETRY_OVER 0x80 + + uint8_t queue_time_low; + uint8_t queue_time_high; + uint8_t final_rate; + uint8_t rptb6; +#define R88E_RPTB6_QSEL_M 0xf0 +#define R88E_RPTB6_QSEL_S 4 + + uint8_t rptb7; +} __packed; + struct r88e_rx_cck { uint8_t path_agc[2]; uint8_t sig_qual; @@ -1155,6 +1184,9 @@ struct r92c_tx_desc_usb { uint16_t pad; } __packed __attribute__((aligned(4))); +#define R88E_TX_RPT_CTRL 0x4ec +#define R88E_TX_RPT1_ENA 0x01 + #define R92C_TXDW0_PKTLEN_M 0x0000ffff #define R92C_TXDW0_PKTLEN_S 0 #define R92C_TXDW0_OFFSET_M 0x00ff0000 @@ -1191,6 +1223,14 @@ struct r92c_tx_desc_usb { #define R92C_TXDW1_PKTOFF_S 26 #define R88E_TXDW2_AGGBK 0x00010000 +#define R92C_TXDW2_CCX_RPT 0x00080000 + +#define R88E_RXDW3_RPT_M 0x0000c000 +#define R88E_RXDW3_RPT_S 14 +#define R88E_RXDW3_RPT_RX 0 +#define R88E_RXDW3_RPT_TX1 1 +#define R88E_RXDW3_RPT_TX2 2 +#define R88E_RXDW3_RPT_HIS 3 #define R92C_TXDW4_RTSRATE_M 0x0000003f #define R92C_TXDW4_RTSRATE_S 0 @@ -1205,6 +1245,7 @@ struct r92c_tx_desc_usb { #define R92C_TXDW4_SCO_SCA 1 #define R92C_TXDW4_SCO_SCB 2 #define R92C_TXDW4_40MHZ 0x02000000 +#define R92C_TXDW4_RTS_SHORT 0x04000000 #define R92C_TXDW5_DATARATE_M 0x0000003f #define R92C_TXDW5_DATARATE_S 0 diff --git a/sys/dev/ic/rtwn.c b/sys/dev/ic/rtwn.c index ee4e5b37f46..9cc98451bda 100644 --- a/sys/dev/ic/rtwn.c +++ b/sys/dev/ic/rtwn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtwn.c,v 1.10 2016/07/26 13:00:28 stsp Exp $ */ +/* $OpenBSD: rtwn.c,v 1.11 2017/01/08 05:48:27 stsp Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> @@ -692,15 +692,17 @@ rtwn_ra_init(struct rtwn_softc *sc) rtwn_write_4(sc, R92C_ARFR(0), rates & 0x0ff5); } - if (sc->chip & RTWN_CHIP_88E) + if (sc->chip & RTWN_CHIP_88E) { error = rtwn_r88e_ra_init(sc, mode, rates, maxrate, basicrates, maxbasicrate); - else + /* We use AMRR with this chip. Start with the lowest rate. */ + ni->ni_txrate = 0; + } else { error = rtwn_r92c_ra_init(sc, mode, rates, maxrate, basicrates, maxbasicrate); - - /* Indicate highest supported rate. */ - ni->ni_txrate = rs->rs_nrates - 1; + /* No AMRR support yet. Indicate highest supported rate. */ + ni->ni_txrate = rs->rs_nrates - 1; + } return (error); } diff --git a/sys/dev/usb/if_urtwn.c b/sys/dev/usb/if_urtwn.c index cc00ea9365b..d8f2430391d 100644 --- a/sys/dev/usb/if_urtwn.c +++ b/sys/dev/usb/if_urtwn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_urtwn.c,v 1.66 2016/07/21 08:38:33 stsp Exp $ */ +/* $OpenBSD: if_urtwn.c,v 1.67 2017/01/08 05:48:27 stsp Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> @@ -47,6 +47,7 @@ #include <netinet/if_ether.h> #include <net80211/ieee80211_var.h> +#include <net80211/ieee80211_amrr.h> #include <net80211/ieee80211_radiotap.h> #include <dev/usb/usb.h> @@ -172,6 +173,9 @@ struct urtwn_softc { struct urtwn_tx_data tx_data[URTWN_TX_LIST_COUNT]; TAILQ_HEAD(, urtwn_tx_data) tx_free_list; + struct ieee80211_amrr amrr; + struct ieee80211_amrr_node amn; + #if NBPFILTER > 0 caddr_t sc_drvbpf; @@ -406,7 +410,10 @@ urtwn_attach(struct device *parent, struct device *self, void *aux) chip_type |= RTWN_CHIP_88E; else chip_type |= (RTWN_CHIP_92C | RTWN_CHIP_88C); - + + sc->amrr.amrr_min_success_threshold = 1; + sc->amrr.amrr_max_success_threshold = 10; + /* Attach the bus-agnostic driver. */ sc->sc_sc.sc_ops.cookie = sc; sc->sc_sc.sc_ops.write_1 = urtwn_write_1; @@ -839,6 +846,15 @@ urtwn_calib_to(void *arg) void urtwn_calib_cb(struct urtwn_softc *sc, void *arg) { + struct ieee80211com *ic = &sc->sc_sc.sc_ic; + int s; + + s = splnet(); + if (ic->ic_opmode == IEEE80211_M_STA) { + ieee80211_amrr_choose(&sc->amrr, ic->ic_bss, &sc->amn); + } + splx(s); + rtwn_calib(&sc->sc_sc); } @@ -1142,6 +1158,27 @@ urtwn_rxeof(struct usbd_xfer *xfer, void *priv, npkts = MS(letoh32(rxd->rxdw2), R92C_RXDW2_PKTCNT); DPRINTFN(4, ("Rx %d frames in one chunk\n", npkts)); + if (sc->sc_sc.chip & RTWN_CHIP_88E) { + int ntries, type; + struct r88e_tx_rpt_ccx *rxstat; + + type = MS(letoh32(rxd->rxdw3), R88E_RXDW3_RPT); + + if (type == R88E_RXDW3_RPT_TX1) { + buf += sizeof(struct r92c_rx_desc_usb); + rxstat = (struct r88e_tx_rpt_ccx *)buf; + ntries = MS(letoh32(rxstat->rptb2), + R88E_RPTB2_RETRY_CNT); + + if (rxstat->rptb1 & R88E_RPTB1_PKT_OK) + sc->amn.amn_txcnt++; + if (ntries > 0) + sc->amn.amn_retrycnt++; + + goto resubmit; + } + } + /* Process all of them. */ while (npkts-- > 0) { if (__predict_false(len < sizeof(*rxd))) @@ -1292,6 +1329,8 @@ urtwn_tx(void *cookie, struct mbuf *m, struct ieee80211_node *ni) SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) | SM(R92C_TXDW1_RAID, raid)); txd->txdw2 |= htole32(R88E_TXDW2_AGGBK); + /* Request TX status report for AMRR */ + txd->txdw2 |= htole32(R92C_TXDW2_CCX_RPT); } else { txd->txdw1 |= htole32( SM(R92C_TXDW1_MACID, R92C_MACID_BSS) | @@ -1311,12 +1350,20 @@ urtwn_tx(void *cookie, struct mbuf *m, struct ieee80211_node *ni) R92C_TXDW4_HWRTSEN); } } - /* Send RTS at OFDM24. */ - txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8)); txd->txdw5 |= htole32(0x0001ff00); - /* Send data at OFDM54. */ - txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11)); + if (sc->sc_sc.chip & RTWN_CHIP_88E) { + /* Use AMRR */ + txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE); + txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, + ni->ni_txrate)); + txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, + ni->ni_txrate)); + } else { + /* Send RTS at OFDM24 and data at OFDM54. */ + txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8)); + txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11)); + } } else { txd->txdw1 |= htole32( SM(R92C_TXDW1_MACID, 0) | @@ -1961,6 +2008,16 @@ urtwn_init(void *cookie) return (error); } + ieee80211_amrr_node_init(&sc->amrr, &sc->amn); + + /* + * Enable TX reports for AMRR. + * In order to get reports we need to explicitly reset the register. + */ + if (sc->sc_sc.chip & RTWN_CHIP_88E) + urtwn_write_1(sc, R88E_TX_RPT_CTRL, (urtwn_read_1(sc, + R88E_TX_RPT_CTRL) & ~0) | R88E_TX_RPT1_ENA); + return (0); } |