aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k/txrx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/txrx.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c67
1 files changed, 22 insertions, 45 deletions
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 68b6faefd1d8..5ae373a1e294 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -44,40 +44,39 @@ out:
44 spin_unlock_bh(&ar->data_lock); 44 spin_unlock_bh(&ar->data_lock);
45} 45}
46 46
47void ath10k_txrx_tx_unref(struct ath10k_htt *htt, struct sk_buff *txdesc) 47void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
48 const struct htt_tx_done *tx_done)
48{ 49{
49 struct device *dev = htt->ar->dev; 50 struct device *dev = htt->ar->dev;
50 struct ieee80211_tx_info *info; 51 struct ieee80211_tx_info *info;
51 struct sk_buff *txfrag = ATH10K_SKB_CB(txdesc)->htt.txfrag; 52 struct ath10k_skb_cb *skb_cb;
52 struct sk_buff *msdu = ATH10K_SKB_CB(txdesc)->htt.msdu; 53 struct sk_buff *msdu;
53 int ret; 54 int ret;
54 55
55 if (ATH10K_SKB_CB(txdesc)->htt.refcount == 0) 56 ath10k_dbg(ATH10K_DBG_HTT, "htt tx completion msdu_id %u discard %d no_ack %d\n",
56 return; 57 tx_done->msdu_id, !!tx_done->discard, !!tx_done->no_ack);
57
58 ATH10K_SKB_CB(txdesc)->htt.refcount--;
59 58
60 if (ATH10K_SKB_CB(txdesc)->htt.refcount > 0) 59 if (tx_done->msdu_id >= htt->max_num_pending_tx) {
60 ath10k_warn("warning: msdu_id %d too big, ignoring\n",
61 tx_done->msdu_id);
61 return; 62 return;
62
63 if (txfrag) {
64 ret = ath10k_skb_unmap(dev, txfrag);
65 if (ret)
66 ath10k_warn("txfrag unmap failed (%d)\n", ret);
67
68 dev_kfree_skb_any(txfrag);
69 } 63 }
70 64
65 msdu = htt->pending_tx[tx_done->msdu_id];
66 skb_cb = ATH10K_SKB_CB(msdu);
67
71 ret = ath10k_skb_unmap(dev, msdu); 68 ret = ath10k_skb_unmap(dev, msdu);
72 if (ret) 69 if (ret)
73 ath10k_warn("data skb unmap failed (%d)\n", ret); 70 ath10k_warn("data skb unmap failed (%d)\n", ret);
74 71
72 if (skb_cb->htt.frag_len)
73 skb_pull(msdu, skb_cb->htt.frag_len + skb_cb->htt.pad_len);
74
75 ath10k_report_offchan_tx(htt->ar, msdu); 75 ath10k_report_offchan_tx(htt->ar, msdu);
76 76
77 info = IEEE80211_SKB_CB(msdu); 77 info = IEEE80211_SKB_CB(msdu);
78 memset(&info->status, 0, sizeof(info->status));
79 78
80 if (ATH10K_SKB_CB(txdesc)->htt.discard) { 79 if (tx_done->discard) {
81 ieee80211_free_txskb(htt->ar->hw, msdu); 80 ieee80211_free_txskb(htt->ar->hw, msdu);
82 goto exit; 81 goto exit;
83 } 82 }
@@ -85,7 +84,7 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt, struct sk_buff *txdesc)
85 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 84 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
86 info->flags |= IEEE80211_TX_STAT_ACK; 85 info->flags |= IEEE80211_TX_STAT_ACK;
87 86
88 if (ATH10K_SKB_CB(txdesc)->htt.no_ack) 87 if (tx_done->no_ack)
89 info->flags &= ~IEEE80211_TX_STAT_ACK; 88 info->flags &= ~IEEE80211_TX_STAT_ACK;
90 89
91 ieee80211_tx_status(htt->ar->hw, msdu); 90 ieee80211_tx_status(htt->ar->hw, msdu);
@@ -93,36 +92,12 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt, struct sk_buff *txdesc)
93 92
94exit: 93exit:
95 spin_lock_bh(&htt->tx_lock); 94 spin_lock_bh(&htt->tx_lock);
96 htt->pending_tx[ATH10K_SKB_CB(txdesc)->htt.msdu_id] = NULL; 95 htt->pending_tx[tx_done->msdu_id] = NULL;
97 ath10k_htt_tx_free_msdu_id(htt, ATH10K_SKB_CB(txdesc)->htt.msdu_id); 96 ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id);
98 __ath10k_htt_tx_dec_pending(htt); 97 __ath10k_htt_tx_dec_pending(htt);
99 if (bitmap_empty(htt->used_msdu_ids, htt->max_num_pending_tx)) 98 if (htt->num_pending_tx == 0)
100 wake_up(&htt->empty_tx_wq); 99 wake_up(&htt->empty_tx_wq);
101 spin_unlock_bh(&htt->tx_lock); 100 spin_unlock_bh(&htt->tx_lock);
102
103 dev_kfree_skb_any(txdesc);
104}
105
106void ath10k_txrx_tx_completed(struct ath10k_htt *htt,
107 const struct htt_tx_done *tx_done)
108{
109 struct sk_buff *txdesc;
110
111 ath10k_dbg(ATH10K_DBG_HTT, "htt tx completion msdu_id %u discard %d no_ack %d\n",
112 tx_done->msdu_id, !!tx_done->discard, !!tx_done->no_ack);
113
114 if (tx_done->msdu_id >= htt->max_num_pending_tx) {
115 ath10k_warn("warning: msdu_id %d too big, ignoring\n",
116 tx_done->msdu_id);
117 return;
118 }
119
120 txdesc = htt->pending_tx[tx_done->msdu_id];
121
122 ATH10K_SKB_CB(txdesc)->htt.discard = tx_done->discard;
123 ATH10K_SKB_CB(txdesc)->htt.no_ack = tx_done->no_ack;
124
125 ath10k_txrx_tx_unref(htt, txdesc);
126} 101}
127 102
128static const u8 rx_legacy_rate_idx[] = { 103static const u8 rx_legacy_rate_idx[] = {
@@ -293,6 +268,8 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
293 status->vht_nss, 268 status->vht_nss,
294 status->freq, 269 status->freq,
295 status->band); 270 status->band);
271 ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
272 info->skb->data, info->skb->len);
296 273
297 ieee80211_rx(ar->hw, info->skb); 274 ieee80211_rx(ar->hw, info->skb);
298} 275}