diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/txrx.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 348c6463fe00..0869ff396b57 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c | |||
@@ -317,6 +317,24 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) | |||
317 | 317 | ||
318 | spin_unlock_bh(&ar->lock); | 318 | spin_unlock_bh(&ar->lock); |
319 | 319 | ||
320 | if (!IS_ALIGNED((unsigned long) skb->data - HTC_HDR_LENGTH, 4) && | ||
321 | skb_cloned(skb)) { | ||
322 | /* | ||
323 | * We will touch (move the buffer data to align it. Since the | ||
324 | * skb buffer is cloned and not only the header is changed, we | ||
325 | * have to copy it to allow the changes. Since we are copying | ||
326 | * the data here, we may as well align it by reserving suitable | ||
327 | * headroom to avoid the memmove in ath6kl_htc_tx_buf_align(). | ||
328 | */ | ||
329 | struct sk_buff *nskb; | ||
330 | |||
331 | nskb = skb_copy_expand(skb, HTC_HDR_LENGTH, 0, GFP_ATOMIC); | ||
332 | if (nskb == NULL) | ||
333 | goto fail_tx; | ||
334 | kfree_skb(skb); | ||
335 | skb = nskb; | ||
336 | } | ||
337 | |||
320 | cookie->skb = skb; | 338 | cookie->skb = skb; |
321 | cookie->map_no = map_no; | 339 | cookie->map_no = map_no; |
322 | set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len, | 340 | set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len, |