From: Jouni Malinen Date: Mon, 11 Aug 2008 11:01:50 +0000 (+0300) Subject: ath9k: Assign seq# when mac80211 requests this X-Git-Tag: v2.6.28-rc1~717^2~384^2~42 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=147583c057c43095925b5f331fe304f2d5b997ba;p=linux-2.6-omap-h63xx.git ath9k: Assign seq# when mac80211 requests this 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 Signed-off-by: John W. Linville --- diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index 8abcd3e8a30..a020f9a2154 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -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, diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index bf731940188..c242942bbc1 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -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; diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 4b61666261e..8fbde897406 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -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);