|
@@ -2139,6 +2139,28 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
|
|
|
return bf;
|
|
|
}
|
|
|
|
|
|
+void ath_assign_seq(struct ath_common *common, struct sk_buff *skb)
|
|
|
+{
|
|
|
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
|
|
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
|
|
+ struct ieee80211_vif *vif = info->control.vif;
|
|
|
+ struct ath_vif *avp;
|
|
|
+
|
|
|
+ if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (!vif)
|
|
|
+ return;
|
|
|
+
|
|
|
+ avp = (struct ath_vif *)vif->drv_priv;
|
|
|
+
|
|
|
+ if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
|
|
|
+ avp->seq_no += 0x10;
|
|
|
+
|
|
|
+ hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
|
|
|
+ hdr->seq_ctrl |= cpu_to_le16(avp->seq_no);
|
|
|
+}
|
|
|
+
|
|
|
static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|
|
struct ath_tx_control *txctl)
|
|
|
{
|
|
@@ -2162,17 +2184,7 @@ static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|
|
if (info->control.hw_key)
|
|
|
frmlen += info->control.hw_key->icv_len;
|
|
|
|
|
|
- /*
|
|
|
- * 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) {
|
|
|
- if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
|
|
|
- sc->tx.seq_no += 0x10;
|
|
|
- hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
|
|
|
- hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
|
|
|
- }
|
|
|
+ ath_assign_seq(ath9k_hw_common(sc->sc_ah), skb);
|
|
|
|
|
|
if ((vif && vif->type != NL80211_IFTYPE_AP &&
|
|
|
vif->type != NL80211_IFTYPE_AP_VLAN) ||
|