Index: head/sys/dev/usb/wlan/if_rum.c =================================================================== --- head/sys/dev/usb/wlan/if_rum.c +++ head/sys/dev/usb/wlan/if_rum.c @@ -1212,7 +1212,7 @@ isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort) + ieee80211_ack_duration(ic->ic_rt, rate, isshort); - flags = RT2573_TX_MORE_FRAG; + flags = 0; if (prot == IEEE80211_PROT_RTSCTS) { /* NB: CTS is the same size as an ACK */ dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort); @@ -1286,6 +1286,7 @@ struct ieee80211_key *k = NULL; uint32_t flags = 0; uint16_t dur; + uint8_t type, xflags = 0; int hdrlen; RUM_LOCK_ASSERT(sc); @@ -1295,6 +1296,7 @@ sc->tx_nfree--; wh = mtod(m0, struct ieee80211_frame *); + type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; hdrlen = ieee80211_anyhdrsize(wh); if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { @@ -1319,12 +1321,15 @@ USETW(wh->i_dur, dur); /* tell hardware to add timestamp for probe responses */ - if ((wh->i_fc[0] & - (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == - (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)) + if (type == IEEE80211_FC0_TYPE_MGT && + (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == + IEEE80211_FC0_SUBTYPE_PROBE_RESP) flags |= RT2573_TX_TIMESTAMP; } + if (type != IEEE80211_FC0_TYPE_CTL && !IEEE80211_QOS_HAS_SEQ(wh)) + xflags |= RT2573_TX_HWSEQ; + if (k != NULL) flags |= rum_tx_crypto_flags(sc, ni, k); @@ -1332,7 +1337,7 @@ data->ni = ni; data->rate = tp->mgmtrate; - rum_setup_tx_desc(sc, &data->desc, k, flags, 0, hdrlen, + rum_setup_tx_desc(sc, &data->desc, k, flags, xflags, hdrlen, m0->m_pkthdr.len, tp->mgmtrate); DPRINTFN(10, "sending mgt frame len=%d rate=%d\n", @@ -1349,12 +1354,17 @@ const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; + struct ieee80211_frame *wh; struct rum_tx_data *data; uint32_t flags; + uint8_t type, xflags = 0; int rate, error; RUM_LOCK_ASSERT(sc); + wh = mtod(m0, struct ieee80211_frame *); + type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + rate = params->ibp_rate0; if (!ieee80211_isratevalid(ic->ic_rt, rate)) return (EINVAL); @@ -1373,6 +1383,9 @@ flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS; } + if (type != IEEE80211_FC0_TYPE_CTL && !IEEE80211_QOS_HAS_SEQ(wh)) + xflags |= RT2573_TX_HWSEQ; + data = STAILQ_FIRST(&sc->tx_free); STAILQ_REMOVE_HEAD(&sc->tx_free, next); sc->tx_nfree--; @@ -1382,8 +1395,8 @@ data->rate = rate; /* XXX need to setup descriptor ourself */ - rum_setup_tx_desc(sc, &data->desc, NULL, flags, 0, 0, m0->m_pkthdr.len, - rate); + rum_setup_tx_desc(sc, &data->desc, NULL, flags, xflags, 0, + m0->m_pkthdr.len, rate); DPRINTFN(10, "sending raw frame len=%u rate=%u\n", m0->m_pkthdr.len, rate); @@ -1405,11 +1418,13 @@ struct ieee80211_key *k = NULL; uint32_t flags = 0; uint16_t dur; + uint8_t type, xflags = 0; int error, hdrlen, rate; RUM_LOCK_ASSERT(sc); wh = mtod(m0, struct ieee80211_frame *); + type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; hdrlen = ieee80211_anyhdrsize(wh); tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; @@ -1436,6 +1451,9 @@ wh = mtod(m0, struct ieee80211_frame *); } + if (type != IEEE80211_FC0_TYPE_CTL && !IEEE80211_QOS_HAS_SEQ(wh)) + xflags |= RT2573_TX_HWSEQ; + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { int prot = IEEE80211_PROT_NONE; if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) @@ -1466,14 +1484,13 @@ if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { flags |= RT2573_TX_NEED_ACK; - flags |= RT2573_TX_MORE_FRAG; dur = ieee80211_ack_duration(ic->ic_rt, rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); USETW(wh->i_dur, dur); } - rum_setup_tx_desc(sc, &data->desc, k, flags, 0, hdrlen, + rum_setup_tx_desc(sc, &data->desc, k, flags, xflags, hdrlen, m0->m_pkthdr.len, rate); DPRINTFN(10, "sending frame len=%d rate=%d\n",