summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravos <avos@FreeBSD.org>2016-05-22 19:43:40 +0000
committeravos <avos@FreeBSD.org>2016-05-22 19:43:40 +0000
commit8d12c00783d3e25c5bbc660dc89e8f167e20e941 (patch)
treef0ed57dd683435f3e61c353b1a78ff256fc0fe3c
parent923635816f6a1b08a6e9434803b309a0fb761ec9 (diff)
downloadFreeBSD-src-8d12c00783d3e25c5bbc660dc89e8f167e20e941.zip
FreeBSD-src-8d12c00783d3e25c5bbc660dc89e8f167e20e941.tar.gz
urtwn: setup per-frame retry limit.
Override global retry limit (which is set in R92C_RL) via per-frame TX descriptor field. Obsoletes D3840 (should work better with 2+ vaps). Tested with RTL8188EU and RTL8192CUS in STA mode (maxretry = [3-9]).
-rw-r--r--sys/dev/urtwn/if_urtwn.c23
-rw-r--r--sys/dev/urtwn/if_urtwnreg.h3
2 files changed, 22 insertions, 4 deletions
diff --git a/sys/dev/urtwn/if_urtwn.c b/sys/dev/urtwn/if_urtwn.c
index efbdaba..df2fffd 100644
--- a/sys/dev/urtwn/if_urtwn.c
+++ b/sys/dev/urtwn/if_urtwn.c
@@ -2838,7 +2838,7 @@ urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
struct ieee80211_channel *chan;
struct ieee80211_frame *wh;
struct r92c_tx_desc *txd;
- uint8_t macid, raid, rate, ridx, subtype, type, tid, qsel;
+ uint8_t macid, raid, rate, ridx, subtype, type, tid, qos, qsel;
int hasqos, ismcast;
URTWN_ASSERT_LOCKED(sc);
@@ -2854,10 +2854,12 @@ urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
/* Select TX ring for this frame. */
if (hasqos) {
- tid = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
- tid &= IEEE80211_QOS_TID;
- } else
+ qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
+ tid = qos & IEEE80211_QOS_TID;
+ } else {
+ qos = 0;
tid = 0;
+ }
chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ?
ni->ni_chan : ic->ic_curchan;
@@ -2923,6 +2925,14 @@ urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
txd->txdw0 |= htole32(R92C_TXDW0_BMCAST);
if (!ismcast) {
+ /* Unicast frame, check if an ACK is expected. */
+ if (!qos || (qos & IEEE80211_QOS_ACKPOLICY) !=
+ IEEE80211_QOS_ACKPOLICY_NOACK) {
+ txd->txdw5 |= htole32(R92C_TXDW5_RTY_LMT_ENA);
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_RTY_LMT,
+ tp->maxretry));
+ }
+
if (sc->chip & URTWN_CHIP_88E) {
struct urtwn_node *un = URTWN_NODE(ni);
macid = un->id;
@@ -3102,6 +3112,11 @@ urtwn_tx_raw(struct urtwn_softc *sc, struct ieee80211_node *ni,
if (IEEE80211_IS_MULTICAST(wh->i_addr1))
txd->txdw0 |= htole32(R92C_TXDW0_BMCAST);
+ if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) {
+ txd->txdw5 |= htole32(R92C_TXDW5_RTY_LMT_ENA);
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_RTY_LMT,
+ params->ibp_try0));
+ }
if (params->ibp_flags & IEEE80211_BPF_RTS)
txd->txdw4 |= htole32(R92C_TXDW4_RTSEN);
if (params->ibp_flags & IEEE80211_BPF_CTS)
diff --git a/sys/dev/urtwn/if_urtwnreg.h b/sys/dev/urtwn/if_urtwnreg.h
index 45ab56d..7b618aa 100644
--- a/sys/dev/urtwn/if_urtwnreg.h
+++ b/sys/dev/urtwn/if_urtwnreg.h
@@ -1198,6 +1198,9 @@ struct r92c_tx_desc {
#define R92C_TXDW5_DATARATE_M 0x0000003f
#define R92C_TXDW5_DATARATE_S 0
#define R92C_TXDW5_SGI 0x00000040
+#define R92C_TXDW5_RTY_LMT_ENA 0x00020000
+#define R92C_TXDW5_RTY_LMT_M 0x00fc0000
+#define R92C_TXDW5_RTY_LMT_S 18
#define R92C_TXDW5_AGGNUM_M 0xff000000
#define R92C_TXDW5_AGGNUM_S 24
OpenPOWER on IntegriCloud