txrx.c (7028B)
1// SPDX-License-Identifier: ISC 2/* 3 * Copyright (c) 2005-2011 Atheros Communications Inc. 4 * Copyright (c) 2011-2016 Qualcomm Atheros, Inc. 5 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 6 */ 7 8#include "core.h" 9#include "txrx.h" 10#include "htt.h" 11#include "mac.h" 12#include "debug.h" 13 14static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb) 15{ 16 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 17 18 if (likely(!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN))) 19 return; 20 21 if (ath10k_mac_tx_frm_has_freq(ar)) 22 return; 23 24 /* If the original wait_for_completion() timed out before 25 * {data,mgmt}_tx_completed() was called then we could complete 26 * offchan_tx_completed for a different skb. Prevent this by using 27 * offchan_tx_skb. 28 */ 29 spin_lock_bh(&ar->data_lock); 30 if (ar->offchan_tx_skb != skb) { 31 ath10k_warn(ar, "completed old offchannel frame\n"); 32 goto out; 33 } 34 35 complete(&ar->offchan_tx_completed); 36 ar->offchan_tx_skb = NULL; /* just for sanity */ 37 38 ath10k_dbg(ar, ATH10K_DBG_HTT, "completed offchannel skb %pK\n", skb); 39out: 40 spin_unlock_bh(&ar->data_lock); 41} 42 43int ath10k_txrx_tx_unref(struct ath10k_htt *htt, 44 const struct htt_tx_done *tx_done) 45{ 46 struct ath10k *ar = htt->ar; 47 struct device *dev = ar->dev; 48 struct ieee80211_tx_info *info; 49 struct ieee80211_txq *txq; 50 struct ath10k_skb_cb *skb_cb; 51 struct ath10k_txq *artxq; 52 struct sk_buff *msdu; 53 u8 flags; 54 55 ath10k_dbg(ar, ATH10K_DBG_HTT, 56 "htt tx completion msdu_id %u status %d\n", 57 tx_done->msdu_id, tx_done->status); 58 59 if (tx_done->msdu_id >= htt->max_num_pending_tx) { 60 ath10k_warn(ar, "warning: msdu_id %d too big, ignoring\n", 61 tx_done->msdu_id); 62 return -EINVAL; 63 } 64 65 spin_lock_bh(&htt->tx_lock); 66 msdu = idr_find(&htt->pending_tx, tx_done->msdu_id); 67 if (!msdu) { 68 ath10k_warn(ar, "received tx completion for invalid msdu_id: %d\n", 69 tx_done->msdu_id); 70 spin_unlock_bh(&htt->tx_lock); 71 return -ENOENT; 72 } 73 74 skb_cb = ATH10K_SKB_CB(msdu); 75 txq = skb_cb->txq; 76 77 if (txq) { 78 artxq = (void *)txq->drv_priv; 79 artxq->num_fw_queued--; 80 } 81 82 flags = skb_cb->flags; 83 ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id); 84 ath10k_htt_tx_dec_pending(htt); 85 spin_unlock_bh(&htt->tx_lock); 86 87 rcu_read_lock(); 88 if (txq && txq->sta && skb_cb->airtime_est) 89 ieee80211_sta_register_airtime(txq->sta, txq->tid, 90 skb_cb->airtime_est, 0); 91 rcu_read_unlock(); 92 93 if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL) 94 dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); 95 96 ath10k_report_offchan_tx(htt->ar, msdu); 97 98 info = IEEE80211_SKB_CB(msdu); 99 memset(&info->status, 0, sizeof(info->status)); 100 info->status.rates[0].idx = -1; 101 102 trace_ath10k_txrx_tx_unref(ar, tx_done->msdu_id); 103 104 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && 105 !(flags & ATH10K_SKB_F_NOACK_TID)) 106 info->flags |= IEEE80211_TX_STAT_ACK; 107 108 if (tx_done->status == HTT_TX_COMPL_STATE_NOACK) 109 info->flags &= ~IEEE80211_TX_STAT_ACK; 110 111 if ((tx_done->status == HTT_TX_COMPL_STATE_ACK) && 112 ((info->flags & IEEE80211_TX_CTL_NO_ACK) || 113 (flags & ATH10K_SKB_F_NOACK_TID))) 114 info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; 115 116 if (tx_done->status == HTT_TX_COMPL_STATE_DISCARD) { 117 if ((info->flags & IEEE80211_TX_CTL_NO_ACK) || 118 (flags & ATH10K_SKB_F_NOACK_TID)) 119 info->flags &= ~IEEE80211_TX_STAT_NOACK_TRANSMITTED; 120 else 121 info->flags &= ~IEEE80211_TX_STAT_ACK; 122 } 123 124 if (tx_done->status == HTT_TX_COMPL_STATE_ACK && 125 tx_done->ack_rssi != ATH10K_INVALID_RSSI) { 126 info->status.ack_signal = ATH10K_DEFAULT_NOISE_FLOOR + 127 tx_done->ack_rssi; 128 info->status.flags |= IEEE80211_TX_STATUS_ACK_SIGNAL_VALID; 129 } 130 131 ieee80211_tx_status(htt->ar->hw, msdu); 132 /* we do not own the msdu anymore */ 133 134 return 0; 135} 136 137struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id, 138 const u8 *addr) 139{ 140 struct ath10k_peer *peer; 141 142 lockdep_assert_held(&ar->data_lock); 143 144 list_for_each_entry(peer, &ar->peers, list) { 145 if (peer->vdev_id != vdev_id) 146 continue; 147 if (!ether_addr_equal(peer->addr, addr)) 148 continue; 149 150 return peer; 151 } 152 153 return NULL; 154} 155 156struct ath10k_peer *ath10k_peer_find_by_id(struct ath10k *ar, int peer_id) 157{ 158 struct ath10k_peer *peer; 159 160 if (peer_id >= BITS_PER_TYPE(peer->peer_ids)) 161 return NULL; 162 163 lockdep_assert_held(&ar->data_lock); 164 165 list_for_each_entry(peer, &ar->peers, list) 166 if (test_bit(peer_id, peer->peer_ids)) 167 return peer; 168 169 return NULL; 170} 171 172static int ath10k_wait_for_peer_common(struct ath10k *ar, int vdev_id, 173 const u8 *addr, bool expect_mapped) 174{ 175 long time_left; 176 177 time_left = wait_event_timeout(ar->peer_mapping_wq, ({ 178 bool mapped; 179 180 spin_lock_bh(&ar->data_lock); 181 mapped = !!ath10k_peer_find(ar, vdev_id, addr); 182 spin_unlock_bh(&ar->data_lock); 183 184 (mapped == expect_mapped || 185 test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)); 186 }), 3 * HZ); 187 188 if (time_left == 0) 189 return -ETIMEDOUT; 190 191 return 0; 192} 193 194int ath10k_wait_for_peer_created(struct ath10k *ar, int vdev_id, const u8 *addr) 195{ 196 return ath10k_wait_for_peer_common(ar, vdev_id, addr, true); 197} 198 199int ath10k_wait_for_peer_deleted(struct ath10k *ar, int vdev_id, const u8 *addr) 200{ 201 return ath10k_wait_for_peer_common(ar, vdev_id, addr, false); 202} 203 204void ath10k_peer_map_event(struct ath10k_htt *htt, 205 struct htt_peer_map_event *ev) 206{ 207 struct ath10k *ar = htt->ar; 208 struct ath10k_peer *peer; 209 210 if (ev->peer_id >= ATH10K_MAX_NUM_PEER_IDS) { 211 ath10k_warn(ar, 212 "received htt peer map event with idx out of bounds: %u\n", 213 ev->peer_id); 214 return; 215 } 216 217 spin_lock_bh(&ar->data_lock); 218 peer = ath10k_peer_find(ar, ev->vdev_id, ev->addr); 219 if (!peer) { 220 peer = kzalloc(sizeof(*peer), GFP_ATOMIC); 221 if (!peer) 222 goto exit; 223 224 peer->vdev_id = ev->vdev_id; 225 ether_addr_copy(peer->addr, ev->addr); 226 list_add(&peer->list, &ar->peers); 227 wake_up(&ar->peer_mapping_wq); 228 } 229 230 ath10k_dbg(ar, ATH10K_DBG_HTT, "htt peer map vdev %d peer %pM id %d\n", 231 ev->vdev_id, ev->addr, ev->peer_id); 232 233 WARN_ON(ar->peer_map[ev->peer_id] && (ar->peer_map[ev->peer_id] != peer)); 234 ar->peer_map[ev->peer_id] = peer; 235 set_bit(ev->peer_id, peer->peer_ids); 236exit: 237 spin_unlock_bh(&ar->data_lock); 238} 239 240void ath10k_peer_unmap_event(struct ath10k_htt *htt, 241 struct htt_peer_unmap_event *ev) 242{ 243 struct ath10k *ar = htt->ar; 244 struct ath10k_peer *peer; 245 246 if (ev->peer_id >= ATH10K_MAX_NUM_PEER_IDS) { 247 ath10k_warn(ar, 248 "received htt peer unmap event with idx out of bounds: %u\n", 249 ev->peer_id); 250 return; 251 } 252 253 spin_lock_bh(&ar->data_lock); 254 peer = ath10k_peer_find_by_id(ar, ev->peer_id); 255 if (!peer) { 256 ath10k_warn(ar, "peer-unmap-event: unknown peer id %d\n", 257 ev->peer_id); 258 goto exit; 259 } 260 261 ath10k_dbg(ar, ATH10K_DBG_HTT, "htt peer unmap vdev %d peer %pM id %d\n", 262 peer->vdev_id, peer->addr, ev->peer_id); 263 264 ar->peer_map[ev->peer_id] = NULL; 265 clear_bit(ev->peer_id, peer->peer_ids); 266 267 if (bitmap_empty(peer->peer_ids, ATH10K_MAX_NUM_PEER_IDS)) { 268 list_del(&peer->list); 269 kfree(peer); 270 wake_up(&ar->peer_mapping_wq); 271 } 272 273exit: 274 spin_unlock_bh(&ar->data_lock); 275}