ath9k: Assign seq# when mac80211 requests this
authorJouni Malinen <jouni.malinen@atheros.com>
Mon, 11 Aug 2008 11:01:50 +0000 (14:01 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 29 Aug 2008 20:24:03 +0000 (16:24 -0400)
Use TX control flag IEEE80211_TX_CTL_ASSIGN_SEQ as a request to update
the seq# for the frames. This will likely require some further cleanup
to get seq# correctly for Beacons vs. other frames and also potentially
for multiple BSSes. Anyway, this is better than ending up sending out
most frames with seq# 0.

Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath9k/beacon.c
drivers/net/wireless/ath9k/core.h
drivers/net/wireless/ath9k/main.c

index 8abcd3e8a301035a32d20cce1bf55ed675a11e8e..a020f9a21544ffaafc2381b53dc5b0a88c265ef7 100644 (file)
@@ -209,6 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
        int is_beacon_dtim = 0;
        struct ath_txq *cabq;
        struct ath_txq *mcastq;
+       struct ieee80211_tx_info *info;
        avp = sc->sc_vaps[if_id];
 
        mcastq = &avp->av_mcastq;
@@ -233,6 +234,17 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
        bf->bf_mpdu = skb;
        if (skb == NULL)
                return NULL;
+       info = IEEE80211_SKB_CB(skb);
+       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+               /*
+                * TODO: make sure the seq# gets assigned properly (vs. other
+                * TX frames)
+                */
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+               sc->seq_no += 0x10;
+               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+               hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
+       }
        bf->bf_buf_addr = bf->bf_dmacontext =
                pci_map_single(sc->pdev, skb->data,
                               skb_end_pointer(skb) - skb->head,
index bf7319401889740245b4a38ee8654403335c50e0..c242942bbc1812cbc9cd5d664aecb4a5b94a2131 100644 (file)
@@ -965,6 +965,7 @@ struct ath_softc {
        u32 sc_txqsetup;
        u32 sc_txintrperiod;    /* tx interrupt batching */
        int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */
+       u16 seq_no; /* TX sequence number */
 
        /* Beacon */
        struct ath9k_tx_queue_info sc_beacon_qi;
index 4b61666261e34f7d8e983dae54fccc434dfa8eb6..8fbde897406ee6a2e11c603e1e8105f514fffd43 100644 (file)
@@ -368,6 +368,20 @@ static int ath9k_tx(struct ieee80211_hw *hw,
 {
        struct ath_softc *sc = hw->priv;
        int hdrlen, padsize;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+       /*
+        * As a temporary workaround, assign seq# here; this will likely need
+        * to be cleaned up to work better with Beacon transmission and virtual
+        * BSSes.
+        */
+       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+                       sc->seq_no += 0x10;
+               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+               hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
+       }
 
        /* Add the padding after the header if this is not already done */
        hdrlen = ieee80211_get_hdrlen_from_skb(skb);