summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Yariv <ido@wizery.com>2011-02-28 00:16:13 +0200
committerLuciano Coelho <coelho@ti.com>2011-03-03 16:10:45 +0200
commit50e9f746f63c9b881f2ca4a35dbdfd34b1a8a215 (patch)
treeb0d81cbf3fc53f8535f114712106b336b8b7a4d4
parent11251e7e5c7c5411d1f77dbc7f9bfa2c23626749 (diff)
downloadlinux-50e9f746f63c9b881f2ca4a35dbdfd34b1a8a215.tar.bz2
wl12xx: Remove private headers in wl1271_tx_reset
Frames in the tx_frames array include extra private headers, which must be removed before passing the skbs to ieee80211_tx_status. Fix this by removing any private headers in wl1271_tx_reset, similar to how this is done in wl1271_tx_complete_packet. Signed-off-by: Ido Yariv <ido@wizery.com> Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
-rw-r--r--drivers/net/wireless/wl12xx/tx.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index ac60d577319f..37d354ddd58e 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -687,16 +687,30 @@ void wl1271_tx_reset(struct wl1271 *wl)
*/
wl1271_handle_tx_low_watermark(wl);
- for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
- if (wl->tx_frames[i] != NULL) {
- skb = wl->tx_frames[i];
- wl1271_free_tx_id(wl, i);
- wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
- info = IEEE80211_SKB_CB(skb);
- info->status.rates[0].idx = -1;
- info->status.rates[0].count = 0;
- ieee80211_tx_status(wl->hw, skb);
+ for (i = 0; i < ACX_TX_DESCRIPTORS; i++) {
+ if (wl->tx_frames[i] == NULL)
+ continue;
+
+ skb = wl->tx_frames[i];
+ wl1271_free_tx_id(wl, i);
+ wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
+
+ /* Remove private headers before passing the skb to mac80211 */
+ info = IEEE80211_SKB_CB(skb);
+ skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
+ if (info->control.hw_key &&
+ info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
+ int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data,
+ hdrlen);
+ skb_pull(skb, WL1271_TKIP_IV_SPACE);
}
+
+ info->status.rates[0].idx = -1;
+ info->status.rates[0].count = 0;
+
+ ieee80211_tx_status(wl->hw, skb);
+ }
}
#define WL1271_TX_FLUSH_TIMEOUT 500000