--- ieee80211-1.0.3/ieee80211_tx.c 2005-07-14 18:53:35.000000000 -0500 +++ ieee80211-1.0.3-mod/ieee80211_tx.c 2005-08-04 14:02:18.000000000 -0500 @@ -131,7 +131,7 @@ payload of each frame is reduced to 492 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; -static inline int ieee80211_put_snap(u8 *data, u16 h_proto) +static inline int ieee80211_copy_snap(u8 *data, u16 h_proto) { struct ieee80211_snap_hdr *snap; u8 *oui; @@ -257,6 +257,7 @@ int ieee80211_xmit(struct sk_buff *skb, u8 dest[ETH_ALEN], src[ETH_ALEN]; struct ieee80211_crypt_data* crypt; int priority = skb->priority; + int snapped = 0; spin_lock_irqsave(&ieee->lock, flags); @@ -308,15 +309,6 @@ int ieee80211_xmit(struct sk_buff *skb, /* Determine total amount of storage required for TXB packets */ bytes = skb->len + SNAP_SIZE + sizeof(u16); - if (skb_headroom(skb) < SNAP_SIZE + sizeof(u16)) { - int res = pskb_expand_head(skb, SNAP_SIZE + sizeof(u16), - 0, GFP_ATOMIC); - if (res) - goto failed; - } - ieee80211_put_snap(skb_push(skb, SNAP_SIZE + sizeof(u16)), ether_type); - - if (host_encrypt) fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | IEEE80211_FCTL_WEP; @@ -349,6 +341,9 @@ int ieee80211_xmit(struct sk_buff *skb, goto failed; skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len); memcpy(skb_put(skb_new, hdr_len), &header, hdr_len); + snapped = 1; + ieee80211_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)), + ether_type); memcpy(skb_put(skb_new, skb->len), skb->data, skb->len); res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv); if (res < 0) { @@ -410,7 +405,8 @@ int ieee80211_xmit(struct sk_buff *skb, } txb->encrypted = encrypt; if (host_encrypt) - txb->payload_size = frag_size * (nr_frags - 1) + bytes_last_frag; + txb->payload_size = frag_size * (nr_frags - 1) + + bytes_last_frag; else txb->payload_size = bytes; @@ -418,7 +414,8 @@ int ieee80211_xmit(struct sk_buff *skb, skb_frag = txb->fragments[i]; if (host_encrypt) - skb_reserve(skb_frag, crypt->ops->extra_mpdu_prefix_len); + skb_reserve(skb_frag, + crypt->ops->extra_mpdu_prefix_len); frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len); memcpy(frag_hdr, &header, hdr_len); @@ -433,6 +430,13 @@ int ieee80211_xmit(struct sk_buff *skb, /* The last fragment takes the remaining length */ bytes = bytes_last_frag; } + + if (i == 0 && !snapped) { + ieee80211_copy_snap( + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), + ether_type); + bytes -= SNAP_SIZE + sizeof(u16); + } memcpy(skb_put(skb_frag, bytes), skb->data, bytes);