aboutsummaryrefslogtreecommitdiff
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-12-08 16:23:31 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-12-08 16:23:31 -0500
commit393934c6b5c8d00f9d1ae20670d4a770f07a418a (patch)
treedad33cd2e4fc0e3d3b28dcbc36cfb44178cb046c /net/mac80211
parent69f4aab1157d2a386e7ea4de77cc253629d1b4f2 (diff)
parent0a54917c3fc295cb61f3fb52373c173fd3b69f48 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Conflicts: drivers/net/wireless/ath/ath9k/ath9k.h drivers/net/wireless/ath/ath9k/main.c drivers/net/wireless/ath/ath9k/xmit.c
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/tx.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5d6b0759d18..0ee56bb0ea7 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1746,15 +1746,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
int nh_pos, h_pos;
struct sta_info *sta = NULL;
u32 sta_flags = 0;
+ struct sk_buff *tmp_skb;
if (unlikely(skb->len < ETH_HLEN)) {
ret = NETDEV_TX_OK;
goto fail;
}
- nh_pos = skb_network_header(skb) - skb->data;
- h_pos = skb_transport_header(skb) - skb->data;
-
/* convert Ethernet header to proper 802.11 header (based on
* operation mode) */
ethertype = (skb->data[12] << 8) | skb->data[13];
@@ -1927,6 +1925,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
goto fail;
}
+ /*
+ * If the skb is shared we need to obtain our own copy.
+ */
+ if (skb_shared(skb)) {
+ tmp_skb = skb;
+ skb = skb_copy(skb, GFP_ATOMIC);
+ kfree_skb(tmp_skb);
+
+ if (!skb) {
+ ret = NETDEV_TX_OK;
+ goto fail;
+ }
+ }
+
hdr.frame_control = fc;
hdr.duration_id = 0;
hdr.seq_ctrl = 0;
@@ -1945,6 +1957,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
encaps_len = 0;
}
+ nh_pos = skb_network_header(skb) - skb->data;
+ h_pos = skb_transport_header(skb) - skb->data;
+
skb_pull(skb, skip_header_bytes);
nh_pos -= skip_header_bytes;
h_pos -= skip_header_bytes;