@@ -654,6 +654,24 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
(full_len << 19));
}
+static void create_tx_desc_seq(struct zd_mac *mac, struct ieee80211_hdr *hdr,
+ struct ieee80211_tx_info *info)
+{
+ unsigned long irqflags;
+
+ if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
+ return;
+
+ spin_lock_irqsave(&mac->seqlock, irqflags);
+
+ if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+ mac->seqno += 0x10;
+ hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+ hdr->seq_ctrl |= cpu_to_le16(mac->seqno);
+
+ spin_unlock_irqrestore(&mac->seqlock, irqflags);
+}
+
static int fill_ctrlset(struct zd_mac *mac,
struct sk_buff *skb)
{
@@ -678,6 +696,8 @@ static int fill_ctrlset(struct zd_mac *mac,
cs_set_control(mac, cs, hdr, info);
+ create_tx_desc_seq(mac, hdr, info);
+
packet_length = frag_len + sizeof(struct zd_ctrlset) + 10;
ZD_ASSERT(packet_length <= 0xffff);
/* ZD1211B: Computing the length difference this way, gives us
@@ -1117,6 +1137,7 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
memset(mac, 0, sizeof(*mac));
spin_lock_init(&mac->lock);
+ spin_lock_init(&mac->seqlock);
mac->hw = hw;
mac->type = NL80211_IFTYPE_UNSPECIFIED;
@@ -186,6 +186,8 @@ struct zd_mac {
struct ieee80211_channel channels[14];
struct ieee80211_rate rates[12];
struct ieee80211_supported_band band;
+ spinlock_t seqlock;
+ u16 seqno;
/* Short preamble (used for RTS/CTS) */
unsigned int short_preamble:1;