Author: adrian
Date: Sat Oct  3 22:15:59 2015
New Revision: 288637
URL: https://svnweb.freebsd.org/changeset/base/288637

Log:
  rum(4): fix sequence number generation.
  
  * drop erroneous RT2573_TX_MORE_FRAG flag;
  * provide RT2573_TX_HWSEQ where needed.
  
  Submitted by: <[email protected]>
  Differential Revision:        https://reviews.freebsd.org/D3672

Modified:
  head/sys/dev/usb/wlan/if_rum.c

Modified: head/sys/dev/usb/wlan/if_rum.c
==============================================================================
--- head/sys/dev/usb/wlan/if_rum.c      Sat Oct  3 22:12:25 2015        
(r288636)
+++ head/sys/dev/usb/wlan/if_rum.c      Sat Oct  3 22:15:59 2015        
(r288637)
@@ -1212,7 +1212,7 @@ rum_sendprot(struct rum_softc *sc,
        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 @@ rum_tx_mgt(struct rum_softc *sc, struct 
        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 @@ rum_tx_mgt(struct rum_softc *sc, struct 
        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 @@ rum_tx_mgt(struct rum_softc *sc, struct 
                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 @@ rum_tx_mgt(struct rum_softc *sc, struct 
        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 @@ rum_tx_raw(struct rum_softc *sc, struct 
     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 @@ rum_tx_raw(struct rum_softc *sc, struct 
                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 @@ rum_tx_raw(struct rum_softc *sc, struct 
        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 @@ rum_tx_data(struct rum_softc *sc, struct
        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 @@ rum_tx_data(struct rum_softc *sc, struct
                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 @@ rum_tx_data(struct rum_softc *sc, struct
 
        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",
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to