diff options
author | David Lin <dlin@marvell.com> | 2015-03-30 15:49:26 +0800 |
---|---|---|
committer | David Lin <dlin@marvell.com> | 2015-03-30 15:49:26 +0800 |
commit | 22dd866c4110552b60b06c4d31e5d54c6f467a63 (patch) | |
tree | 437be12988cd0714dbbeebd0e3c19885692fa04e | |
parent | 4774b30dce69a8e97c9431e2dc920ea92b5a976c (diff) |
ACK transmitted data or qos data packet to mac80211.
Signed-off-by: David Lin <dlin@marvell.com>
-rw-r--r-- | mwl_tx.c | 28 |
1 files changed, 19 insertions, 9 deletions
@@ -370,16 +370,35 @@ void mwl_tx_done(unsigned long data) { struct mwl_dma_data *tr; + bool ack_frame; struct ieee80211_tx_info *info; int hdrlen; tr = (struct mwl_dma_data *)done_skb->data; + ack_frame = false; if (ieee80211_is_assoc_resp(tr->wh.frame_control) || ieee80211_is_reassoc_resp(tr->wh.frame_control) || ieee80211_is_auth(tr->wh.frame_control) || ieee80211_is_nullfunc(tr->wh.frame_control) || ieee80211_is_qos_nullfunc(tr->wh.frame_control)) { + ack_frame = true; + } else { + skb_queue_tail(&priv->delay_freeq, done_skb); + + if (skb_queue_len(&priv->delay_freeq) > SYSADPT_DELAY_FREE_Q_LIMIT) { + done_skb = skb_dequeue(&priv->delay_freeq); + tr = (struct mwl_dma_data *)done_skb->data; + if (ieee80211_is_data(tr->wh.frame_control) || + ieee80211_is_data_qos(tr->wh.frame_control)) { + ack_frame = true; + } else { + dev_kfree_skb_any(done_skb); + } + } + } + + if (ack_frame == true) { /* Remove H/W dma header */ hdrlen = ieee80211_hdrlen(tr->wh.frame_control); @@ -399,15 +418,6 @@ void mwl_tx_done(unsigned long data) info->flags |= IEEE80211_TX_STAT_ACK; ieee80211_tx_status(hw, done_skb); - } else { - /* Due to firmware does not return real tx status, - * we should not ACK data frame, otherwise, hostap will - * think station is always existed. - */ - skb_queue_tail(&priv->delay_freeq, done_skb); - - if (skb_queue_len(&priv->delay_freeq) > SYSADPT_DELAY_FREE_Q_LIMIT) - dev_kfree_skb_any(skb_dequeue(&priv->delay_freeq)); } } } |