Branch data Line data Source code
1 : : // SPDX-License-Identifier: ISC
2 : : /*
3 : : * Copyright (c) 2005-2011 Atheros Communications Inc.
4 : : * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
5 : : * Copyright (c) 2018, The Linux Foundation. All rights reserved.
6 : : */
7 : :
8 : : #include "core.h"
9 : : #include "htc.h"
10 : : #include "htt.h"
11 : : #include "txrx.h"
12 : : #include "debug.h"
13 : : #include "trace.h"
14 : : #include "mac.h"
15 : :
16 : : #include <linux/log2.h>
17 : : #include <linux/bitfield.h>
18 : :
19 : : /* when under memory pressure rx ring refill may fail and needs a retry */
20 : : #define HTT_RX_RING_REFILL_RETRY_MS 50
21 : :
22 : : #define HTT_RX_RING_REFILL_RESCHED_MS 5
23 : :
24 : : static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb);
25 : :
26 : : static struct sk_buff *
27 : 0 : ath10k_htt_rx_find_skb_paddr(struct ath10k *ar, u64 paddr)
28 : : {
29 : 0 : struct ath10k_skb_rxcb *rxcb;
30 : :
31 [ # # # # : 0 : hash_for_each_possible(ar->htt.rx_ring.skb_table, rxcb, hlist, paddr)
# # ]
32 [ # # ]: 0 : if (rxcb->paddr == paddr)
33 : 0 : return ATH10K_RXCB_SKB(rxcb);
34 : :
35 : 0 : WARN_ON_ONCE(1);
36 : 0 : return NULL;
37 : : }
38 : :
39 : 0 : static void ath10k_htt_rx_ring_free(struct ath10k_htt *htt)
40 : : {
41 : 0 : struct sk_buff *skb;
42 : 0 : struct ath10k_skb_rxcb *rxcb;
43 : 0 : struct hlist_node *n;
44 : 0 : int i;
45 : :
46 [ # # ]: 0 : if (htt->rx_ring.in_ord_rx) {
47 [ # # # # : 0 : hash_for_each_safe(htt->rx_ring.skb_table, i, n, rxcb, hlist) {
# # # # #
# ]
48 : 0 : skb = ATH10K_RXCB_SKB(rxcb);
49 [ # # ]: 0 : dma_unmap_single(htt->ar->dev, rxcb->paddr,
50 : : skb->len + skb_tailroom(skb),
51 : : DMA_FROM_DEVICE);
52 [ # # ]: 0 : hash_del(&rxcb->hlist);
53 : 0 : dev_kfree_skb_any(skb);
54 : : }
55 : : } else {
56 [ # # ]: 0 : for (i = 0; i < htt->rx_ring.size; i++) {
57 : 0 : skb = htt->rx_ring.netbufs_ring[i];
58 [ # # ]: 0 : if (!skb)
59 : 0 : continue;
60 : :
61 [ # # ]: 0 : rxcb = ATH10K_SKB_RXCB(skb);
62 [ # # ]: 0 : dma_unmap_single(htt->ar->dev, rxcb->paddr,
63 : : skb->len + skb_tailroom(skb),
64 : : DMA_FROM_DEVICE);
65 : 0 : dev_kfree_skb_any(skb);
66 : : }
67 : : }
68 : :
69 : 0 : htt->rx_ring.fill_cnt = 0;
70 : 0 : hash_init(htt->rx_ring.skb_table);
71 : 0 : memset(htt->rx_ring.netbufs_ring, 0,
72 : 0 : htt->rx_ring.size * sizeof(htt->rx_ring.netbufs_ring[0]));
73 : 0 : }
74 : :
75 : 0 : static size_t ath10k_htt_get_rx_ring_size_32(struct ath10k_htt *htt)
76 : : {
77 : 0 : return htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring_32);
78 : : }
79 : :
80 : 0 : static size_t ath10k_htt_get_rx_ring_size_64(struct ath10k_htt *htt)
81 : : {
82 : 0 : return htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring_64);
83 : : }
84 : :
85 : 0 : static void ath10k_htt_config_paddrs_ring_32(struct ath10k_htt *htt,
86 : : void *vaddr)
87 : : {
88 : 0 : htt->rx_ring.paddrs_ring_32 = vaddr;
89 : 0 : }
90 : :
91 : 0 : static void ath10k_htt_config_paddrs_ring_64(struct ath10k_htt *htt,
92 : : void *vaddr)
93 : : {
94 : 0 : htt->rx_ring.paddrs_ring_64 = vaddr;
95 : 0 : }
96 : :
97 : 0 : static void ath10k_htt_set_paddrs_ring_32(struct ath10k_htt *htt,
98 : : dma_addr_t paddr, int idx)
99 : : {
100 : 0 : htt->rx_ring.paddrs_ring_32[idx] = __cpu_to_le32(paddr);
101 : 0 : }
102 : :
103 : 0 : static void ath10k_htt_set_paddrs_ring_64(struct ath10k_htt *htt,
104 : : dma_addr_t paddr, int idx)
105 : : {
106 : 0 : htt->rx_ring.paddrs_ring_64[idx] = __cpu_to_le64(paddr);
107 : 0 : }
108 : :
109 : 0 : static void ath10k_htt_reset_paddrs_ring_32(struct ath10k_htt *htt, int idx)
110 : : {
111 : 0 : htt->rx_ring.paddrs_ring_32[idx] = 0;
112 : 0 : }
113 : :
114 : 0 : static void ath10k_htt_reset_paddrs_ring_64(struct ath10k_htt *htt, int idx)
115 : : {
116 : 0 : htt->rx_ring.paddrs_ring_64[idx] = 0;
117 : 0 : }
118 : :
119 : 0 : static void *ath10k_htt_get_vaddr_ring_32(struct ath10k_htt *htt)
120 : : {
121 : 0 : return (void *)htt->rx_ring.paddrs_ring_32;
122 : : }
123 : :
124 : 0 : static void *ath10k_htt_get_vaddr_ring_64(struct ath10k_htt *htt)
125 : : {
126 : 0 : return (void *)htt->rx_ring.paddrs_ring_64;
127 : : }
128 : :
129 : 0 : static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
130 : : {
131 : 0 : struct htt_rx_desc *rx_desc;
132 : 0 : struct ath10k_skb_rxcb *rxcb;
133 : 0 : struct sk_buff *skb;
134 : 0 : dma_addr_t paddr;
135 : 0 : int ret = 0, idx;
136 : :
137 : : /* The Full Rx Reorder firmware has no way of telling the host
138 : : * implicitly when it copied HTT Rx Ring buffers to MAC Rx Ring.
139 : : * To keep things simple make sure ring is always half empty. This
140 : : * guarantees there'll be no replenishment overruns possible.
141 : : */
142 : 0 : BUILD_BUG_ON(HTT_RX_RING_FILL_LEVEL >= HTT_RX_RING_SIZE / 2);
143 : :
144 : 0 : idx = __le32_to_cpu(*htt->rx_ring.alloc_idx.vaddr);
145 [ # # ]: 0 : while (num > 0) {
146 : 0 : skb = dev_alloc_skb(HTT_RX_BUF_SIZE + HTT_RX_DESC_ALIGN);
147 [ # # ]: 0 : if (!skb) {
148 : 0 : ret = -ENOMEM;
149 : 0 : goto fail;
150 : : }
151 : :
152 [ # # ]: 0 : if (!IS_ALIGNED((unsigned long)skb->data, HTT_RX_DESC_ALIGN))
153 : 0 : skb_pull(skb,
154 : 0 : PTR_ALIGN(skb->data, HTT_RX_DESC_ALIGN) -
155 : : skb->data);
156 : :
157 : : /* Clear rx_desc attention word before posting to Rx ring */
158 : 0 : rx_desc = (struct htt_rx_desc *)skb->data;
159 : 0 : rx_desc->attention.flags = __cpu_to_le32(0);
160 : :
161 [ # # ]: 0 : paddr = dma_map_single(htt->ar->dev, skb->data,
162 : : skb->len + skb_tailroom(skb),
163 : : DMA_FROM_DEVICE);
164 : :
165 [ # # ]: 0 : if (unlikely(dma_mapping_error(htt->ar->dev, paddr))) {
166 : 0 : dev_kfree_skb_any(skb);
167 : 0 : ret = -ENOMEM;
168 : 0 : goto fail;
169 : : }
170 : :
171 [ # # ]: 0 : rxcb = ATH10K_SKB_RXCB(skb);
172 : 0 : rxcb->paddr = paddr;
173 : 0 : htt->rx_ring.netbufs_ring[idx] = skb;
174 [ # # ]: 0 : ath10k_htt_set_paddrs_ring(htt, paddr, idx);
175 : 0 : htt->rx_ring.fill_cnt++;
176 : :
177 [ # # ]: 0 : if (htt->rx_ring.in_ord_rx) {
178 [ # # ]: 0 : hash_add(htt->rx_ring.skb_table,
179 : : &ATH10K_SKB_RXCB(skb)->hlist,
180 : : paddr);
181 : : }
182 : :
183 : 0 : num--;
184 : 0 : idx++;
185 : 0 : idx &= htt->rx_ring.size_mask;
186 : : }
187 : :
188 : 0 : fail:
189 : : /*
190 : : * Make sure the rx buffer is updated before available buffer
191 : : * index to avoid any potential rx ring corruption.
192 : : */
193 : 0 : mb();
194 : 0 : *htt->rx_ring.alloc_idx.vaddr = __cpu_to_le32(idx);
195 : 0 : return ret;
196 : : }
197 : :
198 : 0 : static int ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
199 : : {
200 : 0 : lockdep_assert_held(&htt->rx_ring.lock);
201 : 0 : return __ath10k_htt_rx_ring_fill_n(htt, num);
202 : : }
203 : :
204 : 0 : static void ath10k_htt_rx_msdu_buff_replenish(struct ath10k_htt *htt)
205 : : {
206 : 0 : int ret, num_deficit, num_to_fill;
207 : :
208 : : /* Refilling the whole RX ring buffer proves to be a bad idea. The
209 : : * reason is RX may take up significant amount of CPU cycles and starve
210 : : * other tasks, e.g. TX on an ethernet device while acting as a bridge
211 : : * with ath10k wlan interface. This ended up with very poor performance
212 : : * once CPU the host system was overwhelmed with RX on ath10k.
213 : : *
214 : : * By limiting the number of refills the replenishing occurs
215 : : * progressively. This in turns makes use of the fact tasklets are
216 : : * processed in FIFO order. This means actual RX processing can starve
217 : : * out refilling. If there's not enough buffers on RX ring FW will not
218 : : * report RX until it is refilled with enough buffers. This
219 : : * automatically balances load wrt to CPU power.
220 : : *
221 : : * This probably comes at a cost of lower maximum throughput but
222 : : * improves the average and stability.
223 : : */
224 : 0 : spin_lock_bh(&htt->rx_ring.lock);
225 : 0 : num_deficit = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt;
226 : 0 : num_to_fill = min(ATH10K_HTT_MAX_NUM_REFILL, num_deficit);
227 : 0 : num_deficit -= num_to_fill;
228 : 0 : ret = ath10k_htt_rx_ring_fill_n(htt, num_to_fill);
229 [ # # ]: 0 : if (ret == -ENOMEM) {
230 : : /*
231 : : * Failed to fill it to the desired level -
232 : : * we'll start a timer and try again next time.
233 : : * As long as enough buffers are left in the ring for
234 : : * another A-MPDU rx, no special recovery is needed.
235 : : */
236 : 0 : mod_timer(&htt->rx_ring.refill_retry_timer, jiffies +
237 : : msecs_to_jiffies(HTT_RX_RING_REFILL_RETRY_MS));
238 [ # # ]: 0 : } else if (num_deficit > 0) {
239 : 0 : mod_timer(&htt->rx_ring.refill_retry_timer, jiffies +
240 : : msecs_to_jiffies(HTT_RX_RING_REFILL_RESCHED_MS));
241 : : }
242 : 0 : spin_unlock_bh(&htt->rx_ring.lock);
243 : 0 : }
244 : :
245 : 0 : static void ath10k_htt_rx_ring_refill_retry(struct timer_list *t)
246 : : {
247 : 0 : struct ath10k_htt *htt = from_timer(htt, t, rx_ring.refill_retry_timer);
248 : :
249 : 0 : ath10k_htt_rx_msdu_buff_replenish(htt);
250 : 0 : }
251 : :
252 : 0 : int ath10k_htt_rx_ring_refill(struct ath10k *ar)
253 : : {
254 : 0 : struct ath10k_htt *htt = &ar->htt;
255 : 0 : int ret;
256 : :
257 [ # # ]: 0 : if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
258 : : return 0;
259 : :
260 : 0 : spin_lock_bh(&htt->rx_ring.lock);
261 : 0 : ret = ath10k_htt_rx_ring_fill_n(htt, (htt->rx_ring.fill_level -
262 : 0 : htt->rx_ring.fill_cnt));
263 : :
264 [ # # ]: 0 : if (ret)
265 : 0 : ath10k_htt_rx_ring_free(htt);
266 : :
267 : 0 : spin_unlock_bh(&htt->rx_ring.lock);
268 : :
269 : 0 : return ret;
270 : : }
271 : :
272 : 0 : void ath10k_htt_rx_free(struct ath10k_htt *htt)
273 : : {
274 [ # # ]: 0 : if (htt->ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
275 : : return;
276 : :
277 : 0 : del_timer_sync(&htt->rx_ring.refill_retry_timer);
278 : :
279 : 0 : skb_queue_purge(&htt->rx_msdus_q);
280 : 0 : skb_queue_purge(&htt->rx_in_ord_compl_q);
281 : 0 : skb_queue_purge(&htt->tx_fetch_ind_q);
282 : :
283 : 0 : spin_lock_bh(&htt->rx_ring.lock);
284 : 0 : ath10k_htt_rx_ring_free(htt);
285 : 0 : spin_unlock_bh(&htt->rx_ring.lock);
286 : :
287 [ # # ]: 0 : dma_free_coherent(htt->ar->dev,
288 : : ath10k_htt_get_rx_ring_size(htt),
289 : : ath10k_htt_get_vaddr_ring(htt),
290 : : htt->rx_ring.base_paddr);
291 : :
292 : 0 : dma_free_coherent(htt->ar->dev,
293 : : sizeof(*htt->rx_ring.alloc_idx.vaddr),
294 : 0 : htt->rx_ring.alloc_idx.vaddr,
295 : : htt->rx_ring.alloc_idx.paddr);
296 : :
297 : 0 : kfree(htt->rx_ring.netbufs_ring);
298 : : }
299 : :
300 : 0 : static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt)
301 : : {
302 : 0 : struct ath10k *ar = htt->ar;
303 : 0 : int idx;
304 : 0 : struct sk_buff *msdu;
305 : :
306 : 0 : lockdep_assert_held(&htt->rx_ring.lock);
307 : :
308 [ # # ]: 0 : if (htt->rx_ring.fill_cnt == 0) {
309 : 0 : ath10k_warn(ar, "tried to pop sk_buff from an empty rx ring\n");
310 : 0 : return NULL;
311 : : }
312 : :
313 : 0 : idx = htt->rx_ring.sw_rd_idx.msdu_payld;
314 : 0 : msdu = htt->rx_ring.netbufs_ring[idx];
315 : 0 : htt->rx_ring.netbufs_ring[idx] = NULL;
316 [ # # ]: 0 : ath10k_htt_reset_paddrs_ring(htt, idx);
317 : :
318 : 0 : idx++;
319 : 0 : idx &= htt->rx_ring.size_mask;
320 : 0 : htt->rx_ring.sw_rd_idx.msdu_payld = idx;
321 : 0 : htt->rx_ring.fill_cnt--;
322 : :
323 [ # # ]: 0 : dma_unmap_single(htt->ar->dev,
324 : : ATH10K_SKB_RXCB(msdu)->paddr,
325 : : msdu->len + skb_tailroom(msdu),
326 : : DMA_FROM_DEVICE);
327 : 0 : ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx netbuf pop: ",
328 [ # # ]: 0 : msdu->data, msdu->len + skb_tailroom(msdu));
329 : :
330 : 0 : return msdu;
331 : : }
332 : :
333 : : /* return: < 0 fatal error, 0 - non chained msdu, 1 chained msdu */
334 : 0 : static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
335 : : struct sk_buff_head *amsdu)
336 : : {
337 : 0 : struct ath10k *ar = htt->ar;
338 : 0 : int msdu_len, msdu_chaining = 0;
339 : 0 : struct sk_buff *msdu;
340 : 0 : struct htt_rx_desc *rx_desc;
341 : :
342 : 0 : lockdep_assert_held(&htt->rx_ring.lock);
343 : :
344 : 0 : for (;;) {
345 : 0 : int last_msdu, msdu_len_invalid, msdu_chained;
346 : :
347 : 0 : msdu = ath10k_htt_rx_netbuf_pop(htt);
348 [ # # ]: 0 : if (!msdu) {
349 : 0 : __skb_queue_purge(amsdu);
350 : 0 : return -ENOENT;
351 : : }
352 : :
353 : 0 : __skb_queue_tail(amsdu, msdu);
354 : :
355 : 0 : rx_desc = (struct htt_rx_desc *)msdu->data;
356 : :
357 : : /* FIXME: we must report msdu payload since this is what caller
358 : : * expects now
359 : : */
360 : 0 : skb_put(msdu, offsetof(struct htt_rx_desc, msdu_payload));
361 : 0 : skb_pull(msdu, offsetof(struct htt_rx_desc, msdu_payload));
362 : :
363 : : /*
364 : : * Sanity check - confirm the HW is finished filling in the
365 : : * rx data.
366 : : * If the HW and SW are working correctly, then it's guaranteed
367 : : * that the HW's MAC DMA is done before this point in the SW.
368 : : * To prevent the case that we handle a stale Rx descriptor,
369 : : * just assert for now until we have a way to recover.
370 : : */
371 [ # # ]: 0 : if (!(__le32_to_cpu(rx_desc->attention.flags)
372 : : & RX_ATTENTION_FLAGS_MSDU_DONE)) {
373 : 0 : __skb_queue_purge(amsdu);
374 : 0 : return -EIO;
375 : : }
376 : :
377 : 0 : msdu_len_invalid = !!(__le32_to_cpu(rx_desc->attention.flags)
378 : 0 : & (RX_ATTENTION_FLAGS_MPDU_LENGTH_ERR |
379 : : RX_ATTENTION_FLAGS_MSDU_LENGTH_ERR));
380 : 0 : msdu_len = MS(__le32_to_cpu(rx_desc->msdu_start.common.info0),
381 : : RX_MSDU_START_INFO0_MSDU_LENGTH);
382 : 0 : msdu_chained = rx_desc->frag_info.ring2_more_count;
383 : :
384 [ # # ]: 0 : if (msdu_len_invalid)
385 : 0 : msdu_len = 0;
386 : :
387 : 0 : skb_trim(msdu, 0);
388 : 0 : skb_put(msdu, min(msdu_len, HTT_RX_MSDU_SIZE));
389 : 0 : msdu_len -= msdu->len;
390 : :
391 : : /* Note: Chained buffers do not contain rx descriptor */
392 [ # # ]: 0 : while (msdu_chained--) {
393 : 0 : msdu = ath10k_htt_rx_netbuf_pop(htt);
394 [ # # ]: 0 : if (!msdu) {
395 : 0 : __skb_queue_purge(amsdu);
396 : 0 : return -ENOENT;
397 : : }
398 : :
399 : 0 : __skb_queue_tail(amsdu, msdu);
400 : 0 : skb_trim(msdu, 0);
401 : 0 : skb_put(msdu, min(msdu_len, HTT_RX_BUF_SIZE));
402 : 0 : msdu_len -= msdu->len;
403 : 0 : msdu_chaining = 1;
404 : : }
405 : :
406 : 0 : last_msdu = __le32_to_cpu(rx_desc->msdu_end.common.info0) &
407 : : RX_MSDU_END_INFO0_LAST_MSDU;
408 : :
409 : 0 : trace_ath10k_htt_rx_desc(ar, &rx_desc->attention,
410 : : sizeof(*rx_desc) - sizeof(u32));
411 : :
412 [ # # ]: 0 : if (last_msdu)
413 : : break;
414 : : }
415 : :
416 [ # # ]: 0 : if (skb_queue_empty(amsdu))
417 : 0 : msdu_chaining = -1;
418 : :
419 : : /*
420 : : * Don't refill the ring yet.
421 : : *
422 : : * First, the elements popped here are still in use - it is not
423 : : * safe to overwrite them until the matching call to
424 : : * mpdu_desc_list_next. Second, for efficiency it is preferable to
425 : : * refill the rx ring with 1 PPDU's worth of rx buffers (something
426 : : * like 32 x 3 buffers), rather than one MPDU's worth of rx buffers
427 : : * (something like 3 buffers). Consequently, we'll rely on the txrx
428 : : * SW to tell us when it is done pulling all the PPDU's rx buffers
429 : : * out of the rx ring, and then refill it just once.
430 : : */
431 : :
432 : : return msdu_chaining;
433 : : }
434 : :
435 : : static struct sk_buff *ath10k_htt_rx_pop_paddr(struct ath10k_htt *htt,
436 : : u64 paddr)
437 : : {
438 : : struct ath10k *ar = htt->ar;
439 : : struct ath10k_skb_rxcb *rxcb;
440 : : struct sk_buff *msdu;
441 : :
442 : : lockdep_assert_held(&htt->rx_ring.lock);
443 : :
444 : : msdu = ath10k_htt_rx_find_skb_paddr(ar, paddr);
445 : : if (!msdu)
446 : : return NULL;
447 : :
448 : : rxcb = ATH10K_SKB_RXCB(msdu);
449 : : hash_del(&rxcb->hlist);
450 : : htt->rx_ring.fill_cnt--;
451 : :
452 : : dma_unmap_single(htt->ar->dev, rxcb->paddr,
453 : : msdu->len + skb_tailroom(msdu),
454 : : DMA_FROM_DEVICE);
455 : : ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx netbuf pop: ",
456 : : msdu->data, msdu->len + skb_tailroom(msdu));
457 : :
458 : : return msdu;
459 : : }
460 : :
461 : 0 : static inline void ath10k_htt_append_frag_list(struct sk_buff *skb_head,
462 : : struct sk_buff *frag_list,
463 : : unsigned int frag_len)
464 : : {
465 : 0 : skb_shinfo(skb_head)->frag_list = frag_list;
466 : 0 : skb_head->data_len = frag_len;
467 : 0 : skb_head->len += skb_head->data_len;
468 : : }
469 : :
470 : 0 : static int ath10k_htt_rx_handle_amsdu_mon_32(struct ath10k_htt *htt,
471 : : struct sk_buff *msdu,
472 : : struct htt_rx_in_ord_msdu_desc **msdu_desc)
473 : : {
474 : 0 : struct ath10k *ar = htt->ar;
475 : 0 : u32 paddr;
476 : 0 : struct sk_buff *frag_buf;
477 : 0 : struct sk_buff *prev_frag_buf;
478 : 0 : u8 last_frag;
479 : 0 : struct htt_rx_in_ord_msdu_desc *ind_desc = *msdu_desc;
480 : 0 : struct htt_rx_desc *rxd;
481 : 0 : int amsdu_len = __le16_to_cpu(ind_desc->msdu_len);
482 : :
483 : 0 : rxd = (void *)msdu->data;
484 : 0 : trace_ath10k_htt_rx_desc(ar, rxd, sizeof(*rxd));
485 : :
486 : 0 : skb_put(msdu, sizeof(struct htt_rx_desc));
487 : 0 : skb_pull(msdu, sizeof(struct htt_rx_desc));
488 : 0 : skb_put(msdu, min(amsdu_len, HTT_RX_MSDU_SIZE));
489 : 0 : amsdu_len -= msdu->len;
490 : :
491 : 0 : last_frag = ind_desc->reserved;
492 [ # # ]: 0 : if (last_frag) {
493 [ # # ]: 0 : if (amsdu_len) {
494 : 0 : ath10k_warn(ar, "invalid amsdu len %u, left %d",
495 : 0 : __le16_to_cpu(ind_desc->msdu_len),
496 : : amsdu_len);
497 : : }
498 : 0 : return 0;
499 : : }
500 : :
501 : 0 : ind_desc++;
502 : 0 : paddr = __le32_to_cpu(ind_desc->msdu_paddr);
503 : 0 : frag_buf = ath10k_htt_rx_pop_paddr(htt, paddr);
504 [ # # ]: 0 : if (!frag_buf) {
505 : 0 : ath10k_warn(ar, "failed to pop frag-1 paddr: 0x%x", paddr);
506 : 0 : return -ENOENT;
507 : : }
508 : :
509 : 0 : skb_put(frag_buf, min(amsdu_len, HTT_RX_BUF_SIZE));
510 : 0 : ath10k_htt_append_frag_list(msdu, frag_buf, amsdu_len);
511 : :
512 : 0 : amsdu_len -= frag_buf->len;
513 : 0 : prev_frag_buf = frag_buf;
514 : 0 : last_frag = ind_desc->reserved;
515 [ # # ]: 0 : while (!last_frag) {
516 : 0 : ind_desc++;
517 : 0 : paddr = __le32_to_cpu(ind_desc->msdu_paddr);
518 : 0 : frag_buf = ath10k_htt_rx_pop_paddr(htt, paddr);
519 [ # # ]: 0 : if (!frag_buf) {
520 : 0 : ath10k_warn(ar, "failed to pop frag-n paddr: 0x%x",
521 : : paddr);
522 : 0 : prev_frag_buf->next = NULL;
523 : 0 : return -ENOENT;
524 : : }
525 : :
526 : 0 : skb_put(frag_buf, min(amsdu_len, HTT_RX_BUF_SIZE));
527 : 0 : last_frag = ind_desc->reserved;
528 : 0 : amsdu_len -= frag_buf->len;
529 : :
530 : 0 : prev_frag_buf->next = frag_buf;
531 : 0 : prev_frag_buf = frag_buf;
532 : : }
533 : :
534 [ # # ]: 0 : if (amsdu_len) {
535 : 0 : ath10k_warn(ar, "invalid amsdu len %u, left %d",
536 : 0 : __le16_to_cpu(ind_desc->msdu_len), amsdu_len);
537 : : }
538 : :
539 : 0 : *msdu_desc = ind_desc;
540 : :
541 : 0 : prev_frag_buf->next = NULL;
542 : 0 : return 0;
543 : : }
544 : :
545 : : static int
546 : 0 : ath10k_htt_rx_handle_amsdu_mon_64(struct ath10k_htt *htt,
547 : : struct sk_buff *msdu,
548 : : struct htt_rx_in_ord_msdu_desc_ext **msdu_desc)
549 : : {
550 : 0 : struct ath10k *ar = htt->ar;
551 : 0 : u64 paddr;
552 : 0 : struct sk_buff *frag_buf;
553 : 0 : struct sk_buff *prev_frag_buf;
554 : 0 : u8 last_frag;
555 : 0 : struct htt_rx_in_ord_msdu_desc_ext *ind_desc = *msdu_desc;
556 : 0 : struct htt_rx_desc *rxd;
557 : 0 : int amsdu_len = __le16_to_cpu(ind_desc->msdu_len);
558 : :
559 : 0 : rxd = (void *)msdu->data;
560 : 0 : trace_ath10k_htt_rx_desc(ar, rxd, sizeof(*rxd));
561 : :
562 : 0 : skb_put(msdu, sizeof(struct htt_rx_desc));
563 : 0 : skb_pull(msdu, sizeof(struct htt_rx_desc));
564 : 0 : skb_put(msdu, min(amsdu_len, HTT_RX_MSDU_SIZE));
565 : 0 : amsdu_len -= msdu->len;
566 : :
567 : 0 : last_frag = ind_desc->reserved;
568 [ # # ]: 0 : if (last_frag) {
569 [ # # ]: 0 : if (amsdu_len) {
570 : 0 : ath10k_warn(ar, "invalid amsdu len %u, left %d",
571 : 0 : __le16_to_cpu(ind_desc->msdu_len),
572 : : amsdu_len);
573 : : }
574 : 0 : return 0;
575 : : }
576 : :
577 : 0 : ind_desc++;
578 : 0 : paddr = __le64_to_cpu(ind_desc->msdu_paddr);
579 : 0 : frag_buf = ath10k_htt_rx_pop_paddr(htt, paddr);
580 [ # # ]: 0 : if (!frag_buf) {
581 : 0 : ath10k_warn(ar, "failed to pop frag-1 paddr: 0x%llx", paddr);
582 : 0 : return -ENOENT;
583 : : }
584 : :
585 : 0 : skb_put(frag_buf, min(amsdu_len, HTT_RX_BUF_SIZE));
586 : 0 : ath10k_htt_append_frag_list(msdu, frag_buf, amsdu_len);
587 : :
588 : 0 : amsdu_len -= frag_buf->len;
589 : 0 : prev_frag_buf = frag_buf;
590 : 0 : last_frag = ind_desc->reserved;
591 [ # # ]: 0 : while (!last_frag) {
592 : 0 : ind_desc++;
593 : 0 : paddr = __le64_to_cpu(ind_desc->msdu_paddr);
594 : 0 : frag_buf = ath10k_htt_rx_pop_paddr(htt, paddr);
595 [ # # ]: 0 : if (!frag_buf) {
596 : 0 : ath10k_warn(ar, "failed to pop frag-n paddr: 0x%llx",
597 : : paddr);
598 : 0 : prev_frag_buf->next = NULL;
599 : 0 : return -ENOENT;
600 : : }
601 : :
602 : 0 : skb_put(frag_buf, min(amsdu_len, HTT_RX_BUF_SIZE));
603 : 0 : last_frag = ind_desc->reserved;
604 : 0 : amsdu_len -= frag_buf->len;
605 : :
606 : 0 : prev_frag_buf->next = frag_buf;
607 : 0 : prev_frag_buf = frag_buf;
608 : : }
609 : :
610 [ # # ]: 0 : if (amsdu_len) {
611 : 0 : ath10k_warn(ar, "invalid amsdu len %u, left %d",
612 : 0 : __le16_to_cpu(ind_desc->msdu_len), amsdu_len);
613 : : }
614 : :
615 : 0 : *msdu_desc = ind_desc;
616 : :
617 : 0 : prev_frag_buf->next = NULL;
618 : 0 : return 0;
619 : : }
620 : :
621 : 0 : static int ath10k_htt_rx_pop_paddr32_list(struct ath10k_htt *htt,
622 : : struct htt_rx_in_ord_ind *ev,
623 : : struct sk_buff_head *list)
624 : : {
625 : 0 : struct ath10k *ar = htt->ar;
626 : 0 : struct htt_rx_in_ord_msdu_desc *msdu_desc = ev->msdu_descs32;
627 : 0 : struct htt_rx_desc *rxd;
628 : 0 : struct sk_buff *msdu;
629 : 0 : int msdu_count, ret;
630 : 0 : bool is_offload;
631 : 0 : u32 paddr;
632 : :
633 : 0 : lockdep_assert_held(&htt->rx_ring.lock);
634 : :
635 : 0 : msdu_count = __le16_to_cpu(ev->msdu_count);
636 : 0 : is_offload = !!(ev->info & HTT_RX_IN_ORD_IND_INFO_OFFLOAD_MASK);
637 : :
638 [ # # ]: 0 : while (msdu_count--) {
639 : 0 : paddr = __le32_to_cpu(msdu_desc->msdu_paddr);
640 : :
641 : 0 : msdu = ath10k_htt_rx_pop_paddr(htt, paddr);
642 [ # # ]: 0 : if (!msdu) {
643 : 0 : __skb_queue_purge(list);
644 : 0 : return -ENOENT;
645 : : }
646 : :
647 [ # # # # ]: 0 : if (!is_offload && ar->monitor_arvif) {
648 : 0 : ret = ath10k_htt_rx_handle_amsdu_mon_32(htt, msdu,
649 : : &msdu_desc);
650 [ # # ]: 0 : if (ret) {
651 : 0 : __skb_queue_purge(list);
652 : 0 : return ret;
653 : : }
654 : 0 : __skb_queue_tail(list, msdu);
655 : 0 : msdu_desc++;
656 : 0 : continue;
657 : : }
658 : :
659 [ # # ]: 0 : __skb_queue_tail(list, msdu);
660 : :
661 [ # # ]: 0 : if (!is_offload) {
662 : 0 : rxd = (void *)msdu->data;
663 : :
664 : 0 : trace_ath10k_htt_rx_desc(ar, rxd, sizeof(*rxd));
665 : :
666 : 0 : skb_put(msdu, sizeof(*rxd));
667 : 0 : skb_pull(msdu, sizeof(*rxd));
668 : 0 : skb_put(msdu, __le16_to_cpu(msdu_desc->msdu_len));
669 : :
670 [ # # ]: 0 : if (!(__le32_to_cpu(rxd->attention.flags) &
671 : : RX_ATTENTION_FLAGS_MSDU_DONE)) {
672 : 0 : ath10k_warn(htt->ar, "tried to pop an incomplete frame, oops!\n");
673 : 0 : return -EIO;
674 : : }
675 : : }
676 : :
677 : 0 : msdu_desc++;
678 : : }
679 : :
680 : : return 0;
681 : : }
682 : :
683 : 0 : static int ath10k_htt_rx_pop_paddr64_list(struct ath10k_htt *htt,
684 : : struct htt_rx_in_ord_ind *ev,
685 : : struct sk_buff_head *list)
686 : : {
687 : 0 : struct ath10k *ar = htt->ar;
688 : 0 : struct htt_rx_in_ord_msdu_desc_ext *msdu_desc = ev->msdu_descs64;
689 : 0 : struct htt_rx_desc *rxd;
690 : 0 : struct sk_buff *msdu;
691 : 0 : int msdu_count, ret;
692 : 0 : bool is_offload;
693 : 0 : u64 paddr;
694 : :
695 : 0 : lockdep_assert_held(&htt->rx_ring.lock);
696 : :
697 : 0 : msdu_count = __le16_to_cpu(ev->msdu_count);
698 : 0 : is_offload = !!(ev->info & HTT_RX_IN_ORD_IND_INFO_OFFLOAD_MASK);
699 : :
700 [ # # ]: 0 : while (msdu_count--) {
701 : 0 : paddr = __le64_to_cpu(msdu_desc->msdu_paddr);
702 : 0 : msdu = ath10k_htt_rx_pop_paddr(htt, paddr);
703 [ # # ]: 0 : if (!msdu) {
704 : 0 : __skb_queue_purge(list);
705 : 0 : return -ENOENT;
706 : : }
707 : :
708 [ # # # # ]: 0 : if (!is_offload && ar->monitor_arvif) {
709 : 0 : ret = ath10k_htt_rx_handle_amsdu_mon_64(htt, msdu,
710 : : &msdu_desc);
711 [ # # ]: 0 : if (ret) {
712 : 0 : __skb_queue_purge(list);
713 : 0 : return ret;
714 : : }
715 : 0 : __skb_queue_tail(list, msdu);
716 : 0 : msdu_desc++;
717 : 0 : continue;
718 : : }
719 : :
720 [ # # ]: 0 : __skb_queue_tail(list, msdu);
721 : :
722 [ # # ]: 0 : if (!is_offload) {
723 : 0 : rxd = (void *)msdu->data;
724 : :
725 : 0 : trace_ath10k_htt_rx_desc(ar, rxd, sizeof(*rxd));
726 : :
727 : 0 : skb_put(msdu, sizeof(*rxd));
728 : 0 : skb_pull(msdu, sizeof(*rxd));
729 : 0 : skb_put(msdu, __le16_to_cpu(msdu_desc->msdu_len));
730 : :
731 [ # # ]: 0 : if (!(__le32_to_cpu(rxd->attention.flags) &
732 : : RX_ATTENTION_FLAGS_MSDU_DONE)) {
733 : 0 : ath10k_warn(htt->ar, "tried to pop an incomplete frame, oops!\n");
734 : 0 : return -EIO;
735 : : }
736 : : }
737 : :
738 : 0 : msdu_desc++;
739 : : }
740 : :
741 : : return 0;
742 : : }
743 : :
744 : 0 : int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
745 : : {
746 : 0 : struct ath10k *ar = htt->ar;
747 : 0 : dma_addr_t paddr;
748 : 0 : void *vaddr, *vaddr_ring;
749 : 0 : size_t size;
750 : 0 : struct timer_list *timer = &htt->rx_ring.refill_retry_timer;
751 : :
752 [ # # ]: 0 : if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
753 : : return 0;
754 : :
755 : 0 : htt->rx_confused = false;
756 : :
757 : : /* XXX: The fill level could be changed during runtime in response to
758 : : * the host processing latency. Is this really worth it?
759 : : */
760 : 0 : htt->rx_ring.size = HTT_RX_RING_SIZE;
761 : 0 : htt->rx_ring.size_mask = htt->rx_ring.size - 1;
762 : 0 : htt->rx_ring.fill_level = ar->hw_params.rx_ring_fill_level;
763 : :
764 : 0 : if (!is_power_of_2(htt->rx_ring.size)) {
765 : : ath10k_warn(ar, "htt rx ring size is not power of 2\n");
766 : : return -EINVAL;
767 : : }
768 : :
769 : 0 : htt->rx_ring.netbufs_ring =
770 : : kcalloc(htt->rx_ring.size, sizeof(struct sk_buff *),
771 : : GFP_KERNEL);
772 [ # # ]: 0 : if (!htt->rx_ring.netbufs_ring)
773 : 0 : goto err_netbuf;
774 : :
775 [ # # ]: 0 : size = ath10k_htt_get_rx_ring_size(htt);
776 : :
777 : 0 : vaddr_ring = dma_alloc_coherent(htt->ar->dev, size, &paddr, GFP_KERNEL);
778 [ # # ]: 0 : if (!vaddr_ring)
779 : 0 : goto err_dma_ring;
780 : :
781 [ # # ]: 0 : ath10k_htt_config_paddrs_ring(htt, vaddr_ring);
782 : 0 : htt->rx_ring.base_paddr = paddr;
783 : :
784 : 0 : vaddr = dma_alloc_coherent(htt->ar->dev,
785 : : sizeof(*htt->rx_ring.alloc_idx.vaddr),
786 : : &paddr, GFP_KERNEL);
787 [ # # ]: 0 : if (!vaddr)
788 : 0 : goto err_dma_idx;
789 : :
790 : 0 : htt->rx_ring.alloc_idx.vaddr = vaddr;
791 : 0 : htt->rx_ring.alloc_idx.paddr = paddr;
792 : 0 : htt->rx_ring.sw_rd_idx.msdu_payld = htt->rx_ring.size_mask;
793 : 0 : *htt->rx_ring.alloc_idx.vaddr = 0;
794 : :
795 : : /* Initialize the Rx refill retry timer */
796 : 0 : timer_setup(timer, ath10k_htt_rx_ring_refill_retry, 0);
797 : :
798 : 0 : spin_lock_init(&htt->rx_ring.lock);
799 : :
800 : 0 : htt->rx_ring.fill_cnt = 0;
801 : 0 : htt->rx_ring.sw_rd_idx.msdu_payld = 0;
802 : 0 : hash_init(htt->rx_ring.skb_table);
803 : :
804 : 0 : skb_queue_head_init(&htt->rx_msdus_q);
805 : 0 : skb_queue_head_init(&htt->rx_in_ord_compl_q);
806 : 0 : skb_queue_head_init(&htt->tx_fetch_ind_q);
807 : 0 : atomic_set(&htt->num_mpdus_ready, 0);
808 : :
809 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt rx ring size %d fill_level %d\n",
810 : : htt->rx_ring.size, htt->rx_ring.fill_level);
811 : : return 0;
812 : :
813 : : err_dma_idx:
814 [ # # ]: 0 : dma_free_coherent(htt->ar->dev,
815 : : ath10k_htt_get_rx_ring_size(htt),
816 : : vaddr_ring,
817 : : htt->rx_ring.base_paddr);
818 : 0 : err_dma_ring:
819 : 0 : kfree(htt->rx_ring.netbufs_ring);
820 : : err_netbuf:
821 : : return -ENOMEM;
822 : : }
823 : :
824 : 0 : static int ath10k_htt_rx_crypto_param_len(struct ath10k *ar,
825 : : enum htt_rx_mpdu_encrypt_type type)
826 : : {
827 [ # # # # : 0 : switch (type) {
# # # ]
828 : : case HTT_RX_MPDU_ENCRYPT_NONE:
829 : : return 0;
830 : 0 : case HTT_RX_MPDU_ENCRYPT_WEP40:
831 : : case HTT_RX_MPDU_ENCRYPT_WEP104:
832 : 0 : return IEEE80211_WEP_IV_LEN;
833 : 0 : case HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC:
834 : : case HTT_RX_MPDU_ENCRYPT_TKIP_WPA:
835 : 0 : return IEEE80211_TKIP_IV_LEN;
836 : 0 : case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2:
837 : 0 : return IEEE80211_CCMP_HDR_LEN;
838 : 0 : case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2:
839 : 0 : return IEEE80211_CCMP_256_HDR_LEN;
840 : 0 : case HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2:
841 : : case HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2:
842 : 0 : return IEEE80211_GCMP_HDR_LEN;
843 : : case HTT_RX_MPDU_ENCRYPT_WEP128:
844 : : case HTT_RX_MPDU_ENCRYPT_WAPI:
845 : : break;
846 : : }
847 : :
848 : 0 : ath10k_warn(ar, "unsupported encryption type %d\n", type);
849 : 0 : return 0;
850 : : }
851 : :
852 : : #define MICHAEL_MIC_LEN 8
853 : :
854 : 0 : static int ath10k_htt_rx_crypto_mic_len(struct ath10k *ar,
855 : : enum htt_rx_mpdu_encrypt_type type)
856 : : {
857 [ # # # # : 0 : switch (type) {
# ]
858 : : case HTT_RX_MPDU_ENCRYPT_NONE:
859 : : case HTT_RX_MPDU_ENCRYPT_WEP40:
860 : : case HTT_RX_MPDU_ENCRYPT_WEP104:
861 : : case HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC:
862 : : case HTT_RX_MPDU_ENCRYPT_TKIP_WPA:
863 : : return 0;
864 : 0 : case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2:
865 : 0 : return IEEE80211_CCMP_MIC_LEN;
866 : 0 : case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2:
867 : 0 : return IEEE80211_CCMP_256_MIC_LEN;
868 : 0 : case HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2:
869 : : case HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2:
870 : 0 : return IEEE80211_GCMP_MIC_LEN;
871 : : case HTT_RX_MPDU_ENCRYPT_WEP128:
872 : : case HTT_RX_MPDU_ENCRYPT_WAPI:
873 : : break;
874 : : }
875 : :
876 : 0 : ath10k_warn(ar, "unsupported encryption type %d\n", type);
877 : 0 : return 0;
878 : : }
879 : :
880 : 0 : static int ath10k_htt_rx_crypto_icv_len(struct ath10k *ar,
881 : : enum htt_rx_mpdu_encrypt_type type)
882 : : {
883 [ # # # # ]: 0 : switch (type) {
884 : : case HTT_RX_MPDU_ENCRYPT_NONE:
885 : : case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2:
886 : : case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2:
887 : : case HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2:
888 : : case HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2:
889 : : return 0;
890 : 0 : case HTT_RX_MPDU_ENCRYPT_WEP40:
891 : : case HTT_RX_MPDU_ENCRYPT_WEP104:
892 : 0 : return IEEE80211_WEP_ICV_LEN;
893 : 0 : case HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC:
894 : : case HTT_RX_MPDU_ENCRYPT_TKIP_WPA:
895 : 0 : return IEEE80211_TKIP_ICV_LEN;
896 : : case HTT_RX_MPDU_ENCRYPT_WEP128:
897 : : case HTT_RX_MPDU_ENCRYPT_WAPI:
898 : : break;
899 : : }
900 : :
901 : 0 : ath10k_warn(ar, "unsupported encryption type %d\n", type);
902 : 0 : return 0;
903 : : }
904 : :
905 : : struct amsdu_subframe_hdr {
906 : : u8 dst[ETH_ALEN];
907 : : u8 src[ETH_ALEN];
908 : : __be16 len;
909 : : } __packed;
910 : :
911 : : #define GROUP_ID_IS_SU_MIMO(x) ((x) == 0 || (x) == 63)
912 : :
913 : 0 : static inline u8 ath10k_bw_to_mac80211_bw(u8 bw)
914 : : {
915 : 0 : u8 ret = 0;
916 : :
917 : 0 : switch (bw) {
918 : : case 0:
919 : : ret = RATE_INFO_BW_20;
920 : : break;
921 : : case 1:
922 : : ret = RATE_INFO_BW_40;
923 : : break;
924 : : case 2:
925 : : ret = RATE_INFO_BW_80;
926 : : break;
927 : : case 3:
928 : : ret = RATE_INFO_BW_160;
929 : : break;
930 : : }
931 : :
932 : 0 : return ret;
933 : : }
934 : :
935 : 0 : static void ath10k_htt_rx_h_rates(struct ath10k *ar,
936 : : struct ieee80211_rx_status *status,
937 : : struct htt_rx_desc *rxd)
938 : : {
939 : 0 : struct ieee80211_supported_band *sband;
940 : 0 : u8 cck, rate, bw, sgi, mcs, nss;
941 : 0 : u8 preamble = 0;
942 : 0 : u8 group_id;
943 : 0 : u32 info1, info2, info3;
944 : :
945 : 0 : info1 = __le32_to_cpu(rxd->ppdu_start.info1);
946 : 0 : info2 = __le32_to_cpu(rxd->ppdu_start.info2);
947 : 0 : info3 = __le32_to_cpu(rxd->ppdu_start.info3);
948 : :
949 : 0 : preamble = MS(info1, RX_PPDU_START_INFO1_PREAMBLE_TYPE);
950 : :
951 [ # # # # ]: 0 : switch (preamble) {
952 : 0 : case HTT_RX_LEGACY:
953 : : /* To get legacy rate index band is required. Since band can't
954 : : * be undefined check if freq is non-zero.
955 : : */
956 [ # # ]: 0 : if (!status->freq)
957 : : return;
958 : :
959 : 0 : cck = info1 & RX_PPDU_START_INFO1_L_SIG_RATE_SELECT;
960 : 0 : rate = MS(info1, RX_PPDU_START_INFO1_L_SIG_RATE);
961 : 0 : rate &= ~RX_PPDU_START_RATE_FLAG;
962 : :
963 : 0 : sband = &ar->mac.sbands[status->band];
964 : 0 : status->rate_idx = ath10k_mac_hw_rate_to_idx(sband, rate, cck);
965 : 0 : break;
966 : 0 : case HTT_RX_HT:
967 : : case HTT_RX_HT_WITH_TXBF:
968 : : /* HT-SIG - Table 20-11 in info2 and info3 */
969 : 0 : mcs = info2 & 0x1F;
970 : 0 : nss = mcs >> 3;
971 : 0 : bw = (info2 >> 7) & 1;
972 : 0 : sgi = (info3 >> 7) & 1;
973 : :
974 : 0 : status->rate_idx = mcs;
975 : 0 : status->encoding = RX_ENC_HT;
976 [ # # ]: 0 : if (sgi)
977 : 0 : status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
978 [ # # ]: 0 : if (bw)
979 : 0 : status->bw = RATE_INFO_BW_40;
980 : : break;
981 : 0 : case HTT_RX_VHT:
982 : : case HTT_RX_VHT_WITH_TXBF:
983 : : /* VHT-SIG-A1 in info2, VHT-SIG-A2 in info3
984 : : * TODO check this
985 : : */
986 : 0 : bw = info2 & 3;
987 : 0 : sgi = info3 & 1;
988 : 0 : group_id = (info2 >> 4) & 0x3F;
989 : :
990 [ # # # # ]: 0 : if (GROUP_ID_IS_SU_MIMO(group_id)) {
991 : 0 : mcs = (info3 >> 4) & 0x0F;
992 : 0 : nss = ((info2 >> 10) & 0x07) + 1;
993 : : } else {
994 : : /* Hardware doesn't decode VHT-SIG-B into Rx descriptor
995 : : * so it's impossible to decode MCS. Also since
996 : : * firmware consumes Group Id Management frames host
997 : : * has no knowledge regarding group/user position
998 : : * mapping so it's impossible to pick the correct Nsts
999 : : * from VHT-SIG-A1.
1000 : : *
1001 : : * Bandwidth and SGI are valid so report the rateinfo
1002 : : * on best-effort basis.
1003 : : */
1004 : : mcs = 0;
1005 : : nss = 1;
1006 : : }
1007 : :
1008 [ # # ]: 0 : if (mcs > 0x09) {
1009 : 0 : ath10k_warn(ar, "invalid MCS received %u\n", mcs);
1010 : 0 : ath10k_warn(ar, "rxd %08x mpdu start %08x %08x msdu start %08x %08x ppdu start %08x %08x %08x %08x %08x\n",
1011 : 0 : __le32_to_cpu(rxd->attention.flags),
1012 : 0 : __le32_to_cpu(rxd->mpdu_start.info0),
1013 : 0 : __le32_to_cpu(rxd->mpdu_start.info1),
1014 : 0 : __le32_to_cpu(rxd->msdu_start.common.info0),
1015 : 0 : __le32_to_cpu(rxd->msdu_start.common.info1),
1016 : 0 : rxd->ppdu_start.info0,
1017 : 0 : __le32_to_cpu(rxd->ppdu_start.info1),
1018 : 0 : __le32_to_cpu(rxd->ppdu_start.info2),
1019 : 0 : __le32_to_cpu(rxd->ppdu_start.info3),
1020 : 0 : __le32_to_cpu(rxd->ppdu_start.info4));
1021 : :
1022 : 0 : ath10k_warn(ar, "msdu end %08x mpdu end %08x\n",
1023 : 0 : __le32_to_cpu(rxd->msdu_end.common.info0),
1024 : 0 : __le32_to_cpu(rxd->mpdu_end.info0));
1025 : :
1026 : 0 : ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL,
1027 : : "rx desc msdu payload: ",
1028 : 0 : rxd->msdu_payload, 50);
1029 : : }
1030 : :
1031 : 0 : status->rate_idx = mcs;
1032 : 0 : status->nss = nss;
1033 : :
1034 [ # # ]: 0 : if (sgi)
1035 : 0 : status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
1036 : :
1037 [ # # ]: 0 : status->bw = ath10k_bw_to_mac80211_bw(bw);
1038 : 0 : status->encoding = RX_ENC_VHT;
1039 : 0 : break;
1040 : : default:
1041 : : break;
1042 : : }
1043 : : }
1044 : :
1045 : : static struct ieee80211_channel *
1046 : 0 : ath10k_htt_rx_h_peer_channel(struct ath10k *ar, struct htt_rx_desc *rxd)
1047 : : {
1048 : 0 : struct ath10k_peer *peer;
1049 : 0 : struct ath10k_vif *arvif;
1050 : 0 : struct cfg80211_chan_def def;
1051 : 0 : u16 peer_id;
1052 : :
1053 : 0 : lockdep_assert_held(&ar->data_lock);
1054 : :
1055 [ # # ]: 0 : if (!rxd)
1056 : : return NULL;
1057 : :
1058 [ # # ]: 0 : if (rxd->attention.flags &
1059 : : __cpu_to_le32(RX_ATTENTION_FLAGS_PEER_IDX_INVALID))
1060 : : return NULL;
1061 : :
1062 [ # # ]: 0 : if (!(rxd->msdu_end.common.info0 &
1063 : : __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU)))
1064 : : return NULL;
1065 : :
1066 : 0 : peer_id = MS(__le32_to_cpu(rxd->mpdu_start.info0),
1067 : : RX_MPDU_START_INFO0_PEER_IDX);
1068 : :
1069 : 0 : peer = ath10k_peer_find_by_id(ar, peer_id);
1070 [ # # ]: 0 : if (!peer)
1071 : : return NULL;
1072 : :
1073 : 0 : arvif = ath10k_get_arvif(ar, peer->vdev_id);
1074 [ # # # # ]: 0 : if (WARN_ON_ONCE(!arvif))
1075 : : return NULL;
1076 : :
1077 [ # # ]: 0 : if (ath10k_mac_vif_chan(arvif->vif, &def))
1078 : : return NULL;
1079 : :
1080 : 0 : return def.chan;
1081 : : }
1082 : :
1083 : : static struct ieee80211_channel *
1084 : 0 : ath10k_htt_rx_h_vdev_channel(struct ath10k *ar, u32 vdev_id)
1085 : : {
1086 : 0 : struct ath10k_vif *arvif;
1087 : 0 : struct cfg80211_chan_def def;
1088 : :
1089 : 0 : lockdep_assert_held(&ar->data_lock);
1090 : :
1091 [ # # ]: 0 : list_for_each_entry(arvif, &ar->arvifs, list) {
1092 [ # # # # ]: 0 : if (arvif->vdev_id == vdev_id &&
1093 : 0 : ath10k_mac_vif_chan(arvif->vif, &def) == 0)
1094 : 0 : return def.chan;
1095 : : }
1096 : :
1097 : : return NULL;
1098 : : }
1099 : :
1100 : : static void
1101 : 0 : ath10k_htt_rx_h_any_chan_iter(struct ieee80211_hw *hw,
1102 : : struct ieee80211_chanctx_conf *conf,
1103 : : void *data)
1104 : : {
1105 : 0 : struct cfg80211_chan_def *def = data;
1106 : :
1107 : 0 : *def = conf->def;
1108 : 0 : }
1109 : :
1110 : : static struct ieee80211_channel *
1111 : : ath10k_htt_rx_h_any_channel(struct ath10k *ar)
1112 : : {
1113 : : struct cfg80211_chan_def def = {};
1114 : :
1115 : : ieee80211_iter_chan_contexts_atomic(ar->hw,
1116 : : ath10k_htt_rx_h_any_chan_iter,
1117 : : &def);
1118 : :
1119 : : return def.chan;
1120 : : }
1121 : :
1122 : : static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
1123 : : struct ieee80211_rx_status *status,
1124 : : struct htt_rx_desc *rxd,
1125 : : u32 vdev_id)
1126 : : {
1127 : : struct ieee80211_channel *ch;
1128 : :
1129 : : spin_lock_bh(&ar->data_lock);
1130 : : ch = ar->scan_channel;
1131 : : if (!ch)
1132 : : ch = ar->rx_channel;
1133 : : if (!ch)
1134 : : ch = ath10k_htt_rx_h_peer_channel(ar, rxd);
1135 : : if (!ch)
1136 : : ch = ath10k_htt_rx_h_vdev_channel(ar, vdev_id);
1137 : : if (!ch)
1138 : : ch = ath10k_htt_rx_h_any_channel(ar);
1139 : : if (!ch)
1140 : : ch = ar->tgt_oper_chan;
1141 : : spin_unlock_bh(&ar->data_lock);
1142 : :
1143 : : if (!ch)
1144 : : return false;
1145 : :
1146 : : status->band = ch->band;
1147 : : status->freq = ch->center_freq;
1148 : :
1149 : : return true;
1150 : : }
1151 : :
1152 : 0 : static void ath10k_htt_rx_h_signal(struct ath10k *ar,
1153 : : struct ieee80211_rx_status *status,
1154 : : struct htt_rx_desc *rxd)
1155 : : {
1156 : : int i;
1157 : :
1158 [ # # ]: 0 : for (i = 0; i < IEEE80211_MAX_CHAINS ; i++) {
1159 : 0 : status->chains &= ~BIT(i);
1160 : :
1161 [ # # ]: 0 : if (rxd->ppdu_start.rssi_chains[i].pri20_mhz != 0x80) {
1162 : 0 : status->chain_signal[i] = ATH10K_DEFAULT_NOISE_FLOOR +
1163 : 0 : rxd->ppdu_start.rssi_chains[i].pri20_mhz;
1164 : :
1165 : 0 : status->chains |= BIT(i);
1166 : : }
1167 : : }
1168 : :
1169 : : /* FIXME: Get real NF */
1170 : 0 : status->signal = ATH10K_DEFAULT_NOISE_FLOOR +
1171 : 0 : rxd->ppdu_start.rssi_comb;
1172 : 0 : status->flag &= ~RX_FLAG_NO_SIGNAL_VAL;
1173 : : }
1174 : :
1175 : 0 : static void ath10k_htt_rx_h_mactime(struct ath10k *ar,
1176 : : struct ieee80211_rx_status *status,
1177 : : struct htt_rx_desc *rxd)
1178 : : {
1179 : : /* FIXME: TSF is known only at the end of PPDU, in the last MPDU. This
1180 : : * means all prior MSDUs in a PPDU are reported to mac80211 without the
1181 : : * TSF. Is it worth holding frames until end of PPDU is known?
1182 : : *
1183 : : * FIXME: Can we get/compute 64bit TSF?
1184 : : */
1185 : 0 : status->mactime = __le32_to_cpu(rxd->ppdu_end.common.tsf_timestamp);
1186 : 0 : status->flag |= RX_FLAG_MACTIME_END;
1187 : : }
1188 : :
1189 : 0 : static void ath10k_htt_rx_h_ppdu(struct ath10k *ar,
1190 : : struct sk_buff_head *amsdu,
1191 : : struct ieee80211_rx_status *status,
1192 : : u32 vdev_id)
1193 : : {
1194 : 0 : struct sk_buff *first;
1195 : 0 : struct htt_rx_desc *rxd;
1196 : 0 : bool is_first_ppdu;
1197 : 0 : bool is_last_ppdu;
1198 : :
1199 [ # # ]: 0 : if (skb_queue_empty(amsdu))
1200 : : return;
1201 : :
1202 [ # # ]: 0 : first = skb_peek(amsdu);
1203 : 0 : rxd = (void *)first->data - sizeof(*rxd);
1204 : :
1205 : 0 : is_first_ppdu = !!(rxd->attention.flags &
1206 : : __cpu_to_le32(RX_ATTENTION_FLAGS_FIRST_MPDU));
1207 : 0 : is_last_ppdu = !!(rxd->attention.flags &
1208 : : __cpu_to_le32(RX_ATTENTION_FLAGS_LAST_MPDU));
1209 : :
1210 [ # # ]: 0 : if (is_first_ppdu) {
1211 : : /* New PPDU starts so clear out the old per-PPDU status. */
1212 : 0 : status->freq = 0;
1213 : 0 : status->rate_idx = 0;
1214 : 0 : status->nss = 0;
1215 : 0 : status->encoding = RX_ENC_LEGACY;
1216 : 0 : status->bw = RATE_INFO_BW_20;
1217 : :
1218 : 0 : status->flag &= ~RX_FLAG_MACTIME_END;
1219 : 0 : status->flag |= RX_FLAG_NO_SIGNAL_VAL;
1220 : :
1221 : 0 : status->flag &= ~(RX_FLAG_AMPDU_IS_LAST);
1222 : 0 : status->flag |= RX_FLAG_AMPDU_DETAILS | RX_FLAG_AMPDU_LAST_KNOWN;
1223 : 0 : status->ampdu_reference = ar->ampdu_reference;
1224 : :
1225 : 0 : ath10k_htt_rx_h_signal(ar, status, rxd);
1226 : 0 : ath10k_htt_rx_h_channel(ar, status, rxd, vdev_id);
1227 : 0 : ath10k_htt_rx_h_rates(ar, status, rxd);
1228 : : }
1229 : :
1230 [ # # ]: 0 : if (is_last_ppdu) {
1231 : 0 : ath10k_htt_rx_h_mactime(ar, status, rxd);
1232 : :
1233 : : /* set ampdu last segment flag */
1234 : 0 : status->flag |= RX_FLAG_AMPDU_IS_LAST;
1235 : 0 : ar->ampdu_reference++;
1236 : : }
1237 : : }
1238 : :
1239 : : static const char * const tid_to_ac[] = {
1240 : : "BE",
1241 : : "BK",
1242 : : "BK",
1243 : : "BE",
1244 : : "VI",
1245 : : "VI",
1246 : : "VO",
1247 : : "VO",
1248 : : };
1249 : :
1250 : 0 : static char *ath10k_get_tid(struct ieee80211_hdr *hdr, char *out, size_t size)
1251 : : {
1252 : 0 : u8 *qc;
1253 : 0 : int tid;
1254 : :
1255 [ # # ]: 0 : if (!ieee80211_is_data_qos(hdr->frame_control))
1256 : : return "";
1257 : :
1258 [ # # ]: 0 : qc = ieee80211_get_qos_ctl(hdr);
1259 : 0 : tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
1260 [ # # ]: 0 : if (tid < 8)
1261 : 0 : snprintf(out, size, "tid %d (%s)", tid, tid_to_ac[tid]);
1262 : : else
1263 : 0 : snprintf(out, size, "tid %d", tid);
1264 : :
1265 : : return out;
1266 : : }
1267 : :
1268 : 0 : static void ath10k_htt_rx_h_queue_msdu(struct ath10k *ar,
1269 : : struct ieee80211_rx_status *rx_status,
1270 : : struct sk_buff *skb)
1271 : : {
1272 : 0 : struct ieee80211_rx_status *status;
1273 : :
1274 : 0 : status = IEEE80211_SKB_RXCB(skb);
1275 : 0 : *status = *rx_status;
1276 : :
1277 : 0 : skb_queue_tail(&ar->htt.rx_msdus_q, skb);
1278 : 0 : }
1279 : :
1280 : 0 : static void ath10k_process_rx(struct ath10k *ar, struct sk_buff *skb)
1281 : : {
1282 : 0 : struct ieee80211_rx_status *status;
1283 : 0 : struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1284 : 0 : char tid[32];
1285 : :
1286 [ # # ]: 0 : status = IEEE80211_SKB_RXCB(skb);
1287 : :
1288 [ # # ]: 0 : if (!(ar->filter_flags & FIF_FCSFAIL) &&
1289 [ # # ]: 0 : status->flag & RX_FLAG_FAILED_FCS_CRC) {
1290 : 0 : ar->stats.rx_crc_err_drop++;
1291 : 0 : dev_kfree_skb_any(skb);
1292 : 0 : return;
1293 : : }
1294 : :
1295 [ # # # # : 0 : ath10k_dbg(ar, ATH10K_DBG_DATA,
# # # # #
# # # # #
# # # # #
# ]
1296 : : "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
1297 : : skb,
1298 : : skb->len,
1299 : : ieee80211_get_SA(hdr),
1300 : : ath10k_get_tid(hdr, tid, sizeof(tid)),
1301 : : is_multicast_ether_addr(ieee80211_get_DA(hdr)) ?
1302 : : "mcast" : "ucast",
1303 : : (__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4,
1304 : : (status->encoding == RX_ENC_LEGACY) ? "legacy" : "",
1305 : : (status->encoding == RX_ENC_HT) ? "ht" : "",
1306 : : (status->encoding == RX_ENC_VHT) ? "vht" : "",
1307 : : (status->bw == RATE_INFO_BW_40) ? "40" : "",
1308 : : (status->bw == RATE_INFO_BW_80) ? "80" : "",
1309 : : (status->bw == RATE_INFO_BW_160) ? "160" : "",
1310 : : status->enc_flags & RX_ENC_FLAG_SHORT_GI ? "sgi " : "",
1311 : : status->rate_idx,
1312 : : status->nss,
1313 : : status->freq,
1314 : : status->band, status->flag,
1315 : : !!(status->flag & RX_FLAG_FAILED_FCS_CRC),
1316 : : !!(status->flag & RX_FLAG_MMIC_ERROR),
1317 : : !!(status->flag & RX_FLAG_AMSDU_MORE));
1318 : 0 : ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
1319 : 0 : skb->data, skb->len);
1320 : 0 : trace_ath10k_rx_hdr(ar, skb->data, skb->len);
1321 : 0 : trace_ath10k_rx_payload(ar, skb->data, skb->len);
1322 : :
1323 : 0 : ieee80211_rx_napi(ar->hw, NULL, skb, &ar->napi);
1324 : : }
1325 : :
1326 : : static int ath10k_htt_rx_nwifi_hdrlen(struct ath10k *ar,
1327 : : struct ieee80211_hdr *hdr)
1328 : : {
1329 : : int len = ieee80211_hdrlen(hdr->frame_control);
1330 : :
1331 : : if (!test_bit(ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING,
1332 : : ar->running_fw->fw_file.fw_features))
1333 : : len = round_up(len, 4);
1334 : :
1335 : : return len;
1336 : : }
1337 : :
1338 : 0 : static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,
1339 : : struct sk_buff *msdu,
1340 : : struct ieee80211_rx_status *status,
1341 : : enum htt_rx_mpdu_encrypt_type enctype,
1342 : : bool is_decrypted,
1343 : : const u8 first_hdr[64])
1344 : : {
1345 : 0 : struct ieee80211_hdr *hdr;
1346 : 0 : struct htt_rx_desc *rxd;
1347 : 0 : size_t hdr_len;
1348 : 0 : size_t crypto_len;
1349 : 0 : bool is_first;
1350 : 0 : bool is_last;
1351 : 0 : bool msdu_limit_err;
1352 : 0 : int bytes_aligned = ar->hw_params.decap_align_bytes;
1353 : 0 : u8 *qos;
1354 : :
1355 : 0 : rxd = (void *)msdu->data - sizeof(*rxd);
1356 : 0 : is_first = !!(rxd->msdu_end.common.info0 &
1357 : : __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU));
1358 : 0 : is_last = !!(rxd->msdu_end.common.info0 &
1359 : : __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU));
1360 : :
1361 : : /* Delivered decapped frame:
1362 : : * [802.11 header]
1363 : : * [crypto param] <-- can be trimmed if !fcs_err &&
1364 : : * !decrypt_err && !peer_idx_invalid
1365 : : * [amsdu header] <-- only if A-MSDU
1366 : : * [rfc1042/llc]
1367 : : * [payload]
1368 : : * [FCS] <-- at end, needs to be trimmed
1369 : : */
1370 : :
1371 : : /* Some hardwares(QCA99x0 variants) limit number of msdus in a-msdu when
1372 : : * deaggregate, so that unwanted MSDU-deaggregation is avoided for
1373 : : * error packets. If limit exceeds, hw sends all remaining MSDUs as
1374 : : * a single last MSDU with this msdu limit error set.
1375 : : */
1376 [ # # ]: 0 : msdu_limit_err = ath10k_rx_desc_msdu_limit_error(&ar->hw_params, rxd);
1377 : :
1378 : : /* If MSDU limit error happens, then don't warn on, the partial raw MSDU
1379 : : * without first MSDU is expected in that case, and handled later here.
1380 : : */
1381 : : /* This probably shouldn't happen but warn just in case */
1382 [ # # # # : 0 : if (WARN_ON_ONCE(!is_first && !msdu_limit_err))
# # # # ]
1383 : : return;
1384 : :
1385 : : /* This probably shouldn't happen but warn just in case */
1386 [ # # # # : 0 : if (WARN_ON_ONCE(!(is_first && is_last) && !msdu_limit_err))
# # # # #
# ]
1387 : : return;
1388 : :
1389 : 0 : skb_trim(msdu, msdu->len - FCS_LEN);
1390 : :
1391 : : /* Push original 80211 header */
1392 [ # # ]: 0 : if (unlikely(msdu_limit_err)) {
1393 : 0 : hdr = (struct ieee80211_hdr *)first_hdr;
1394 : 0 : hdr_len = ieee80211_hdrlen(hdr->frame_control);
1395 : 0 : crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype);
1396 : :
1397 [ # # ]: 0 : if (ieee80211_is_data_qos(hdr->frame_control)) {
1398 [ # # ]: 0 : qos = ieee80211_get_qos_ctl(hdr);
1399 : 0 : qos[0] |= IEEE80211_QOS_CTL_A_MSDU_PRESENT;
1400 : : }
1401 : :
1402 [ # # ]: 0 : if (crypto_len)
1403 : 0 : memcpy(skb_push(msdu, crypto_len),
1404 : 0 : (void *)hdr + round_up(hdr_len, bytes_aligned),
1405 : : crypto_len);
1406 : :
1407 : 0 : memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
1408 : : }
1409 : :
1410 : : /* In most cases this will be true for sniffed frames. It makes sense
1411 : : * to deliver them as-is without stripping the crypto param. This is
1412 : : * necessary for software based decryption.
1413 : : *
1414 : : * If there's no error then the frame is decrypted. At least that is
1415 : : * the case for frames that come in via fragmented rx indication.
1416 : : */
1417 [ # # ]: 0 : if (!is_decrypted)
1418 : : return;
1419 : :
1420 : : /* The payload is decrypted so strip crypto params. Start from tail
1421 : : * since hdr is used to compute some stuff.
1422 : : */
1423 : :
1424 : 0 : hdr = (void *)msdu->data;
1425 : :
1426 : : /* Tail */
1427 [ # # ]: 0 : if (status->flag & RX_FLAG_IV_STRIPPED) {
1428 : 0 : skb_trim(msdu, msdu->len -
1429 : 0 : ath10k_htt_rx_crypto_mic_len(ar, enctype));
1430 : :
1431 : 0 : skb_trim(msdu, msdu->len -
1432 : 0 : ath10k_htt_rx_crypto_icv_len(ar, enctype));
1433 : : } else {
1434 : : /* MIC */
1435 [ # # ]: 0 : if (status->flag & RX_FLAG_MIC_STRIPPED)
1436 : 0 : skb_trim(msdu, msdu->len -
1437 : 0 : ath10k_htt_rx_crypto_mic_len(ar, enctype));
1438 : :
1439 : : /* ICV */
1440 [ # # ]: 0 : if (status->flag & RX_FLAG_ICV_STRIPPED)
1441 : 0 : skb_trim(msdu, msdu->len -
1442 : 0 : ath10k_htt_rx_crypto_icv_len(ar, enctype));
1443 : : }
1444 : :
1445 : : /* MMIC */
1446 [ # # # # ]: 0 : if ((status->flag & RX_FLAG_MMIC_STRIPPED) &&
1447 [ # # # # ]: 0 : !ieee80211_has_morefrags(hdr->frame_control) &&
1448 : : enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
1449 : 0 : skb_trim(msdu, msdu->len - MICHAEL_MIC_LEN);
1450 : :
1451 : : /* Head */
1452 [ # # ]: 0 : if (status->flag & RX_FLAG_IV_STRIPPED) {
1453 : 0 : hdr_len = ieee80211_hdrlen(hdr->frame_control);
1454 : 0 : crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype);
1455 : :
1456 : 0 : memmove((void *)msdu->data + crypto_len,
1457 : 0 : (void *)msdu->data, hdr_len);
1458 : 0 : skb_pull(msdu, crypto_len);
1459 : : }
1460 : : }
1461 : :
1462 : : static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
1463 : : struct sk_buff *msdu,
1464 : : struct ieee80211_rx_status *status,
1465 : : const u8 first_hdr[64],
1466 : : enum htt_rx_mpdu_encrypt_type enctype)
1467 : : {
1468 : : struct ieee80211_hdr *hdr;
1469 : : struct htt_rx_desc *rxd;
1470 : : size_t hdr_len;
1471 : : u8 da[ETH_ALEN];
1472 : : u8 sa[ETH_ALEN];
1473 : : int l3_pad_bytes;
1474 : : int bytes_aligned = ar->hw_params.decap_align_bytes;
1475 : :
1476 : : /* Delivered decapped frame:
1477 : : * [nwifi 802.11 header] <-- replaced with 802.11 hdr
1478 : : * [rfc1042/llc]
1479 : : *
1480 : : * Note: The nwifi header doesn't have QoS Control and is
1481 : : * (always?) a 3addr frame.
1482 : : *
1483 : : * Note2: There's no A-MSDU subframe header. Even if it's part
1484 : : * of an A-MSDU.
1485 : : */
1486 : :
1487 : : /* pull decapped header and copy SA & DA */
1488 : : rxd = (void *)msdu->data - sizeof(*rxd);
1489 : :
1490 : : l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd);
1491 : : skb_put(msdu, l3_pad_bytes);
1492 : :
1493 : : hdr = (struct ieee80211_hdr *)(msdu->data + l3_pad_bytes);
1494 : :
1495 : : hdr_len = ath10k_htt_rx_nwifi_hdrlen(ar, hdr);
1496 : : ether_addr_copy(da, ieee80211_get_DA(hdr));
1497 : : ether_addr_copy(sa, ieee80211_get_SA(hdr));
1498 : : skb_pull(msdu, hdr_len);
1499 : :
1500 : : /* push original 802.11 header */
1501 : : hdr = (struct ieee80211_hdr *)first_hdr;
1502 : : hdr_len = ieee80211_hdrlen(hdr->frame_control);
1503 : :
1504 : : if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
1505 : : memcpy(skb_push(msdu,
1506 : : ath10k_htt_rx_crypto_param_len(ar, enctype)),
1507 : : (void *)hdr + round_up(hdr_len, bytes_aligned),
1508 : : ath10k_htt_rx_crypto_param_len(ar, enctype));
1509 : : }
1510 : :
1511 : : memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
1512 : :
1513 : : /* original 802.11 header has a different DA and in
1514 : : * case of 4addr it may also have different SA
1515 : : */
1516 : : hdr = (struct ieee80211_hdr *)msdu->data;
1517 : : ether_addr_copy(ieee80211_get_DA(hdr), da);
1518 : : ether_addr_copy(ieee80211_get_SA(hdr), sa);
1519 : : }
1520 : :
1521 : : static void *ath10k_htt_rx_h_find_rfc1042(struct ath10k *ar,
1522 : : struct sk_buff *msdu,
1523 : : enum htt_rx_mpdu_encrypt_type enctype)
1524 : : {
1525 : : struct ieee80211_hdr *hdr;
1526 : : struct htt_rx_desc *rxd;
1527 : : size_t hdr_len, crypto_len;
1528 : : void *rfc1042;
1529 : : bool is_first, is_last, is_amsdu;
1530 : : int bytes_aligned = ar->hw_params.decap_align_bytes;
1531 : :
1532 : : rxd = (void *)msdu->data - sizeof(*rxd);
1533 : : hdr = (void *)rxd->rx_hdr_status;
1534 : :
1535 : : is_first = !!(rxd->msdu_end.common.info0 &
1536 : : __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU));
1537 : : is_last = !!(rxd->msdu_end.common.info0 &
1538 : : __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU));
1539 : : is_amsdu = !(is_first && is_last);
1540 : :
1541 : : rfc1042 = hdr;
1542 : :
1543 : : if (is_first) {
1544 : : hdr_len = ieee80211_hdrlen(hdr->frame_control);
1545 : : crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype);
1546 : :
1547 : : rfc1042 += round_up(hdr_len, bytes_aligned) +
1548 : : round_up(crypto_len, bytes_aligned);
1549 : : }
1550 : :
1551 : : if (is_amsdu)
1552 : : rfc1042 += sizeof(struct amsdu_subframe_hdr);
1553 : :
1554 : : return rfc1042;
1555 : : }
1556 : :
1557 : : static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
1558 : : struct sk_buff *msdu,
1559 : : struct ieee80211_rx_status *status,
1560 : : const u8 first_hdr[64],
1561 : : enum htt_rx_mpdu_encrypt_type enctype)
1562 : : {
1563 : : struct ieee80211_hdr *hdr;
1564 : : struct ethhdr *eth;
1565 : : size_t hdr_len;
1566 : : void *rfc1042;
1567 : : u8 da[ETH_ALEN];
1568 : : u8 sa[ETH_ALEN];
1569 : : int l3_pad_bytes;
1570 : : struct htt_rx_desc *rxd;
1571 : : int bytes_aligned = ar->hw_params.decap_align_bytes;
1572 : :
1573 : : /* Delivered decapped frame:
1574 : : * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc
1575 : : * [payload]
1576 : : */
1577 : :
1578 : : rfc1042 = ath10k_htt_rx_h_find_rfc1042(ar, msdu, enctype);
1579 : : if (WARN_ON_ONCE(!rfc1042))
1580 : : return;
1581 : :
1582 : : rxd = (void *)msdu->data - sizeof(*rxd);
1583 : : l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd);
1584 : : skb_put(msdu, l3_pad_bytes);
1585 : : skb_pull(msdu, l3_pad_bytes);
1586 : :
1587 : : /* pull decapped header and copy SA & DA */
1588 : : eth = (struct ethhdr *)msdu->data;
1589 : : ether_addr_copy(da, eth->h_dest);
1590 : : ether_addr_copy(sa, eth->h_source);
1591 : : skb_pull(msdu, sizeof(struct ethhdr));
1592 : :
1593 : : /* push rfc1042/llc/snap */
1594 : : memcpy(skb_push(msdu, sizeof(struct rfc1042_hdr)), rfc1042,
1595 : : sizeof(struct rfc1042_hdr));
1596 : :
1597 : : /* push original 802.11 header */
1598 : : hdr = (struct ieee80211_hdr *)first_hdr;
1599 : : hdr_len = ieee80211_hdrlen(hdr->frame_control);
1600 : :
1601 : : if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
1602 : : memcpy(skb_push(msdu,
1603 : : ath10k_htt_rx_crypto_param_len(ar, enctype)),
1604 : : (void *)hdr + round_up(hdr_len, bytes_aligned),
1605 : : ath10k_htt_rx_crypto_param_len(ar, enctype));
1606 : : }
1607 : :
1608 : : memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
1609 : :
1610 : : /* original 802.11 header has a different DA and in
1611 : : * case of 4addr it may also have different SA
1612 : : */
1613 : : hdr = (struct ieee80211_hdr *)msdu->data;
1614 : : ether_addr_copy(ieee80211_get_DA(hdr), da);
1615 : : ether_addr_copy(ieee80211_get_SA(hdr), sa);
1616 : : }
1617 : :
1618 : : static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
1619 : : struct sk_buff *msdu,
1620 : : struct ieee80211_rx_status *status,
1621 : : const u8 first_hdr[64],
1622 : : enum htt_rx_mpdu_encrypt_type enctype)
1623 : : {
1624 : : struct ieee80211_hdr *hdr;
1625 : : size_t hdr_len;
1626 : : int l3_pad_bytes;
1627 : : struct htt_rx_desc *rxd;
1628 : : int bytes_aligned = ar->hw_params.decap_align_bytes;
1629 : :
1630 : : /* Delivered decapped frame:
1631 : : * [amsdu header] <-- replaced with 802.11 hdr
1632 : : * [rfc1042/llc]
1633 : : * [payload]
1634 : : */
1635 : :
1636 : : rxd = (void *)msdu->data - sizeof(*rxd);
1637 : : l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd);
1638 : :
1639 : : skb_put(msdu, l3_pad_bytes);
1640 : : skb_pull(msdu, sizeof(struct amsdu_subframe_hdr) + l3_pad_bytes);
1641 : :
1642 : : hdr = (struct ieee80211_hdr *)first_hdr;
1643 : : hdr_len = ieee80211_hdrlen(hdr->frame_control);
1644 : :
1645 : : if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
1646 : : memcpy(skb_push(msdu,
1647 : : ath10k_htt_rx_crypto_param_len(ar, enctype)),
1648 : : (void *)hdr + round_up(hdr_len, bytes_aligned),
1649 : : ath10k_htt_rx_crypto_param_len(ar, enctype));
1650 : : }
1651 : :
1652 : : memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
1653 : : }
1654 : :
1655 : 0 : static void ath10k_htt_rx_h_undecap(struct ath10k *ar,
1656 : : struct sk_buff *msdu,
1657 : : struct ieee80211_rx_status *status,
1658 : : u8 first_hdr[64],
1659 : : enum htt_rx_mpdu_encrypt_type enctype,
1660 : : bool is_decrypted)
1661 : : {
1662 : 0 : struct htt_rx_desc *rxd;
1663 : 0 : enum rx_msdu_decap_format decap;
1664 : :
1665 : : /* First msdu's decapped header:
1666 : : * [802.11 header] <-- padded to 4 bytes long
1667 : : * [crypto param] <-- padded to 4 bytes long
1668 : : * [amsdu header] <-- only if A-MSDU
1669 : : * [rfc1042/llc]
1670 : : *
1671 : : * Other (2nd, 3rd, ..) msdu's decapped header:
1672 : : * [amsdu header] <-- only if A-MSDU
1673 : : * [rfc1042/llc]
1674 : : */
1675 : :
1676 : 0 : rxd = (void *)msdu->data - sizeof(*rxd);
1677 : 0 : decap = MS(__le32_to_cpu(rxd->msdu_start.common.info1),
1678 : : RX_MSDU_START_INFO1_DECAP_FORMAT);
1679 : :
1680 [ # # # # ]: 0 : switch (decap) {
1681 : 0 : case RX_MSDU_DECAP_RAW:
1682 : 0 : ath10k_htt_rx_h_undecap_raw(ar, msdu, status, enctype,
1683 : : is_decrypted, first_hdr);
1684 : 0 : break;
1685 : 0 : case RX_MSDU_DECAP_NATIVE_WIFI:
1686 : 0 : ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr,
1687 : : enctype);
1688 : 0 : break;
1689 : 0 : case RX_MSDU_DECAP_ETHERNET2_DIX:
1690 : 0 : ath10k_htt_rx_h_undecap_eth(ar, msdu, status, first_hdr, enctype);
1691 : 0 : break;
1692 : 0 : case RX_MSDU_DECAP_8023_SNAP_LLC:
1693 : 0 : ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr,
1694 : : enctype);
1695 : 0 : break;
1696 : : }
1697 : 0 : }
1698 : :
1699 : : static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb)
1700 : : {
1701 : : struct htt_rx_desc *rxd;
1702 : : u32 flags, info;
1703 : : bool is_ip4, is_ip6;
1704 : : bool is_tcp, is_udp;
1705 : : bool ip_csum_ok, tcpudp_csum_ok;
1706 : :
1707 : : rxd = (void *)skb->data - sizeof(*rxd);
1708 : : flags = __le32_to_cpu(rxd->attention.flags);
1709 : : info = __le32_to_cpu(rxd->msdu_start.common.info1);
1710 : :
1711 : : is_ip4 = !!(info & RX_MSDU_START_INFO1_IPV4_PROTO);
1712 : : is_ip6 = !!(info & RX_MSDU_START_INFO1_IPV6_PROTO);
1713 : : is_tcp = !!(info & RX_MSDU_START_INFO1_TCP_PROTO);
1714 : : is_udp = !!(info & RX_MSDU_START_INFO1_UDP_PROTO);
1715 : : ip_csum_ok = !(flags & RX_ATTENTION_FLAGS_IP_CHKSUM_FAIL);
1716 : : tcpudp_csum_ok = !(flags & RX_ATTENTION_FLAGS_TCP_UDP_CHKSUM_FAIL);
1717 : :
1718 : : if (!is_ip4 && !is_ip6)
1719 : : return CHECKSUM_NONE;
1720 : : if (!is_tcp && !is_udp)
1721 : : return CHECKSUM_NONE;
1722 : : if (!ip_csum_ok)
1723 : : return CHECKSUM_NONE;
1724 : : if (!tcpudp_csum_ok)
1725 : : return CHECKSUM_NONE;
1726 : :
1727 : : return CHECKSUM_UNNECESSARY;
1728 : : }
1729 : :
1730 : 0 : static void ath10k_htt_rx_h_csum_offload(struct sk_buff *msdu)
1731 : : {
1732 : 0 : msdu->ip_summed = ath10k_htt_rx_get_csum_state(msdu);
1733 : : }
1734 : :
1735 : 0 : static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
1736 : : struct sk_buff_head *amsdu,
1737 : : struct ieee80211_rx_status *status,
1738 : : bool fill_crypt_header,
1739 : : u8 *rx_hdr,
1740 : : enum ath10k_pkt_rx_err *err)
1741 : : {
1742 : 0 : struct sk_buff *first;
1743 : 0 : struct sk_buff *last;
1744 : 0 : struct sk_buff *msdu;
1745 : 0 : struct htt_rx_desc *rxd;
1746 : 0 : struct ieee80211_hdr *hdr;
1747 : 0 : enum htt_rx_mpdu_encrypt_type enctype;
1748 : 0 : u8 first_hdr[64];
1749 : 0 : u8 *qos;
1750 : 0 : bool has_fcs_err;
1751 : 0 : bool has_crypto_err;
1752 : 0 : bool has_tkip_err;
1753 : 0 : bool has_peer_idx_invalid;
1754 : 0 : bool is_decrypted;
1755 : 0 : bool is_mgmt;
1756 : 0 : u32 attention;
1757 : :
1758 [ # # ]: 0 : if (skb_queue_empty(amsdu))
1759 : 0 : return;
1760 : :
1761 [ # # ]: 0 : first = skb_peek(amsdu);
1762 : 0 : rxd = (void *)first->data - sizeof(*rxd);
1763 : :
1764 : 0 : is_mgmt = !!(rxd->attention.flags &
1765 : : __cpu_to_le32(RX_ATTENTION_FLAGS_MGMT_TYPE));
1766 : :
1767 : 0 : enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
1768 : : RX_MPDU_START_INFO0_ENCRYPT_TYPE);
1769 : :
1770 : : /* First MSDU's Rx descriptor in an A-MSDU contains full 802.11
1771 : : * decapped header. It'll be used for undecapping of each MSDU.
1772 : : */
1773 : 0 : hdr = (void *)rxd->rx_hdr_status;
1774 : 0 : memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN);
1775 : :
1776 [ # # ]: 0 : if (rx_hdr)
1777 : 0 : memcpy(rx_hdr, hdr, RX_HTT_HDR_STATUS_LEN);
1778 : :
1779 : : /* Each A-MSDU subframe will use the original header as the base and be
1780 : : * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl.
1781 : : */
1782 : 0 : hdr = (void *)first_hdr;
1783 : :
1784 [ # # ]: 0 : if (ieee80211_is_data_qos(hdr->frame_control)) {
1785 [ # # ]: 0 : qos = ieee80211_get_qos_ctl(hdr);
1786 : 0 : qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
1787 : : }
1788 : :
1789 : : /* Some attention flags are valid only in the last MSDU. */
1790 [ # # ]: 0 : last = skb_peek_tail(amsdu);
1791 : 0 : rxd = (void *)last->data - sizeof(*rxd);
1792 : 0 : attention = __le32_to_cpu(rxd->attention.flags);
1793 : :
1794 : 0 : has_fcs_err = !!(attention & RX_ATTENTION_FLAGS_FCS_ERR);
1795 : 0 : has_crypto_err = !!(attention & RX_ATTENTION_FLAGS_DECRYPT_ERR);
1796 : 0 : has_tkip_err = !!(attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR);
1797 : 0 : has_peer_idx_invalid = !!(attention & RX_ATTENTION_FLAGS_PEER_IDX_INVALID);
1798 : :
1799 : : /* Note: If hardware captures an encrypted frame that it can't decrypt,
1800 : : * e.g. due to fcs error, missing peer or invalid key data it will
1801 : : * report the frame as raw.
1802 : : */
1803 [ # # ]: 0 : is_decrypted = (enctype != HTT_RX_MPDU_ENCRYPT_NONE &&
1804 [ # # ]: 0 : !has_fcs_err &&
1805 [ # # # # ]: 0 : !has_crypto_err &&
1806 : : !has_peer_idx_invalid);
1807 : :
1808 : : /* Clear per-MPDU flags while leaving per-PPDU flags intact. */
1809 : 0 : status->flag &= ~(RX_FLAG_FAILED_FCS_CRC |
1810 : : RX_FLAG_MMIC_ERROR |
1811 : : RX_FLAG_DECRYPTED |
1812 : : RX_FLAG_IV_STRIPPED |
1813 : : RX_FLAG_ONLY_MONITOR |
1814 : : RX_FLAG_MMIC_STRIPPED);
1815 : :
1816 [ # # ]: 0 : if (has_fcs_err)
1817 : 0 : status->flag |= RX_FLAG_FAILED_FCS_CRC;
1818 : :
1819 [ # # ]: 0 : if (has_tkip_err)
1820 : 0 : status->flag |= RX_FLAG_MMIC_ERROR;
1821 : :
1822 [ # # ]: 0 : if (err) {
1823 [ # # ]: 0 : if (has_fcs_err)
1824 : 0 : *err = ATH10K_PKT_RX_ERR_FCS;
1825 [ # # ]: 0 : else if (has_tkip_err)
1826 : 0 : *err = ATH10K_PKT_RX_ERR_TKIP;
1827 [ # # ]: 0 : else if (has_crypto_err)
1828 : 0 : *err = ATH10K_PKT_RX_ERR_CRYPT;
1829 [ # # ]: 0 : else if (has_peer_idx_invalid)
1830 : 0 : *err = ATH10K_PKT_RX_ERR_PEER_IDX_INVAL;
1831 : : }
1832 : :
1833 : : /* Firmware reports all necessary management frames via WMI already.
1834 : : * They are not reported to monitor interfaces at all so pass the ones
1835 : : * coming via HTT to monitor interfaces instead. This simplifies
1836 : : * matters a lot.
1837 : : */
1838 [ # # ]: 0 : if (is_mgmt)
1839 : 0 : status->flag |= RX_FLAG_ONLY_MONITOR;
1840 : :
1841 [ # # ]: 0 : if (is_decrypted) {
1842 : 0 : status->flag |= RX_FLAG_DECRYPTED;
1843 : :
1844 [ # # ]: 0 : if (likely(!is_mgmt))
1845 : 0 : status->flag |= RX_FLAG_MMIC_STRIPPED;
1846 : :
1847 [ # # ]: 0 : if (fill_crypt_header)
1848 : 0 : status->flag |= RX_FLAG_MIC_STRIPPED |
1849 : : RX_FLAG_ICV_STRIPPED;
1850 : : else
1851 : 0 : status->flag |= RX_FLAG_IV_STRIPPED;
1852 : : }
1853 : :
1854 [ # # ]: 0 : skb_queue_walk(amsdu, msdu) {
1855 : 0 : ath10k_htt_rx_h_csum_offload(msdu);
1856 : 0 : ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype,
1857 : : is_decrypted);
1858 : :
1859 : : /* Undecapping involves copying the original 802.11 header back
1860 : : * to sk_buff. If frame is protected and hardware has decrypted
1861 : : * it then remove the protected bit.
1862 : : */
1863 [ # # ]: 0 : if (!is_decrypted)
1864 : 0 : continue;
1865 [ # # ]: 0 : if (is_mgmt)
1866 : 0 : continue;
1867 : :
1868 [ # # ]: 0 : if (fill_crypt_header)
1869 : 0 : continue;
1870 : :
1871 : 0 : hdr = (void *)msdu->data;
1872 : 0 : hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
1873 : : }
1874 : : }
1875 : :
1876 : 0 : static void ath10k_htt_rx_h_enqueue(struct ath10k *ar,
1877 : : struct sk_buff_head *amsdu,
1878 : : struct ieee80211_rx_status *status)
1879 : : {
1880 : 0 : struct sk_buff *msdu;
1881 : 0 : struct sk_buff *first_subframe;
1882 : :
1883 [ # # ]: 0 : first_subframe = skb_peek(amsdu);
1884 : :
1885 [ # # # # ]: 0 : while ((msdu = __skb_dequeue(amsdu))) {
1886 : : /* Setup per-MSDU flags */
1887 [ # # ]: 0 : if (skb_queue_empty(amsdu))
1888 : 0 : status->flag &= ~RX_FLAG_AMSDU_MORE;
1889 : : else
1890 : 0 : status->flag |= RX_FLAG_AMSDU_MORE;
1891 : :
1892 [ # # ]: 0 : if (msdu == first_subframe) {
1893 : 0 : first_subframe = NULL;
1894 : 0 : status->flag &= ~RX_FLAG_ALLOW_SAME_PN;
1895 : : } else {
1896 : 0 : status->flag |= RX_FLAG_ALLOW_SAME_PN;
1897 : : }
1898 : :
1899 : 0 : ath10k_htt_rx_h_queue_msdu(ar, status, msdu);
1900 : : }
1901 : 0 : }
1902 : :
1903 : 0 : static int ath10k_unchain_msdu(struct sk_buff_head *amsdu,
1904 : : unsigned long *unchain_cnt)
1905 : : {
1906 : 0 : struct sk_buff *skb, *first;
1907 : 0 : int space;
1908 : 0 : int total_len = 0;
1909 [ # # ]: 0 : int amsdu_len = skb_queue_len(amsdu);
1910 : :
1911 : : /* TODO: Might could optimize this by using
1912 : : * skb_try_coalesce or similar method to
1913 : : * decrease copying, or maybe get mac80211 to
1914 : : * provide a way to just receive a list of
1915 : : * skb?
1916 : : */
1917 : :
1918 [ # # ]: 0 : first = __skb_dequeue(amsdu);
1919 : :
1920 : : /* Allocate total length all at once. */
1921 [ # # ]: 0 : skb_queue_walk(amsdu, skb)
1922 : 0 : total_len += skb->len;
1923 : :
1924 [ # # ]: 0 : space = total_len - skb_tailroom(first);
1925 [ # # # # ]: 0 : if ((space > 0) &&
1926 : 0 : (pskb_expand_head(first, 0, space, GFP_ATOMIC) < 0)) {
1927 : : /* TODO: bump some rx-oom error stat */
1928 : : /* put it back together so we can free the
1929 : : * whole list at once.
1930 : : */
1931 : 0 : __skb_queue_head(amsdu, first);
1932 : 0 : return -1;
1933 : : }
1934 : :
1935 : : /* Walk list again, copying contents into
1936 : : * msdu_head
1937 : : */
1938 [ # # # # ]: 0 : while ((skb = __skb_dequeue(amsdu))) {
1939 : 0 : skb_copy_from_linear_data(skb, skb_put(first, skb->len),
1940 : : skb->len);
1941 : 0 : dev_kfree_skb_any(skb);
1942 : : }
1943 : :
1944 : 0 : __skb_queue_head(amsdu, first);
1945 : :
1946 : 0 : *unchain_cnt += amsdu_len - 1;
1947 : :
1948 : 0 : return 0;
1949 : : }
1950 : :
1951 : : static void ath10k_htt_rx_h_unchain(struct ath10k *ar,
1952 : : struct sk_buff_head *amsdu,
1953 : : unsigned long *drop_cnt,
1954 : : unsigned long *unchain_cnt)
1955 : : {
1956 : : struct sk_buff *first;
1957 : : struct htt_rx_desc *rxd;
1958 : : enum rx_msdu_decap_format decap;
1959 : :
1960 : : first = skb_peek(amsdu);
1961 : : rxd = (void *)first->data - sizeof(*rxd);
1962 : : decap = MS(__le32_to_cpu(rxd->msdu_start.common.info1),
1963 : : RX_MSDU_START_INFO1_DECAP_FORMAT);
1964 : :
1965 : : /* FIXME: Current unchaining logic can only handle simple case of raw
1966 : : * msdu chaining. If decapping is other than raw the chaining may be
1967 : : * more complex and this isn't handled by the current code. Don't even
1968 : : * try re-constructing such frames - it'll be pretty much garbage.
1969 : : */
1970 : : if (decap != RX_MSDU_DECAP_RAW ||
1971 : : skb_queue_len(amsdu) != 1 + rxd->frag_info.ring2_more_count) {
1972 : : *drop_cnt += skb_queue_len(amsdu);
1973 : : __skb_queue_purge(amsdu);
1974 : : return;
1975 : : }
1976 : :
1977 : : ath10k_unchain_msdu(amsdu, unchain_cnt);
1978 : : }
1979 : :
1980 : : static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar,
1981 : : struct sk_buff_head *amsdu,
1982 : : struct ieee80211_rx_status *rx_status)
1983 : : {
1984 : : /* FIXME: It might be a good idea to do some fuzzy-testing to drop
1985 : : * invalid/dangerous frames.
1986 : : */
1987 : :
1988 : : if (!rx_status->freq) {
1989 : : ath10k_dbg(ar, ATH10K_DBG_HTT, "no channel configured; ignoring frame(s)!\n");
1990 : : return false;
1991 : : }
1992 : :
1993 : : if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) {
1994 : : ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx cac running\n");
1995 : : return false;
1996 : : }
1997 : :
1998 : : return true;
1999 : : }
2000 : :
2001 : 0 : static void ath10k_htt_rx_h_filter(struct ath10k *ar,
2002 : : struct sk_buff_head *amsdu,
2003 : : struct ieee80211_rx_status *rx_status,
2004 : : unsigned long *drop_cnt)
2005 : : {
2006 [ # # ]: 0 : if (skb_queue_empty(amsdu))
2007 : : return;
2008 : :
2009 [ # # ]: 0 : if (ath10k_htt_rx_amsdu_allowed(ar, amsdu, rx_status))
2010 : : return;
2011 : :
2012 [ # # ]: 0 : if (drop_cnt)
2013 : 0 : *drop_cnt += skb_queue_len(amsdu);
2014 : :
2015 : 0 : __skb_queue_purge(amsdu);
2016 : : }
2017 : :
2018 : 0 : static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt)
2019 : : {
2020 : 0 : struct ath10k *ar = htt->ar;
2021 : 0 : struct ieee80211_rx_status *rx_status = &htt->rx_status;
2022 : 0 : struct sk_buff_head amsdu;
2023 : 0 : int ret;
2024 : 0 : unsigned long drop_cnt = 0;
2025 : 0 : unsigned long unchain_cnt = 0;
2026 : 0 : unsigned long drop_cnt_filter = 0;
2027 : 0 : unsigned long msdus_to_queue, num_msdus;
2028 : 0 : enum ath10k_pkt_rx_err err = ATH10K_PKT_RX_ERR_MAX;
2029 : 0 : u8 first_hdr[RX_HTT_HDR_STATUS_LEN];
2030 : :
2031 : 0 : __skb_queue_head_init(&amsdu);
2032 : :
2033 : 0 : spin_lock_bh(&htt->rx_ring.lock);
2034 [ # # ]: 0 : if (htt->rx_confused) {
2035 : 0 : spin_unlock_bh(&htt->rx_ring.lock);
2036 : 0 : return -EIO;
2037 : : }
2038 : 0 : ret = ath10k_htt_rx_amsdu_pop(htt, &amsdu);
2039 : 0 : spin_unlock_bh(&htt->rx_ring.lock);
2040 : :
2041 [ # # ]: 0 : if (ret < 0) {
2042 : 0 : ath10k_warn(ar, "rx ring became corrupted: %d\n", ret);
2043 : 0 : __skb_queue_purge(&amsdu);
2044 : : /* FIXME: It's probably a good idea to reboot the
2045 : : * device instead of leaving it inoperable.
2046 : : */
2047 : 0 : htt->rx_confused = true;
2048 : 0 : return ret;
2049 : : }
2050 : :
2051 : 0 : num_msdus = skb_queue_len(&amsdu);
2052 : :
2053 : 0 : ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff);
2054 : :
2055 : : /* only for ret = 1 indicates chained msdus */
2056 [ # # ]: 0 : if (ret > 0)
2057 : 0 : ath10k_htt_rx_h_unchain(ar, &amsdu, &drop_cnt, &unchain_cnt);
2058 : :
2059 : 0 : ath10k_htt_rx_h_filter(ar, &amsdu, rx_status, &drop_cnt_filter);
2060 : 0 : ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true, first_hdr, &err);
2061 : 0 : msdus_to_queue = skb_queue_len(&amsdu);
2062 : 0 : ath10k_htt_rx_h_enqueue(ar, &amsdu, rx_status);
2063 : :
2064 : 0 : ath10k_sta_update_rx_tid_stats(ar, first_hdr, num_msdus, err,
2065 : : unchain_cnt, drop_cnt, drop_cnt_filter,
2066 : : msdus_to_queue);
2067 : :
2068 : 0 : return 0;
2069 : : }
2070 : :
2071 : 0 : static void ath10k_htt_rx_mpdu_desc_pn_hl(struct htt_hl_rx_desc *rx_desc,
2072 : : union htt_rx_pn_t *pn,
2073 : : int pn_len_bits)
2074 : : {
2075 : 0 : switch (pn_len_bits) {
2076 : 0 : case 48:
2077 : 0 : pn->pn48 = __le32_to_cpu(rx_desc->pn_31_0) +
2078 : 0 : ((u64)(__le32_to_cpu(rx_desc->u0.pn_63_32) & 0xFFFF) << 32);
2079 : 0 : break;
2080 : 0 : case 24:
2081 : 0 : pn->pn24 = __le32_to_cpu(rx_desc->pn_31_0);
2082 : 0 : break;
2083 : : }
2084 : 0 : }
2085 : :
2086 : : static bool ath10k_htt_rx_pn_cmp48(union htt_rx_pn_t *new_pn,
2087 : : union htt_rx_pn_t *old_pn)
2088 : : {
2089 : : return ((new_pn->pn48 & 0xffffffffffffULL) <=
2090 : : (old_pn->pn48 & 0xffffffffffffULL));
2091 : : }
2092 : :
2093 : : static bool ath10k_htt_rx_pn_check_replay_hl(struct ath10k *ar,
2094 : : struct ath10k_peer *peer,
2095 : : struct htt_rx_indication_hl *rx)
2096 : : {
2097 : : bool last_pn_valid, pn_invalid = false;
2098 : : enum htt_txrx_sec_cast_type sec_index;
2099 : : enum htt_security_types sec_type;
2100 : : union htt_rx_pn_t new_pn = {0};
2101 : : struct htt_hl_rx_desc *rx_desc;
2102 : : union htt_rx_pn_t *last_pn;
2103 : : u32 rx_desc_info, tid;
2104 : : int num_mpdu_ranges;
2105 : :
2106 : : lockdep_assert_held(&ar->data_lock);
2107 : :
2108 : : if (!peer)
2109 : : return false;
2110 : :
2111 : : if (!(rx->fw_desc.flags & FW_RX_DESC_FLAGS_FIRST_MSDU))
2112 : : return false;
2113 : :
2114 : : num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1),
2115 : : HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
2116 : :
2117 : : rx_desc = (struct htt_hl_rx_desc *)&rx->mpdu_ranges[num_mpdu_ranges];
2118 : : rx_desc_info = __le32_to_cpu(rx_desc->info);
2119 : :
2120 : : if (!MS(rx_desc_info, HTT_RX_DESC_HL_INFO_ENCRYPTED))
2121 : : return false;
2122 : :
2123 : : tid = MS(rx->hdr.info0, HTT_RX_INDICATION_INFO0_EXT_TID);
2124 : : last_pn_valid = peer->tids_last_pn_valid[tid];
2125 : : last_pn = &peer->tids_last_pn[tid];
2126 : :
2127 : : if (MS(rx_desc_info, HTT_RX_DESC_HL_INFO_MCAST_BCAST))
2128 : : sec_index = HTT_TXRX_SEC_MCAST;
2129 : : else
2130 : : sec_index = HTT_TXRX_SEC_UCAST;
2131 : :
2132 : : sec_type = peer->rx_pn[sec_index].sec_type;
2133 : : ath10k_htt_rx_mpdu_desc_pn_hl(rx_desc, &new_pn, peer->rx_pn[sec_index].pn_len);
2134 : :
2135 : : if (sec_type != HTT_SECURITY_AES_CCMP &&
2136 : : sec_type != HTT_SECURITY_TKIP &&
2137 : : sec_type != HTT_SECURITY_TKIP_NOMIC)
2138 : : return false;
2139 : :
2140 : : if (last_pn_valid)
2141 : : pn_invalid = ath10k_htt_rx_pn_cmp48(&new_pn, last_pn);
2142 : : else
2143 : : peer->tids_last_pn_valid[tid] = true;
2144 : :
2145 : : if (!pn_invalid)
2146 : : last_pn->pn48 = new_pn.pn48;
2147 : :
2148 : : return pn_invalid;
2149 : : }
2150 : :
2151 : : static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
2152 : : struct htt_rx_indication_hl *rx,
2153 : : struct sk_buff *skb,
2154 : : enum htt_rx_pn_check_type check_pn_type,
2155 : : enum htt_rx_tkip_demic_type tkip_mic_type)
2156 : : {
2157 : : struct ath10k *ar = htt->ar;
2158 : : struct ath10k_peer *peer;
2159 : : struct htt_rx_indication_mpdu_range *mpdu_ranges;
2160 : : struct fw_rx_desc_hl *fw_desc;
2161 : : enum htt_txrx_sec_cast_type sec_index;
2162 : : enum htt_security_types sec_type;
2163 : : union htt_rx_pn_t new_pn = {0};
2164 : : struct htt_hl_rx_desc *rx_desc;
2165 : : struct ieee80211_hdr *hdr;
2166 : : struct ieee80211_rx_status *rx_status;
2167 : : u16 peer_id;
2168 : : u8 rx_desc_len;
2169 : : int num_mpdu_ranges;
2170 : : size_t tot_hdr_len;
2171 : : struct ieee80211_channel *ch;
2172 : : bool pn_invalid, qos, first_msdu;
2173 : : u32 tid, rx_desc_info;
2174 : :
2175 : : peer_id = __le16_to_cpu(rx->hdr.peer_id);
2176 : : tid = MS(rx->hdr.info0, HTT_RX_INDICATION_INFO0_EXT_TID);
2177 : :
2178 : : spin_lock_bh(&ar->data_lock);
2179 : : peer = ath10k_peer_find_by_id(ar, peer_id);
2180 : : spin_unlock_bh(&ar->data_lock);
2181 : : if (!peer && peer_id != HTT_INVALID_PEERID)
2182 : : ath10k_warn(ar, "Got RX ind from invalid peer: %u\n", peer_id);
2183 : :
2184 : : if (!peer)
2185 : : return true;
2186 : :
2187 : : num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1),
2188 : : HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
2189 : : mpdu_ranges = htt_rx_ind_get_mpdu_ranges_hl(rx);
2190 : : fw_desc = &rx->fw_desc;
2191 : : rx_desc_len = fw_desc->len;
2192 : :
2193 : : /* I have not yet seen any case where num_mpdu_ranges > 1.
2194 : : * qcacld does not seem handle that case either, so we introduce the
2195 : : * same limitiation here as well.
2196 : : */
2197 : : if (num_mpdu_ranges > 1)
2198 : : ath10k_warn(ar,
2199 : : "Unsupported number of MPDU ranges: %d, ignoring all but the first\n",
2200 : : num_mpdu_ranges);
2201 : :
2202 : : if (mpdu_ranges->mpdu_range_status !=
2203 : : HTT_RX_IND_MPDU_STATUS_OK &&
2204 : : mpdu_ranges->mpdu_range_status !=
2205 : : HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR) {
2206 : : ath10k_dbg(ar, ATH10K_DBG_HTT, "htt mpdu_range_status %d\n",
2207 : : mpdu_ranges->mpdu_range_status);
2208 : : goto err;
2209 : : }
2210 : :
2211 : : rx_desc = (struct htt_hl_rx_desc *)&rx->mpdu_ranges[num_mpdu_ranges];
2212 : : rx_desc_info = __le32_to_cpu(rx_desc->info);
2213 : :
2214 : : if (MS(rx_desc_info, HTT_RX_DESC_HL_INFO_MCAST_BCAST))
2215 : : sec_index = HTT_TXRX_SEC_MCAST;
2216 : : else
2217 : : sec_index = HTT_TXRX_SEC_UCAST;
2218 : :
2219 : : sec_type = peer->rx_pn[sec_index].sec_type;
2220 : : first_msdu = rx->fw_desc.flags & FW_RX_DESC_FLAGS_FIRST_MSDU;
2221 : :
2222 : : ath10k_htt_rx_mpdu_desc_pn_hl(rx_desc, &new_pn, peer->rx_pn[sec_index].pn_len);
2223 : :
2224 : : if (check_pn_type == HTT_RX_PN_CHECK && tid >= IEEE80211_NUM_TIDS) {
2225 : : spin_lock_bh(&ar->data_lock);
2226 : : pn_invalid = ath10k_htt_rx_pn_check_replay_hl(ar, peer, rx);
2227 : : spin_unlock_bh(&ar->data_lock);
2228 : :
2229 : : if (pn_invalid)
2230 : : goto err;
2231 : : }
2232 : :
2233 : : /* Strip off all headers before the MAC header before delivery to
2234 : : * mac80211
2235 : : */
2236 : : tot_hdr_len = sizeof(struct htt_resp_hdr) + sizeof(rx->hdr) +
2237 : : sizeof(rx->ppdu) + sizeof(rx->prefix) +
2238 : : sizeof(rx->fw_desc) +
2239 : : sizeof(*mpdu_ranges) * num_mpdu_ranges + rx_desc_len;
2240 : :
2241 : : skb_pull(skb, tot_hdr_len);
2242 : :
2243 : : hdr = (struct ieee80211_hdr *)skb->data;
2244 : : qos = ieee80211_is_data_qos(hdr->frame_control);
2245 : :
2246 : : rx_status = IEEE80211_SKB_RXCB(skb);
2247 : : memset(rx_status, 0, sizeof(*rx_status));
2248 : :
2249 : : if (rx->ppdu.combined_rssi == 0) {
2250 : : /* SDIO firmware does not provide signal */
2251 : : rx_status->signal = 0;
2252 : : rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
2253 : : } else {
2254 : : rx_status->signal = ATH10K_DEFAULT_NOISE_FLOOR +
2255 : : rx->ppdu.combined_rssi;
2256 : : rx_status->flag &= ~RX_FLAG_NO_SIGNAL_VAL;
2257 : : }
2258 : :
2259 : : spin_lock_bh(&ar->data_lock);
2260 : : ch = ar->scan_channel;
2261 : : if (!ch)
2262 : : ch = ar->rx_channel;
2263 : : if (!ch)
2264 : : ch = ath10k_htt_rx_h_any_channel(ar);
2265 : : if (!ch)
2266 : : ch = ar->tgt_oper_chan;
2267 : : spin_unlock_bh(&ar->data_lock);
2268 : :
2269 : : if (ch) {
2270 : : rx_status->band = ch->band;
2271 : : rx_status->freq = ch->center_freq;
2272 : : }
2273 : : if (rx->fw_desc.flags & FW_RX_DESC_FLAGS_LAST_MSDU)
2274 : : rx_status->flag &= ~RX_FLAG_AMSDU_MORE;
2275 : : else
2276 : : rx_status->flag |= RX_FLAG_AMSDU_MORE;
2277 : :
2278 : : /* Not entirely sure about this, but all frames from the chipset has
2279 : : * the protected flag set even though they have already been decrypted.
2280 : : * Unmasking this flag is necessary in order for mac80211 not to drop
2281 : : * the frame.
2282 : : * TODO: Verify this is always the case or find out a way to check
2283 : : * if there has been hw decryption.
2284 : : */
2285 : : if (ieee80211_has_protected(hdr->frame_control)) {
2286 : : hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2287 : : rx_status->flag |= RX_FLAG_DECRYPTED |
2288 : : RX_FLAG_IV_STRIPPED |
2289 : : RX_FLAG_MMIC_STRIPPED;
2290 : :
2291 : : if (tid < IEEE80211_NUM_TIDS &&
2292 : : first_msdu &&
2293 : : check_pn_type == HTT_RX_PN_CHECK &&
2294 : : (sec_type == HTT_SECURITY_AES_CCMP ||
2295 : : sec_type == HTT_SECURITY_TKIP ||
2296 : : sec_type == HTT_SECURITY_TKIP_NOMIC)) {
2297 : : u8 offset, *ivp, i;
2298 : : s8 keyidx = 0;
2299 : : __le64 pn48 = cpu_to_le64(new_pn.pn48);
2300 : :
2301 : : hdr = (struct ieee80211_hdr *)skb->data;
2302 : : offset = ieee80211_hdrlen(hdr->frame_control);
2303 : : hdr->frame_control |= __cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2304 : : rx_status->flag &= ~RX_FLAG_IV_STRIPPED;
2305 : :
2306 : : memmove(skb->data - IEEE80211_CCMP_HDR_LEN,
2307 : : skb->data, offset);
2308 : : skb_push(skb, IEEE80211_CCMP_HDR_LEN);
2309 : : ivp = skb->data + offset;
2310 : : memset(skb->data + offset, 0, IEEE80211_CCMP_HDR_LEN);
2311 : : /* Ext IV */
2312 : : ivp[IEEE80211_WEP_IV_LEN - 1] |= ATH10K_IEEE80211_EXTIV;
2313 : :
2314 : : for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
2315 : : if (peer->keys[i] &&
2316 : : peer->keys[i]->flags & IEEE80211_KEY_FLAG_PAIRWISE)
2317 : : keyidx = peer->keys[i]->keyidx;
2318 : : }
2319 : :
2320 : : /* Key ID */
2321 : : ivp[IEEE80211_WEP_IV_LEN - 1] |= keyidx << 6;
2322 : :
2323 : : if (sec_type == HTT_SECURITY_AES_CCMP) {
2324 : : rx_status->flag |= RX_FLAG_MIC_STRIPPED;
2325 : : /* pn 0, pn 1 */
2326 : : memcpy(skb->data + offset, &pn48, 2);
2327 : : /* pn 1, pn 3 , pn 34 , pn 5 */
2328 : : memcpy(skb->data + offset + 4, ((u8 *)&pn48) + 2, 4);
2329 : : } else {
2330 : : rx_status->flag |= RX_FLAG_ICV_STRIPPED;
2331 : : /* TSC 0 */
2332 : : memcpy(skb->data + offset + 2, &pn48, 1);
2333 : : /* TSC 1 */
2334 : : memcpy(skb->data + offset, ((u8 *)&pn48) + 1, 1);
2335 : : /* TSC 2 , TSC 3 , TSC 4 , TSC 5*/
2336 : : memcpy(skb->data + offset + 4, ((u8 *)&pn48) + 2, 4);
2337 : : }
2338 : : }
2339 : : }
2340 : :
2341 : : if (tkip_mic_type == HTT_RX_TKIP_MIC)
2342 : : rx_status->flag &= ~RX_FLAG_IV_STRIPPED &
2343 : : ~RX_FLAG_MMIC_STRIPPED;
2344 : :
2345 : : if (mpdu_ranges->mpdu_range_status == HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR)
2346 : : rx_status->flag |= RX_FLAG_MMIC_ERROR;
2347 : :
2348 : : if (!qos && tid < IEEE80211_NUM_TIDS) {
2349 : : u8 offset;
2350 : : __le16 qos_ctrl = 0;
2351 : :
2352 : : hdr = (struct ieee80211_hdr *)skb->data;
2353 : : offset = ieee80211_hdrlen(hdr->frame_control);
2354 : :
2355 : : hdr->frame_control |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
2356 : : memmove(skb->data - IEEE80211_QOS_CTL_LEN, skb->data, offset);
2357 : : skb_push(skb, IEEE80211_QOS_CTL_LEN);
2358 : : qos_ctrl = cpu_to_le16(tid);
2359 : : memcpy(skb->data + offset, &qos_ctrl, IEEE80211_QOS_CTL_LEN);
2360 : : }
2361 : :
2362 : : if (ar->napi.dev)
2363 : : ieee80211_rx_napi(ar->hw, NULL, skb, &ar->napi);
2364 : : else
2365 : : ieee80211_rx_ni(ar->hw, skb);
2366 : :
2367 : : /* We have delivered the skb to the upper layers (mac80211) so we
2368 : : * must not free it.
2369 : : */
2370 : : return false;
2371 : : err:
2372 : : /* Tell the caller that it must free the skb since we have not
2373 : : * consumed it
2374 : : */
2375 : : return true;
2376 : : }
2377 : :
2378 : 0 : static int ath10k_htt_rx_frag_tkip_decap_nomic(struct sk_buff *skb,
2379 : : u16 head_len,
2380 : : u16 hdr_len)
2381 : : {
2382 : 0 : u8 *ivp, *orig_hdr;
2383 : :
2384 : 0 : orig_hdr = skb->data;
2385 : 0 : ivp = orig_hdr + hdr_len + head_len;
2386 : :
2387 : : /* the ExtIV bit is always set to 1 for TKIP */
2388 [ # # ]: 0 : if (!(ivp[IEEE80211_WEP_IV_LEN - 1] & ATH10K_IEEE80211_EXTIV))
2389 : : return -EINVAL;
2390 : :
2391 : 0 : memmove(orig_hdr + IEEE80211_TKIP_IV_LEN, orig_hdr, head_len + hdr_len);
2392 : 0 : skb_pull(skb, IEEE80211_TKIP_IV_LEN);
2393 : 0 : skb_trim(skb, skb->len - ATH10K_IEEE80211_TKIP_MICLEN);
2394 : 0 : return 0;
2395 : : }
2396 : :
2397 : 0 : static int ath10k_htt_rx_frag_tkip_decap_withmic(struct sk_buff *skb,
2398 : : u16 head_len,
2399 : : u16 hdr_len)
2400 : : {
2401 : 0 : u8 *ivp, *orig_hdr;
2402 : :
2403 : 0 : orig_hdr = skb->data;
2404 : 0 : ivp = orig_hdr + hdr_len + head_len;
2405 : :
2406 : : /* the ExtIV bit is always set to 1 for TKIP */
2407 [ # # ]: 0 : if (!(ivp[IEEE80211_WEP_IV_LEN - 1] & ATH10K_IEEE80211_EXTIV))
2408 : : return -EINVAL;
2409 : :
2410 : 0 : memmove(orig_hdr + IEEE80211_TKIP_IV_LEN, orig_hdr, head_len + hdr_len);
2411 : 0 : skb_pull(skb, IEEE80211_TKIP_IV_LEN);
2412 : 0 : skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN);
2413 : 0 : return 0;
2414 : : }
2415 : :
2416 : 0 : static int ath10k_htt_rx_frag_ccmp_decap(struct sk_buff *skb,
2417 : : u16 head_len,
2418 : : u16 hdr_len)
2419 : : {
2420 : 0 : u8 *ivp, *orig_hdr;
2421 : :
2422 : 0 : orig_hdr = skb->data;
2423 : 0 : ivp = orig_hdr + hdr_len + head_len;
2424 : :
2425 : : /* the ExtIV bit is always set to 1 for CCMP */
2426 [ # # ]: 0 : if (!(ivp[IEEE80211_WEP_IV_LEN - 1] & ATH10K_IEEE80211_EXTIV))
2427 : : return -EINVAL;
2428 : :
2429 : 0 : skb_trim(skb, skb->len - IEEE80211_CCMP_MIC_LEN);
2430 : 0 : memmove(orig_hdr + IEEE80211_CCMP_HDR_LEN, orig_hdr, head_len + hdr_len);
2431 : 0 : skb_pull(skb, IEEE80211_CCMP_HDR_LEN);
2432 : 0 : return 0;
2433 : : }
2434 : :
2435 : 0 : static int ath10k_htt_rx_frag_wep_decap(struct sk_buff *skb,
2436 : : u16 head_len,
2437 : : u16 hdr_len)
2438 : : {
2439 : 0 : u8 *orig_hdr;
2440 : :
2441 : 0 : orig_hdr = skb->data;
2442 : :
2443 : 0 : memmove(orig_hdr + IEEE80211_WEP_IV_LEN,
2444 : 0 : orig_hdr, head_len + hdr_len);
2445 : 0 : skb_pull(skb, IEEE80211_WEP_IV_LEN);
2446 : 0 : skb_trim(skb, skb->len - IEEE80211_WEP_ICV_LEN);
2447 : 0 : return 0;
2448 : : }
2449 : :
2450 : 0 : static bool ath10k_htt_rx_proc_rx_frag_ind_hl(struct ath10k_htt *htt,
2451 : : struct htt_rx_fragment_indication *rx,
2452 : : struct sk_buff *skb)
2453 : : {
2454 : 0 : struct ath10k *ar = htt->ar;
2455 : 0 : enum htt_rx_tkip_demic_type tkip_mic = HTT_RX_NON_TKIP_MIC;
2456 : 0 : enum htt_txrx_sec_cast_type sec_index;
2457 : 0 : struct htt_rx_indication_hl *rx_hl;
2458 : 0 : enum htt_security_types sec_type;
2459 : 0 : u32 tid, frag, seq, rx_desc_info;
2460 : 0 : union htt_rx_pn_t new_pn = {0};
2461 : 0 : struct htt_hl_rx_desc *rx_desc;
2462 : 0 : u16 peer_id, sc, hdr_space;
2463 : 0 : union htt_rx_pn_t *last_pn;
2464 : 0 : struct ieee80211_hdr *hdr;
2465 : 0 : int ret, num_mpdu_ranges;
2466 : 0 : struct ath10k_peer *peer;
2467 : 0 : struct htt_resp *resp;
2468 : 0 : size_t tot_hdr_len;
2469 : :
2470 : 0 : resp = (struct htt_resp *)(skb->data + HTT_RX_FRAG_IND_INFO0_HEADER_LEN);
2471 : 0 : skb_pull(skb, HTT_RX_FRAG_IND_INFO0_HEADER_LEN);
2472 : 0 : skb_trim(skb, skb->len - FCS_LEN);
2473 : :
2474 : 0 : peer_id = __le16_to_cpu(rx->peer_id);
2475 : 0 : rx_hl = (struct htt_rx_indication_hl *)(&resp->rx_ind_hl);
2476 : :
2477 : 0 : spin_lock_bh(&ar->data_lock);
2478 : 0 : peer = ath10k_peer_find_by_id(ar, peer_id);
2479 [ # # ]: 0 : if (!peer) {
2480 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT, "invalid peer: %u\n", peer_id);
2481 : 0 : goto err;
2482 : : }
2483 : :
2484 : 0 : num_mpdu_ranges = MS(__le32_to_cpu(rx_hl->hdr.info1),
2485 : : HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
2486 : :
2487 : 0 : tot_hdr_len = sizeof(struct htt_resp_hdr) +
2488 : : sizeof(rx_hl->hdr) +
2489 : : sizeof(rx_hl->ppdu) +
2490 : : sizeof(rx_hl->prefix) +
2491 : 0 : sizeof(rx_hl->fw_desc) +
2492 : : sizeof(struct htt_rx_indication_mpdu_range) * num_mpdu_ranges;
2493 : :
2494 : 0 : tid = MS(rx_hl->hdr.info0, HTT_RX_INDICATION_INFO0_EXT_TID);
2495 : 0 : rx_desc = (struct htt_hl_rx_desc *)(skb->data + tot_hdr_len);
2496 : 0 : rx_desc_info = __le32_to_cpu(rx_desc->info);
2497 : :
2498 [ # # ]: 0 : if (!MS(rx_desc_info, HTT_RX_DESC_HL_INFO_ENCRYPTED)) {
2499 : 0 : spin_unlock_bh(&ar->data_lock);
2500 : 0 : return ath10k_htt_rx_proc_rx_ind_hl(htt, &resp->rx_ind_hl, skb,
2501 : : HTT_RX_NON_PN_CHECK,
2502 : : HTT_RX_NON_TKIP_MIC);
2503 : : }
2504 : :
2505 : 0 : hdr = (struct ieee80211_hdr *)((u8 *)rx_desc + rx_hl->fw_desc.len);
2506 : :
2507 [ # # ]: 0 : if (ieee80211_has_retry(hdr->frame_control))
2508 : 0 : goto err;
2509 : :
2510 : 0 : hdr_space = ieee80211_hdrlen(hdr->frame_control);
2511 : 0 : sc = __le16_to_cpu(hdr->seq_ctrl);
2512 : 0 : seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
2513 : 0 : frag = sc & IEEE80211_SCTL_FRAG;
2514 : :
2515 : 0 : sec_index = MS(rx_desc_info, HTT_RX_DESC_HL_INFO_MCAST_BCAST) ?
2516 : 0 : HTT_TXRX_SEC_MCAST : HTT_TXRX_SEC_UCAST;
2517 : 0 : sec_type = peer->rx_pn[sec_index].sec_type;
2518 [ # # # ]: 0 : ath10k_htt_rx_mpdu_desc_pn_hl(rx_desc, &new_pn, peer->rx_pn[sec_index].pn_len);
2519 : :
2520 [ # # # # : 0 : switch (sec_type) {
# ]
2521 : 0 : case HTT_SECURITY_TKIP:
2522 : 0 : tkip_mic = HTT_RX_TKIP_MIC;
2523 : 0 : ret = ath10k_htt_rx_frag_tkip_decap_withmic(skb,
2524 : 0 : tot_hdr_len +
2525 : 0 : rx_hl->fw_desc.len,
2526 : : hdr_space);
2527 [ # # ]: 0 : if (ret)
2528 : 0 : goto err;
2529 : : break;
2530 : 0 : case HTT_SECURITY_TKIP_NOMIC:
2531 : 0 : ret = ath10k_htt_rx_frag_tkip_decap_nomic(skb,
2532 : 0 : tot_hdr_len +
2533 : 0 : rx_hl->fw_desc.len,
2534 : : hdr_space);
2535 [ # # ]: 0 : if (ret)
2536 : 0 : goto err;
2537 : : break;
2538 : 0 : case HTT_SECURITY_AES_CCMP:
2539 : 0 : ret = ath10k_htt_rx_frag_ccmp_decap(skb,
2540 : 0 : tot_hdr_len + rx_hl->fw_desc.len,
2541 : : hdr_space);
2542 [ # # ]: 0 : if (ret)
2543 : 0 : goto err;
2544 : : break;
2545 : 0 : case HTT_SECURITY_WEP128:
2546 : : case HTT_SECURITY_WEP104:
2547 : : case HTT_SECURITY_WEP40:
2548 : 0 : ret = ath10k_htt_rx_frag_wep_decap(skb,
2549 : 0 : tot_hdr_len + rx_hl->fw_desc.len,
2550 : : hdr_space);
2551 [ # # ]: 0 : if (ret)
2552 : 0 : goto err;
2553 : : break;
2554 : : default:
2555 : : break;
2556 : : }
2557 : :
2558 : 0 : resp = (struct htt_resp *)(skb->data);
2559 : :
2560 [ # # # # ]: 0 : if (sec_type != HTT_SECURITY_AES_CCMP &&
2561 [ # # ]: 0 : sec_type != HTT_SECURITY_TKIP &&
2562 : : sec_type != HTT_SECURITY_TKIP_NOMIC) {
2563 : 0 : spin_unlock_bh(&ar->data_lock);
2564 : 0 : return ath10k_htt_rx_proc_rx_ind_hl(htt, &resp->rx_ind_hl, skb,
2565 : : HTT_RX_NON_PN_CHECK,
2566 : : HTT_RX_NON_TKIP_MIC);
2567 : : }
2568 : :
2569 : 0 : last_pn = &peer->frag_tids_last_pn[tid];
2570 : :
2571 [ # # ]: 0 : if (frag == 0) {
2572 [ # # ]: 0 : if (ath10k_htt_rx_pn_check_replay_hl(ar, peer, &resp->rx_ind_hl))
2573 : 0 : goto err;
2574 : :
2575 : 0 : last_pn->pn48 = new_pn.pn48;
2576 : 0 : peer->frag_tids_seq[tid] = seq;
2577 [ # # ]: 0 : } else if (sec_type == HTT_SECURITY_AES_CCMP) {
2578 [ # # ]: 0 : if (seq != peer->frag_tids_seq[tid])
2579 : 0 : goto err;
2580 : :
2581 [ # # ]: 0 : if (new_pn.pn48 != last_pn->pn48 + 1)
2582 : 0 : goto err;
2583 : :
2584 : 0 : last_pn->pn48 = new_pn.pn48;
2585 : 0 : last_pn = &peer->tids_last_pn[tid];
2586 : 0 : last_pn->pn48 = new_pn.pn48;
2587 : : }
2588 : :
2589 : 0 : spin_unlock_bh(&ar->data_lock);
2590 : :
2591 : 0 : return ath10k_htt_rx_proc_rx_ind_hl(htt, &resp->rx_ind_hl, skb,
2592 : : HTT_RX_NON_PN_CHECK, tkip_mic);
2593 : :
2594 : 0 : err:
2595 : 0 : spin_unlock_bh(&ar->data_lock);
2596 : :
2597 : : /* Tell the caller that it must free the skb since we have not
2598 : : * consumed it
2599 : : */
2600 : 0 : return true;
2601 : : }
2602 : :
2603 : 0 : static void ath10k_htt_rx_proc_rx_ind_ll(struct ath10k_htt *htt,
2604 : : struct htt_rx_indication *rx)
2605 : : {
2606 : 0 : struct ath10k *ar = htt->ar;
2607 : 0 : struct htt_rx_indication_mpdu_range *mpdu_ranges;
2608 : 0 : int num_mpdu_ranges;
2609 : 0 : int i, mpdu_count = 0;
2610 : 0 : u16 peer_id;
2611 : 0 : u8 tid;
2612 : :
2613 : 0 : num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1),
2614 : : HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
2615 : 0 : peer_id = __le16_to_cpu(rx->hdr.peer_id);
2616 : 0 : tid = MS(rx->hdr.info0, HTT_RX_INDICATION_INFO0_EXT_TID);
2617 : :
2618 [ # # ]: 0 : mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx);
2619 : :
2620 [ # # ]: 0 : ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ",
2621 : : rx, struct_size(rx, mpdu_ranges, num_mpdu_ranges));
2622 : :
2623 [ # # ]: 0 : for (i = 0; i < num_mpdu_ranges; i++)
2624 : 0 : mpdu_count += mpdu_ranges[i].mpdu_count;
2625 : :
2626 : 0 : atomic_add(mpdu_count, &htt->num_mpdus_ready);
2627 : :
2628 : 0 : ath10k_sta_update_rx_tid_stats_ampdu(ar, peer_id, tid, mpdu_ranges,
2629 : : num_mpdu_ranges);
2630 : 0 : }
2631 : :
2632 : : static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar,
2633 : : struct sk_buff *skb)
2634 : : {
2635 : : struct ath10k_htt *htt = &ar->htt;
2636 : : struct htt_resp *resp = (struct htt_resp *)skb->data;
2637 : : struct htt_tx_done tx_done = {};
2638 : : int status = MS(resp->data_tx_completion.flags, HTT_DATA_TX_STATUS);
2639 : : __le16 msdu_id, *msdus;
2640 : : bool rssi_enabled = false;
2641 : : u8 msdu_count = 0, num_airtime_records, tid;
2642 : : int i, htt_pad = 0;
2643 : : struct htt_data_tx_compl_ppdu_dur *ppdu_info;
2644 : : struct ath10k_peer *peer;
2645 : : u16 ppdu_info_offset = 0, peer_id;
2646 : : u32 tx_duration;
2647 : :
2648 : : switch (status) {
2649 : : case HTT_DATA_TX_STATUS_NO_ACK:
2650 : : tx_done.status = HTT_TX_COMPL_STATE_NOACK;
2651 : : break;
2652 : : case HTT_DATA_TX_STATUS_OK:
2653 : : tx_done.status = HTT_TX_COMPL_STATE_ACK;
2654 : : break;
2655 : : case HTT_DATA_TX_STATUS_DISCARD:
2656 : : case HTT_DATA_TX_STATUS_POSTPONE:
2657 : : case HTT_DATA_TX_STATUS_DOWNLOAD_FAIL:
2658 : : tx_done.status = HTT_TX_COMPL_STATE_DISCARD;
2659 : : break;
2660 : : default:
2661 : : ath10k_warn(ar, "unhandled tx completion status %d\n", status);
2662 : : tx_done.status = HTT_TX_COMPL_STATE_DISCARD;
2663 : : break;
2664 : : }
2665 : :
2666 : : ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx completion num_msdus %d\n",
2667 : : resp->data_tx_completion.num_msdus);
2668 : :
2669 : : msdu_count = resp->data_tx_completion.num_msdus;
2670 : : msdus = resp->data_tx_completion.msdus;
2671 : : rssi_enabled = ath10k_is_rssi_enable(&ar->hw_params, resp);
2672 : :
2673 : : if (rssi_enabled)
2674 : : htt_pad = ath10k_tx_data_rssi_get_pad_bytes(&ar->hw_params,
2675 : : resp);
2676 : :
2677 : : for (i = 0; i < msdu_count; i++) {
2678 : : msdu_id = msdus[i];
2679 : : tx_done.msdu_id = __le16_to_cpu(msdu_id);
2680 : :
2681 : : if (rssi_enabled) {
2682 : : /* Total no of MSDUs should be even,
2683 : : * if odd MSDUs are sent firmware fills
2684 : : * last msdu id with 0xffff
2685 : : */
2686 : : if (msdu_count & 0x01) {
2687 : : msdu_id = msdus[msdu_count + i + 1 + htt_pad];
2688 : : tx_done.ack_rssi = __le16_to_cpu(msdu_id);
2689 : : } else {
2690 : : msdu_id = msdus[msdu_count + i + htt_pad];
2691 : : tx_done.ack_rssi = __le16_to_cpu(msdu_id);
2692 : : }
2693 : : }
2694 : :
2695 : : /* kfifo_put: In practice firmware shouldn't fire off per-CE
2696 : : * interrupt and main interrupt (MSI/-X range case) for the same
2697 : : * HTC service so it should be safe to use kfifo_put w/o lock.
2698 : : *
2699 : : * From kfifo_put() documentation:
2700 : : * Note that with only one concurrent reader and one concurrent
2701 : : * writer, you don't need extra locking to use these macro.
2702 : : */
2703 : : if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) {
2704 : : ath10k_txrx_tx_unref(htt, &tx_done);
2705 : : } else if (!kfifo_put(&htt->txdone_fifo, tx_done)) {
2706 : : ath10k_warn(ar, "txdone fifo overrun, msdu_id %d status %d\n",
2707 : : tx_done.msdu_id, tx_done.status);
2708 : : ath10k_txrx_tx_unref(htt, &tx_done);
2709 : : }
2710 : : }
2711 : :
2712 : : if (!(resp->data_tx_completion.flags2 & HTT_TX_CMPL_FLAG_PPDU_DURATION_PRESENT))
2713 : : return;
2714 : :
2715 : : ppdu_info_offset = (msdu_count & 0x01) ? msdu_count + 1 : msdu_count;
2716 : :
2717 : : if (rssi_enabled)
2718 : : ppdu_info_offset += ppdu_info_offset;
2719 : :
2720 : : if (resp->data_tx_completion.flags2 &
2721 : : (HTT_TX_CMPL_FLAG_PPID_PRESENT | HTT_TX_CMPL_FLAG_PA_PRESENT))
2722 : : ppdu_info_offset += 2;
2723 : :
2724 : : ppdu_info = (struct htt_data_tx_compl_ppdu_dur *)&msdus[ppdu_info_offset];
2725 : : num_airtime_records = FIELD_GET(HTT_TX_COMPL_PPDU_DUR_INFO0_NUM_ENTRIES_MASK,
2726 : : __le32_to_cpu(ppdu_info->info0));
2727 : :
2728 : : for (i = 0; i < num_airtime_records; i++) {
2729 : : struct htt_data_tx_ppdu_dur *ppdu_dur;
2730 : : u32 info0;
2731 : :
2732 : : ppdu_dur = &ppdu_info->ppdu_dur[i];
2733 : : info0 = __le32_to_cpu(ppdu_dur->info0);
2734 : :
2735 : : peer_id = FIELD_GET(HTT_TX_PPDU_DUR_INFO0_PEER_ID_MASK,
2736 : : info0);
2737 : : rcu_read_lock();
2738 : : spin_lock_bh(&ar->data_lock);
2739 : :
2740 : : peer = ath10k_peer_find_by_id(ar, peer_id);
2741 : : if (!peer || !peer->sta) {
2742 : : spin_unlock_bh(&ar->data_lock);
2743 : : rcu_read_unlock();
2744 : : continue;
2745 : : }
2746 : :
2747 : : tid = FIELD_GET(HTT_TX_PPDU_DUR_INFO0_TID_MASK, info0);
2748 : : tx_duration = __le32_to_cpu(ppdu_dur->tx_duration);
2749 : :
2750 : : ieee80211_sta_register_airtime(peer->sta, tid, tx_duration, 0);
2751 : :
2752 : : spin_unlock_bh(&ar->data_lock);
2753 : : rcu_read_unlock();
2754 : : }
2755 : : }
2756 : :
2757 : 0 : static void ath10k_htt_rx_addba(struct ath10k *ar, struct htt_resp *resp)
2758 : : {
2759 : 0 : struct htt_rx_addba *ev = &resp->rx_addba;
2760 : 0 : struct ath10k_peer *peer;
2761 : 0 : struct ath10k_vif *arvif;
2762 : 0 : u16 info0, tid, peer_id;
2763 : :
2764 : 0 : info0 = __le16_to_cpu(ev->info0);
2765 : 0 : tid = MS(info0, HTT_RX_BA_INFO0_TID);
2766 : 0 : peer_id = MS(info0, HTT_RX_BA_INFO0_PEER_ID);
2767 : :
2768 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT,
2769 : : "htt rx addba tid %hu peer_id %hu size %hhu\n",
2770 : : tid, peer_id, ev->window_size);
2771 : :
2772 : 0 : spin_lock_bh(&ar->data_lock);
2773 : 0 : peer = ath10k_peer_find_by_id(ar, peer_id);
2774 [ # # ]: 0 : if (!peer) {
2775 : 0 : ath10k_warn(ar, "received addba event for invalid peer_id: %hu\n",
2776 : : peer_id);
2777 : 0 : spin_unlock_bh(&ar->data_lock);
2778 : 0 : return;
2779 : : }
2780 : :
2781 : 0 : arvif = ath10k_get_arvif(ar, peer->vdev_id);
2782 [ # # ]: 0 : if (!arvif) {
2783 : 0 : ath10k_warn(ar, "received addba event for invalid vdev_id: %u\n",
2784 : : peer->vdev_id);
2785 : 0 : spin_unlock_bh(&ar->data_lock);
2786 : 0 : return;
2787 : : }
2788 : :
2789 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT,
2790 : : "htt rx start rx ba session sta %pM tid %hu size %hhu\n",
2791 : : peer->addr, tid, ev->window_size);
2792 : :
2793 : 0 : ieee80211_start_rx_ba_session_offl(arvif->vif, peer->addr, tid);
2794 : 0 : spin_unlock_bh(&ar->data_lock);
2795 : : }
2796 : :
2797 : 0 : static void ath10k_htt_rx_delba(struct ath10k *ar, struct htt_resp *resp)
2798 : : {
2799 : 0 : struct htt_rx_delba *ev = &resp->rx_delba;
2800 : 0 : struct ath10k_peer *peer;
2801 : 0 : struct ath10k_vif *arvif;
2802 : 0 : u16 info0, tid, peer_id;
2803 : :
2804 : 0 : info0 = __le16_to_cpu(ev->info0);
2805 : 0 : tid = MS(info0, HTT_RX_BA_INFO0_TID);
2806 : 0 : peer_id = MS(info0, HTT_RX_BA_INFO0_PEER_ID);
2807 : :
2808 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT,
2809 : : "htt rx delba tid %hu peer_id %hu\n",
2810 : : tid, peer_id);
2811 : :
2812 : 0 : spin_lock_bh(&ar->data_lock);
2813 : 0 : peer = ath10k_peer_find_by_id(ar, peer_id);
2814 [ # # ]: 0 : if (!peer) {
2815 : 0 : ath10k_warn(ar, "received addba event for invalid peer_id: %hu\n",
2816 : : peer_id);
2817 : 0 : spin_unlock_bh(&ar->data_lock);
2818 : 0 : return;
2819 : : }
2820 : :
2821 : 0 : arvif = ath10k_get_arvif(ar, peer->vdev_id);
2822 [ # # ]: 0 : if (!arvif) {
2823 : 0 : ath10k_warn(ar, "received addba event for invalid vdev_id: %u\n",
2824 : : peer->vdev_id);
2825 : 0 : spin_unlock_bh(&ar->data_lock);
2826 : 0 : return;
2827 : : }
2828 : :
2829 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT,
2830 : : "htt rx stop rx ba session sta %pM tid %hu\n",
2831 : : peer->addr, tid);
2832 : :
2833 : 0 : ieee80211_stop_rx_ba_session_offl(arvif->vif, peer->addr, tid);
2834 : 0 : spin_unlock_bh(&ar->data_lock);
2835 : : }
2836 : :
2837 : 0 : static int ath10k_htt_rx_extract_amsdu(struct sk_buff_head *list,
2838 : : struct sk_buff_head *amsdu)
2839 : : {
2840 : 0 : struct sk_buff *msdu;
2841 : 0 : struct htt_rx_desc *rxd;
2842 : :
2843 [ # # ]: 0 : if (skb_queue_empty(list))
2844 : : return -ENOBUFS;
2845 : :
2846 [ # # # # ]: 0 : if (WARN_ON(!skb_queue_empty(amsdu)))
2847 : : return -EINVAL;
2848 : :
2849 [ # # # # ]: 0 : while ((msdu = __skb_dequeue(list))) {
2850 [ # # ]: 0 : __skb_queue_tail(amsdu, msdu);
2851 : :
2852 : 0 : rxd = (void *)msdu->data - sizeof(*rxd);
2853 [ # # ]: 0 : if (rxd->msdu_end.common.info0 &
2854 : : __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU))
2855 : : break;
2856 : : }
2857 : :
2858 [ # # ]: 0 : msdu = skb_peek_tail(amsdu);
2859 : 0 : rxd = (void *)msdu->data - sizeof(*rxd);
2860 [ # # ]: 0 : if (!(rxd->msdu_end.common.info0 &
2861 : : __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU))) {
2862 [ # # ]: 0 : skb_queue_splice_init(amsdu, list);
2863 : 0 : return -EAGAIN;
2864 : : }
2865 : :
2866 : : return 0;
2867 : : }
2868 : :
2869 : 0 : static void ath10k_htt_rx_h_rx_offload_prot(struct ieee80211_rx_status *status,
2870 : : struct sk_buff *skb)
2871 : : {
2872 : 0 : struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2873 : :
2874 : 0 : if (!ieee80211_has_protected(hdr->frame_control))
2875 : : return;
2876 : :
2877 : : /* Offloaded frames are already decrypted but firmware insists they are
2878 : : * protected in the 802.11 header. Strip the flag. Otherwise mac80211
2879 : : * will drop the frame.
2880 : : */
2881 : :
2882 : 0 : hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2883 : 0 : status->flag |= RX_FLAG_DECRYPTED |
2884 : : RX_FLAG_IV_STRIPPED |
2885 : : RX_FLAG_MMIC_STRIPPED;
2886 : : }
2887 : :
2888 : 0 : static void ath10k_htt_rx_h_rx_offload(struct ath10k *ar,
2889 : : struct sk_buff_head *list)
2890 : : {
2891 : 0 : struct ath10k_htt *htt = &ar->htt;
2892 : 0 : struct ieee80211_rx_status *status = &htt->rx_status;
2893 : 0 : struct htt_rx_offload_msdu *rx;
2894 : 0 : struct sk_buff *msdu;
2895 : 0 : size_t offset;
2896 : :
2897 [ # # # # ]: 0 : while ((msdu = __skb_dequeue(list))) {
2898 : : /* Offloaded frames don't have Rx descriptor. Instead they have
2899 : : * a short meta information header.
2900 : : */
2901 : :
2902 : 0 : rx = (void *)msdu->data;
2903 : :
2904 : 0 : skb_put(msdu, sizeof(*rx));
2905 : 0 : skb_pull(msdu, sizeof(*rx));
2906 : :
2907 [ # # # # ]: 0 : if (skb_tailroom(msdu) < __le16_to_cpu(rx->msdu_len)) {
2908 : 0 : ath10k_warn(ar, "dropping frame: offloaded rx msdu is too long!\n");
2909 : 0 : dev_kfree_skb_any(msdu);
2910 : 0 : continue;
2911 : : }
2912 : :
2913 : 0 : skb_put(msdu, __le16_to_cpu(rx->msdu_len));
2914 : :
2915 : : /* Offloaded rx header length isn't multiple of 2 nor 4 so the
2916 : : * actual payload is unaligned. Align the frame. Otherwise
2917 : : * mac80211 complains. This shouldn't reduce performance much
2918 : : * because these offloaded frames are rare.
2919 : : */
2920 : 0 : offset = 4 - ((unsigned long)msdu->data & 3);
2921 : 0 : skb_put(msdu, offset);
2922 : 0 : memmove(msdu->data + offset, msdu->data, msdu->len);
2923 : 0 : skb_pull(msdu, offset);
2924 : :
2925 : : /* FIXME: The frame is NWifi. Re-construct QoS Control
2926 : : * if possible later.
2927 : : */
2928 : :
2929 : 0 : memset(status, 0, sizeof(*status));
2930 : 0 : status->flag |= RX_FLAG_NO_SIGNAL_VAL;
2931 : :
2932 [ # # ]: 0 : ath10k_htt_rx_h_rx_offload_prot(status, msdu);
2933 : 0 : ath10k_htt_rx_h_channel(ar, status, NULL, rx->vdev_id);
2934 : 0 : ath10k_htt_rx_h_queue_msdu(ar, status, msdu);
2935 : : }
2936 : 0 : }
2937 : :
2938 : 0 : static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
2939 : : {
2940 : 0 : struct ath10k_htt *htt = &ar->htt;
2941 : 0 : struct htt_resp *resp = (void *)skb->data;
2942 : 0 : struct ieee80211_rx_status *status = &htt->rx_status;
2943 : 0 : struct sk_buff_head list;
2944 : 0 : struct sk_buff_head amsdu;
2945 : 0 : u16 peer_id;
2946 : 0 : u16 msdu_count;
2947 : 0 : u8 vdev_id;
2948 : 0 : u8 tid;
2949 : 0 : bool offload;
2950 : 0 : bool frag;
2951 : 0 : int ret;
2952 : :
2953 : 0 : lockdep_assert_held(&htt->rx_ring.lock);
2954 : :
2955 [ # # ]: 0 : if (htt->rx_confused)
2956 : : return -EIO;
2957 : :
2958 : 0 : skb_pull(skb, sizeof(resp->hdr));
2959 : 0 : skb_pull(skb, sizeof(resp->rx_in_ord_ind));
2960 : :
2961 : 0 : peer_id = __le16_to_cpu(resp->rx_in_ord_ind.peer_id);
2962 : 0 : msdu_count = __le16_to_cpu(resp->rx_in_ord_ind.msdu_count);
2963 : 0 : vdev_id = resp->rx_in_ord_ind.vdev_id;
2964 : 0 : tid = SM(resp->rx_in_ord_ind.info, HTT_RX_IN_ORD_IND_INFO_TID);
2965 : 0 : offload = !!(resp->rx_in_ord_ind.info &
2966 : : HTT_RX_IN_ORD_IND_INFO_OFFLOAD_MASK);
2967 : 0 : frag = !!(resp->rx_in_ord_ind.info & HTT_RX_IN_ORD_IND_INFO_FRAG_MASK);
2968 : :
2969 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT,
2970 : : "htt rx in ord vdev %i peer %i tid %i offload %i frag %i msdu count %i\n",
2971 : : vdev_id, peer_id, tid, offload, frag, msdu_count);
2972 : :
2973 [ # # ]: 0 : if (skb->len < msdu_count * sizeof(*resp->rx_in_ord_ind.msdu_descs32)) {
2974 : 0 : ath10k_warn(ar, "dropping invalid in order rx indication\n");
2975 : 0 : return -EINVAL;
2976 : : }
2977 : :
2978 : : /* The event can deliver more than 1 A-MSDU. Each A-MSDU is later
2979 : : * extracted and processed.
2980 : : */
2981 [ # # ]: 0 : __skb_queue_head_init(&list);
2982 [ # # ]: 0 : if (ar->hw_params.target_64bit)
2983 : 0 : ret = ath10k_htt_rx_pop_paddr64_list(htt, &resp->rx_in_ord_ind,
2984 : : &list);
2985 : : else
2986 : 0 : ret = ath10k_htt_rx_pop_paddr32_list(htt, &resp->rx_in_ord_ind,
2987 : : &list);
2988 : :
2989 [ # # ]: 0 : if (ret < 0) {
2990 : 0 : ath10k_warn(ar, "failed to pop paddr list: %d\n", ret);
2991 : 0 : htt->rx_confused = true;
2992 : 0 : return -EIO;
2993 : : }
2994 : :
2995 : : /* Offloaded frames are very different and need to be handled
2996 : : * separately.
2997 : : */
2998 [ # # ]: 0 : if (offload)
2999 : 0 : ath10k_htt_rx_h_rx_offload(ar, &list);
3000 : :
3001 [ # # ]: 0 : while (!skb_queue_empty(&list)) {
3002 : 0 : __skb_queue_head_init(&amsdu);
3003 : 0 : ret = ath10k_htt_rx_extract_amsdu(&list, &amsdu);
3004 [ # # ]: 0 : switch (ret) {
3005 : 0 : case 0:
3006 : : /* Note: The in-order indication may report interleaved
3007 : : * frames from different PPDUs meaning reported rx rate
3008 : : * to mac80211 isn't accurate/reliable. It's still
3009 : : * better to report something than nothing though. This
3010 : : * should still give an idea about rx rate to the user.
3011 : : */
3012 : 0 : ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id);
3013 : 0 : ath10k_htt_rx_h_filter(ar, &amsdu, status, NULL);
3014 : 0 : ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false, NULL,
3015 : : NULL);
3016 : 0 : ath10k_htt_rx_h_enqueue(ar, &amsdu, status);
3017 : 0 : break;
3018 : 0 : case -EAGAIN:
3019 : : /* fall through */
3020 : : default:
3021 : : /* Should not happen. */
3022 : 0 : ath10k_warn(ar, "failed to extract amsdu: %d\n", ret);
3023 : 0 : htt->rx_confused = true;
3024 : 0 : __skb_queue_purge(&list);
3025 : 0 : return -EIO;
3026 : : }
3027 : : }
3028 : : return ret;
3029 : : }
3030 : :
3031 : 0 : static void ath10k_htt_rx_tx_fetch_resp_id_confirm(struct ath10k *ar,
3032 : : const __le32 *resp_ids,
3033 : : int num_resp_ids)
3034 : : {
3035 : 0 : int i;
3036 : 0 : u32 resp_id;
3037 : :
3038 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx tx fetch confirm num_resp_ids %d\n",
3039 : : num_resp_ids);
3040 : :
3041 [ # # ]: 0 : for (i = 0; i < num_resp_ids; i++) {
3042 : 0 : resp_id = le32_to_cpu(resp_ids[i]);
3043 : :
3044 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx tx fetch confirm resp_id %u\n",
3045 : : resp_id);
3046 : :
3047 : : /* TODO: free resp_id */
3048 : : }
3049 : 0 : }
3050 : :
3051 : : static void ath10k_htt_rx_tx_fetch_ind(struct ath10k *ar, struct sk_buff *skb)
3052 : : {
3053 : : struct ieee80211_hw *hw = ar->hw;
3054 : : struct ieee80211_txq *txq;
3055 : : struct htt_resp *resp = (struct htt_resp *)skb->data;
3056 : : struct htt_tx_fetch_record *record;
3057 : : size_t len;
3058 : : size_t max_num_bytes;
3059 : : size_t max_num_msdus;
3060 : : size_t num_bytes;
3061 : : size_t num_msdus;
3062 : : const __le32 *resp_ids;
3063 : : u16 num_records;
3064 : : u16 num_resp_ids;
3065 : : u16 peer_id;
3066 : : u8 tid;
3067 : : int ret;
3068 : : int i;
3069 : : bool may_tx;
3070 : :
3071 : : ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx tx fetch ind\n");
3072 : :
3073 : : len = sizeof(resp->hdr) + sizeof(resp->tx_fetch_ind);
3074 : : if (unlikely(skb->len < len)) {
3075 : : ath10k_warn(ar, "received corrupted tx_fetch_ind event: buffer too short\n");
3076 : : return;
3077 : : }
3078 : :
3079 : : num_records = le16_to_cpu(resp->tx_fetch_ind.num_records);
3080 : : num_resp_ids = le16_to_cpu(resp->tx_fetch_ind.num_resp_ids);
3081 : :
3082 : : len += sizeof(resp->tx_fetch_ind.records[0]) * num_records;
3083 : : len += sizeof(resp->tx_fetch_ind.resp_ids[0]) * num_resp_ids;
3084 : :
3085 : : if (unlikely(skb->len < len)) {
3086 : : ath10k_warn(ar, "received corrupted tx_fetch_ind event: too many records/resp_ids\n");
3087 : : return;
3088 : : }
3089 : :
3090 : : ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx tx fetch ind num records %hu num resps %hu seq %hu\n",
3091 : : num_records, num_resp_ids,
3092 : : le16_to_cpu(resp->tx_fetch_ind.fetch_seq_num));
3093 : :
3094 : : if (!ar->htt.tx_q_state.enabled) {
3095 : : ath10k_warn(ar, "received unexpected tx_fetch_ind event: not enabled\n");
3096 : : return;
3097 : : }
3098 : :
3099 : : if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH) {
3100 : : ath10k_warn(ar, "received unexpected tx_fetch_ind event: in push mode\n");
3101 : : return;
3102 : : }
3103 : :
3104 : : rcu_read_lock();
3105 : :
3106 : : for (i = 0; i < num_records; i++) {
3107 : : record = &resp->tx_fetch_ind.records[i];
3108 : : peer_id = MS(le16_to_cpu(record->info),
3109 : : HTT_TX_FETCH_RECORD_INFO_PEER_ID);
3110 : : tid = MS(le16_to_cpu(record->info),
3111 : : HTT_TX_FETCH_RECORD_INFO_TID);
3112 : : max_num_msdus = le16_to_cpu(record->num_msdus);
3113 : : max_num_bytes = le32_to_cpu(record->num_bytes);
3114 : :
3115 : : ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx tx fetch record %i peer_id %hu tid %hhu msdus %zu bytes %zu\n",
3116 : : i, peer_id, tid, max_num_msdus, max_num_bytes);
3117 : :
3118 : : if (unlikely(peer_id >= ar->htt.tx_q_state.num_peers) ||
3119 : : unlikely(tid >= ar->htt.tx_q_state.num_tids)) {
3120 : : ath10k_warn(ar, "received out of range peer_id %hu tid %hhu\n",
3121 : : peer_id, tid);
3122 : : continue;
3123 : : }
3124 : :
3125 : : spin_lock_bh(&ar->data_lock);
3126 : : txq = ath10k_mac_txq_lookup(ar, peer_id, tid);
3127 : : spin_unlock_bh(&ar->data_lock);
3128 : :
3129 : : /* It is okay to release the lock and use txq because RCU read
3130 : : * lock is held.
3131 : : */
3132 : :
3133 : : if (unlikely(!txq)) {
3134 : : ath10k_warn(ar, "failed to lookup txq for peer_id %hu tid %hhu\n",
3135 : : peer_id, tid);
3136 : : continue;
3137 : : }
3138 : :
3139 : : num_msdus = 0;
3140 : : num_bytes = 0;
3141 : :
3142 : : ieee80211_txq_schedule_start(hw, txq->ac);
3143 : : may_tx = ieee80211_txq_may_transmit(hw, txq);
3144 : : while (num_msdus < max_num_msdus &&
3145 : : num_bytes < max_num_bytes) {
3146 : : if (!may_tx)
3147 : : break;
3148 : :
3149 : : ret = ath10k_mac_tx_push_txq(hw, txq);
3150 : : if (ret < 0)
3151 : : break;
3152 : :
3153 : : num_msdus++;
3154 : : num_bytes += ret;
3155 : : }
3156 : : ieee80211_return_txq(hw, txq, false);
3157 : : ieee80211_txq_schedule_end(hw, txq->ac);
3158 : :
3159 : : record->num_msdus = cpu_to_le16(num_msdus);
3160 : : record->num_bytes = cpu_to_le32(num_bytes);
3161 : :
3162 : : ath10k_htt_tx_txq_recalc(hw, txq);
3163 : : }
3164 : :
3165 : : rcu_read_unlock();
3166 : :
3167 : : resp_ids = ath10k_htt_get_tx_fetch_ind_resp_ids(&resp->tx_fetch_ind);
3168 : : ath10k_htt_rx_tx_fetch_resp_id_confirm(ar, resp_ids, num_resp_ids);
3169 : :
3170 : : ret = ath10k_htt_tx_fetch_resp(ar,
3171 : : resp->tx_fetch_ind.token,
3172 : : resp->tx_fetch_ind.fetch_seq_num,
3173 : : resp->tx_fetch_ind.records,
3174 : : num_records);
3175 : : if (unlikely(ret)) {
3176 : : ath10k_warn(ar, "failed to submit tx fetch resp for token 0x%08x: %d\n",
3177 : : le32_to_cpu(resp->tx_fetch_ind.token), ret);
3178 : : /* FIXME: request fw restart */
3179 : : }
3180 : :
3181 : : ath10k_htt_tx_txq_sync(ar);
3182 : : }
3183 : :
3184 : : static void ath10k_htt_rx_tx_fetch_confirm(struct ath10k *ar,
3185 : : struct sk_buff *skb)
3186 : : {
3187 : : const struct htt_resp *resp = (void *)skb->data;
3188 : : size_t len;
3189 : : int num_resp_ids;
3190 : :
3191 : : ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx tx fetch confirm\n");
3192 : :
3193 : : len = sizeof(resp->hdr) + sizeof(resp->tx_fetch_confirm);
3194 : : if (unlikely(skb->len < len)) {
3195 : : ath10k_warn(ar, "received corrupted tx_fetch_confirm event: buffer too short\n");
3196 : : return;
3197 : : }
3198 : :
3199 : : num_resp_ids = le16_to_cpu(resp->tx_fetch_confirm.num_resp_ids);
3200 : : len += sizeof(resp->tx_fetch_confirm.resp_ids[0]) * num_resp_ids;
3201 : :
3202 : : if (unlikely(skb->len < len)) {
3203 : : ath10k_warn(ar, "received corrupted tx_fetch_confirm event: resp_ids buffer overflow\n");
3204 : : return;
3205 : : }
3206 : :
3207 : : ath10k_htt_rx_tx_fetch_resp_id_confirm(ar,
3208 : : resp->tx_fetch_confirm.resp_ids,
3209 : : num_resp_ids);
3210 : : }
3211 : :
3212 : : static void ath10k_htt_rx_tx_mode_switch_ind(struct ath10k *ar,
3213 : : struct sk_buff *skb)
3214 : : {
3215 : : const struct htt_resp *resp = (void *)skb->data;
3216 : : const struct htt_tx_mode_switch_record *record;
3217 : : struct ieee80211_txq *txq;
3218 : : struct ath10k_txq *artxq;
3219 : : size_t len;
3220 : : size_t num_records;
3221 : : enum htt_tx_mode_switch_mode mode;
3222 : : bool enable;
3223 : : u16 info0;
3224 : : u16 info1;
3225 : : u16 threshold;
3226 : : u16 peer_id;
3227 : : u8 tid;
3228 : : int i;
3229 : :
3230 : : ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx tx mode switch ind\n");
3231 : :
3232 : : len = sizeof(resp->hdr) + sizeof(resp->tx_mode_switch_ind);
3233 : : if (unlikely(skb->len < len)) {
3234 : : ath10k_warn(ar, "received corrupted tx_mode_switch_ind event: buffer too short\n");
3235 : : return;
3236 : : }
3237 : :
3238 : : info0 = le16_to_cpu(resp->tx_mode_switch_ind.info0);
3239 : : info1 = le16_to_cpu(resp->tx_mode_switch_ind.info1);
3240 : :
3241 : : enable = !!(info0 & HTT_TX_MODE_SWITCH_IND_INFO0_ENABLE);
3242 : : num_records = MS(info0, HTT_TX_MODE_SWITCH_IND_INFO1_THRESHOLD);
3243 : : mode = MS(info1, HTT_TX_MODE_SWITCH_IND_INFO1_MODE);
3244 : : threshold = MS(info1, HTT_TX_MODE_SWITCH_IND_INFO1_THRESHOLD);
3245 : :
3246 : : ath10k_dbg(ar, ATH10K_DBG_HTT,
3247 : : "htt rx tx mode switch ind info0 0x%04hx info1 0x%04hx enable %d num records %zd mode %d threshold %hu\n",
3248 : : info0, info1, enable, num_records, mode, threshold);
3249 : :
3250 : : len += sizeof(resp->tx_mode_switch_ind.records[0]) * num_records;
3251 : :
3252 : : if (unlikely(skb->len < len)) {
3253 : : ath10k_warn(ar, "received corrupted tx_mode_switch_mode_ind event: too many records\n");
3254 : : return;
3255 : : }
3256 : :
3257 : : switch (mode) {
3258 : : case HTT_TX_MODE_SWITCH_PUSH:
3259 : : case HTT_TX_MODE_SWITCH_PUSH_PULL:
3260 : : break;
3261 : : default:
3262 : : ath10k_warn(ar, "received invalid tx_mode_switch_mode_ind mode %d, ignoring\n",
3263 : : mode);
3264 : : return;
3265 : : }
3266 : :
3267 : : if (!enable)
3268 : : return;
3269 : :
3270 : : ar->htt.tx_q_state.enabled = enable;
3271 : : ar->htt.tx_q_state.mode = mode;
3272 : : ar->htt.tx_q_state.num_push_allowed = threshold;
3273 : :
3274 : : rcu_read_lock();
3275 : :
3276 : : for (i = 0; i < num_records; i++) {
3277 : : record = &resp->tx_mode_switch_ind.records[i];
3278 : : info0 = le16_to_cpu(record->info0);
3279 : : peer_id = MS(info0, HTT_TX_MODE_SWITCH_RECORD_INFO0_PEER_ID);
3280 : : tid = MS(info0, HTT_TX_MODE_SWITCH_RECORD_INFO0_TID);
3281 : :
3282 : : if (unlikely(peer_id >= ar->htt.tx_q_state.num_peers) ||
3283 : : unlikely(tid >= ar->htt.tx_q_state.num_tids)) {
3284 : : ath10k_warn(ar, "received out of range peer_id %hu tid %hhu\n",
3285 : : peer_id, tid);
3286 : : continue;
3287 : : }
3288 : :
3289 : : spin_lock_bh(&ar->data_lock);
3290 : : txq = ath10k_mac_txq_lookup(ar, peer_id, tid);
3291 : : spin_unlock_bh(&ar->data_lock);
3292 : :
3293 : : /* It is okay to release the lock and use txq because RCU read
3294 : : * lock is held.
3295 : : */
3296 : :
3297 : : if (unlikely(!txq)) {
3298 : : ath10k_warn(ar, "failed to lookup txq for peer_id %hu tid %hhu\n",
3299 : : peer_id, tid);
3300 : : continue;
3301 : : }
3302 : :
3303 : : spin_lock_bh(&ar->htt.tx_lock);
3304 : : artxq = (void *)txq->drv_priv;
3305 : : artxq->num_push_allowed = le16_to_cpu(record->num_max_msdus);
3306 : : spin_unlock_bh(&ar->htt.tx_lock);
3307 : : }
3308 : :
3309 : : rcu_read_unlock();
3310 : :
3311 : : ath10k_mac_tx_push_pending(ar);
3312 : : }
3313 : :
3314 : 0 : void ath10k_htt_htc_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
3315 : : {
3316 : 0 : bool release;
3317 : :
3318 : 0 : release = ath10k_htt_t2h_msg_handler(ar, skb);
3319 : :
3320 : : /* Free the indication buffer */
3321 [ # # ]: 0 : if (release)
3322 : 0 : dev_kfree_skb_any(skb);
3323 : 0 : }
3324 : :
3325 : 0 : static inline s8 ath10k_get_legacy_rate_idx(struct ath10k *ar, u8 rate)
3326 : : {
3327 : 0 : static const u8 legacy_rates[] = {1, 2, 5, 11, 6, 9, 12,
3328 : : 18, 24, 36, 48, 54};
3329 : 0 : int i;
3330 : :
3331 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(legacy_rates); i++) {
3332 [ # # ]: 0 : if (rate == legacy_rates[i])
3333 : 0 : return i;
3334 : : }
3335 : :
3336 : 0 : ath10k_warn(ar, "Invalid legacy rate %hhd peer stats", rate);
3337 : 0 : return -EINVAL;
3338 : : }
3339 : :
3340 : : static void
3341 : 0 : ath10k_accumulate_per_peer_tx_stats(struct ath10k *ar,
3342 : : struct ath10k_sta *arsta,
3343 : : struct ath10k_per_peer_tx_stats *pstats,
3344 : : s8 legacy_rate_idx)
3345 : : {
3346 : 0 : struct rate_info *txrate = &arsta->txrate;
3347 : 0 : struct ath10k_htt_tx_stats *tx_stats;
3348 : 0 : int idx, ht_idx, gi, mcs, bw, nss;
3349 : 0 : unsigned long flags;
3350 : :
3351 [ # # ]: 0 : if (!arsta->tx_stats)
3352 : 0 : return;
3353 : :
3354 : 0 : tx_stats = arsta->tx_stats;
3355 : 0 : flags = txrate->flags;
3356 : 0 : gi = test_bit(ATH10K_RATE_INFO_FLAGS_SGI_BIT, &flags);
3357 : 0 : mcs = ATH10K_HW_MCS_RATE(pstats->ratecode);
3358 : 0 : bw = txrate->bw;
3359 : 0 : nss = txrate->nss;
3360 : 0 : ht_idx = mcs + (nss - 1) * 8;
3361 : 0 : idx = mcs * 8 + 8 * 10 * (nss - 1);
3362 : 0 : idx += bw * 2 + gi;
3363 : :
3364 : : #define STATS_OP_FMT(name) tx_stats->stats[ATH10K_STATS_TYPE_##name]
3365 : :
3366 [ # # ]: 0 : if (txrate->flags & RATE_INFO_FLAGS_VHT_MCS) {
3367 : 0 : STATS_OP_FMT(SUCC).vht[0][mcs] += pstats->succ_bytes;
3368 : 0 : STATS_OP_FMT(SUCC).vht[1][mcs] += pstats->succ_pkts;
3369 : 0 : STATS_OP_FMT(FAIL).vht[0][mcs] += pstats->failed_bytes;
3370 : 0 : STATS_OP_FMT(FAIL).vht[1][mcs] += pstats->failed_pkts;
3371 : 0 : STATS_OP_FMT(RETRY).vht[0][mcs] += pstats->retry_bytes;
3372 : 0 : STATS_OP_FMT(RETRY).vht[1][mcs] += pstats->retry_pkts;
3373 [ # # ]: 0 : } else if (txrate->flags & RATE_INFO_FLAGS_MCS) {
3374 : 0 : STATS_OP_FMT(SUCC).ht[0][ht_idx] += pstats->succ_bytes;
3375 : 0 : STATS_OP_FMT(SUCC).ht[1][ht_idx] += pstats->succ_pkts;
3376 : 0 : STATS_OP_FMT(FAIL).ht[0][ht_idx] += pstats->failed_bytes;
3377 : 0 : STATS_OP_FMT(FAIL).ht[1][ht_idx] += pstats->failed_pkts;
3378 : 0 : STATS_OP_FMT(RETRY).ht[0][ht_idx] += pstats->retry_bytes;
3379 : 0 : STATS_OP_FMT(RETRY).ht[1][ht_idx] += pstats->retry_pkts;
3380 : : } else {
3381 : 0 : mcs = legacy_rate_idx;
3382 : :
3383 : 0 : STATS_OP_FMT(SUCC).legacy[0][mcs] += pstats->succ_bytes;
3384 : 0 : STATS_OP_FMT(SUCC).legacy[1][mcs] += pstats->succ_pkts;
3385 : 0 : STATS_OP_FMT(FAIL).legacy[0][mcs] += pstats->failed_bytes;
3386 : 0 : STATS_OP_FMT(FAIL).legacy[1][mcs] += pstats->failed_pkts;
3387 : 0 : STATS_OP_FMT(RETRY).legacy[0][mcs] += pstats->retry_bytes;
3388 : 0 : STATS_OP_FMT(RETRY).legacy[1][mcs] += pstats->retry_pkts;
3389 : : }
3390 : :
3391 [ # # ]: 0 : if (ATH10K_HW_AMPDU(pstats->flags)) {
3392 : 0 : tx_stats->ba_fails += ATH10K_HW_BA_FAIL(pstats->flags);
3393 : :
3394 [ # # ]: 0 : if (txrate->flags & RATE_INFO_FLAGS_MCS) {
3395 : 0 : STATS_OP_FMT(AMPDU).ht[0][ht_idx] +=
3396 : 0 : pstats->succ_bytes + pstats->retry_bytes;
3397 : 0 : STATS_OP_FMT(AMPDU).ht[1][ht_idx] +=
3398 : 0 : pstats->succ_pkts + pstats->retry_pkts;
3399 : : } else {
3400 : 0 : STATS_OP_FMT(AMPDU).vht[0][mcs] +=
3401 : 0 : pstats->succ_bytes + pstats->retry_bytes;
3402 : 0 : STATS_OP_FMT(AMPDU).vht[1][mcs] +=
3403 : 0 : pstats->succ_pkts + pstats->retry_pkts;
3404 : : }
3405 : 0 : STATS_OP_FMT(AMPDU).bw[0][bw] +=
3406 : 0 : pstats->succ_bytes + pstats->retry_bytes;
3407 : 0 : STATS_OP_FMT(AMPDU).nss[0][nss - 1] +=
3408 : 0 : pstats->succ_bytes + pstats->retry_bytes;
3409 : 0 : STATS_OP_FMT(AMPDU).gi[0][gi] +=
3410 : 0 : pstats->succ_bytes + pstats->retry_bytes;
3411 : 0 : STATS_OP_FMT(AMPDU).rate_table[0][idx] +=
3412 : 0 : pstats->succ_bytes + pstats->retry_bytes;
3413 : 0 : STATS_OP_FMT(AMPDU).bw[1][bw] +=
3414 : 0 : pstats->succ_pkts + pstats->retry_pkts;
3415 : 0 : STATS_OP_FMT(AMPDU).nss[1][nss - 1] +=
3416 : 0 : pstats->succ_pkts + pstats->retry_pkts;
3417 : 0 : STATS_OP_FMT(AMPDU).gi[1][gi] +=
3418 : 0 : pstats->succ_pkts + pstats->retry_pkts;
3419 : 0 : STATS_OP_FMT(AMPDU).rate_table[1][idx] +=
3420 : 0 : pstats->succ_pkts + pstats->retry_pkts;
3421 : : } else {
3422 : 0 : tx_stats->ack_fails +=
3423 : 0 : ATH10K_HW_BA_FAIL(pstats->flags);
3424 : : }
3425 : :
3426 : 0 : STATS_OP_FMT(SUCC).bw[0][bw] += pstats->succ_bytes;
3427 : 0 : STATS_OP_FMT(SUCC).nss[0][nss - 1] += pstats->succ_bytes;
3428 : 0 : STATS_OP_FMT(SUCC).gi[0][gi] += pstats->succ_bytes;
3429 : :
3430 : 0 : STATS_OP_FMT(SUCC).bw[1][bw] += pstats->succ_pkts;
3431 : 0 : STATS_OP_FMT(SUCC).nss[1][nss - 1] += pstats->succ_pkts;
3432 : 0 : STATS_OP_FMT(SUCC).gi[1][gi] += pstats->succ_pkts;
3433 : :
3434 : 0 : STATS_OP_FMT(FAIL).bw[0][bw] += pstats->failed_bytes;
3435 : 0 : STATS_OP_FMT(FAIL).nss[0][nss - 1] += pstats->failed_bytes;
3436 : 0 : STATS_OP_FMT(FAIL).gi[0][gi] += pstats->failed_bytes;
3437 : :
3438 : 0 : STATS_OP_FMT(FAIL).bw[1][bw] += pstats->failed_pkts;
3439 : 0 : STATS_OP_FMT(FAIL).nss[1][nss - 1] += pstats->failed_pkts;
3440 : 0 : STATS_OP_FMT(FAIL).gi[1][gi] += pstats->failed_pkts;
3441 : :
3442 : 0 : STATS_OP_FMT(RETRY).bw[0][bw] += pstats->retry_bytes;
3443 : 0 : STATS_OP_FMT(RETRY).nss[0][nss - 1] += pstats->retry_bytes;
3444 : 0 : STATS_OP_FMT(RETRY).gi[0][gi] += pstats->retry_bytes;
3445 : :
3446 : 0 : STATS_OP_FMT(RETRY).bw[1][bw] += pstats->retry_pkts;
3447 : 0 : STATS_OP_FMT(RETRY).nss[1][nss - 1] += pstats->retry_pkts;
3448 : 0 : STATS_OP_FMT(RETRY).gi[1][gi] += pstats->retry_pkts;
3449 : :
3450 [ # # ]: 0 : if (txrate->flags >= RATE_INFO_FLAGS_MCS) {
3451 : 0 : STATS_OP_FMT(SUCC).rate_table[0][idx] += pstats->succ_bytes;
3452 : 0 : STATS_OP_FMT(SUCC).rate_table[1][idx] += pstats->succ_pkts;
3453 : 0 : STATS_OP_FMT(FAIL).rate_table[0][idx] += pstats->failed_bytes;
3454 : 0 : STATS_OP_FMT(FAIL).rate_table[1][idx] += pstats->failed_pkts;
3455 : 0 : STATS_OP_FMT(RETRY).rate_table[0][idx] += pstats->retry_bytes;
3456 : 0 : STATS_OP_FMT(RETRY).rate_table[1][idx] += pstats->retry_pkts;
3457 : : }
3458 : :
3459 : 0 : tx_stats->tx_duration += pstats->duration;
3460 : : }
3461 : :
3462 : : static void
3463 : 0 : ath10k_update_per_peer_tx_stats(struct ath10k *ar,
3464 : : struct ieee80211_sta *sta,
3465 : : struct ath10k_per_peer_tx_stats *peer_stats)
3466 : : {
3467 : 0 : struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
3468 : 0 : struct ieee80211_chanctx_conf *conf = NULL;
3469 : 0 : u8 rate = 0, sgi;
3470 : 0 : s8 rate_idx = 0;
3471 : 0 : bool skip_auto_rate;
3472 : 0 : struct rate_info txrate;
3473 : :
3474 : 0 : lockdep_assert_held(&ar->data_lock);
3475 : :
3476 : 0 : txrate.flags = ATH10K_HW_PREAMBLE(peer_stats->ratecode);
3477 : 0 : txrate.bw = ATH10K_HW_BW(peer_stats->flags);
3478 : 0 : txrate.nss = ATH10K_HW_NSS(peer_stats->ratecode);
3479 : 0 : txrate.mcs = ATH10K_HW_MCS_RATE(peer_stats->ratecode);
3480 : 0 : sgi = ATH10K_HW_GI(peer_stats->flags);
3481 : 0 : skip_auto_rate = ATH10K_FW_SKIPPED_RATE_CTRL(peer_stats->flags);
3482 : :
3483 : : /* Firmware's rate control skips broadcast/management frames,
3484 : : * if host has configure fixed rates and in some other special cases.
3485 : : */
3486 [ # # ]: 0 : if (skip_auto_rate)
3487 : : return;
3488 : :
3489 [ # # # # ]: 0 : if (txrate.flags == WMI_RATE_PREAMBLE_VHT && txrate.mcs > 9) {
3490 : 0 : ath10k_warn(ar, "Invalid VHT mcs %hhd peer stats", txrate.mcs);
3491 : 0 : return;
3492 : : }
3493 : :
3494 [ # # # # ]: 0 : if (txrate.flags == WMI_RATE_PREAMBLE_HT &&
3495 : : (txrate.mcs > 7 || txrate.nss < 1)) {
3496 : 0 : ath10k_warn(ar, "Invalid HT mcs %hhd nss %hhd peer stats",
3497 : : txrate.mcs, txrate.nss);
3498 : 0 : return;
3499 : : }
3500 : :
3501 : 0 : memset(&arsta->txrate, 0, sizeof(arsta->txrate));
3502 : 0 : memset(&arsta->tx_info.status, 0, sizeof(arsta->tx_info.status));
3503 [ # # ]: 0 : if (txrate.flags == WMI_RATE_PREAMBLE_CCK ||
3504 : : txrate.flags == WMI_RATE_PREAMBLE_OFDM) {
3505 : 0 : rate = ATH10K_HW_LEGACY_RATE(peer_stats->ratecode);
3506 : : /* This is hacky, FW sends CCK rate 5.5Mbps as 6 */
3507 [ # # # # ]: 0 : if (rate == 6 && txrate.flags == WMI_RATE_PREAMBLE_CCK)
3508 : 0 : rate = 5;
3509 : 0 : rate_idx = ath10k_get_legacy_rate_idx(ar, rate);
3510 : 0 : if (rate_idx < 0)
3511 : 0 : return;
3512 : 0 : arsta->txrate.legacy = rate;
3513 [ # # ]: 0 : } else if (txrate.flags == WMI_RATE_PREAMBLE_HT) {
3514 : 0 : arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
3515 : 0 : arsta->txrate.mcs = txrate.mcs + 8 * (txrate.nss - 1);
3516 : : } else {
3517 : 0 : arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
3518 : 0 : arsta->txrate.mcs = txrate.mcs;
3519 : : }
3520 : :
3521 [ # # # # ]: 0 : switch (txrate.flags) {
3522 : 0 : case WMI_RATE_PREAMBLE_OFDM:
3523 [ # # # # ]: 0 : if (arsta->arvif && arsta->arvif->vif)
3524 [ # # ]: 0 : conf = rcu_dereference(arsta->arvif->vif->chanctx_conf);
3525 [ # # # # ]: 0 : if (conf && conf->def.chan->band == NL80211_BAND_5GHZ)
3526 : 0 : arsta->tx_info.status.rates[0].idx = rate_idx - 4;
3527 : : break;
3528 : 0 : case WMI_RATE_PREAMBLE_CCK:
3529 : 0 : arsta->tx_info.status.rates[0].idx = rate_idx;
3530 [ # # ]: 0 : if (sgi)
3531 : 0 : arsta->tx_info.status.rates[0].flags |=
3532 : : (IEEE80211_TX_RC_USE_SHORT_PREAMBLE |
3533 : : IEEE80211_TX_RC_SHORT_GI);
3534 : : break;
3535 : 0 : case WMI_RATE_PREAMBLE_HT:
3536 : 0 : arsta->tx_info.status.rates[0].idx =
3537 : 0 : txrate.mcs + ((txrate.nss - 1) * 8);
3538 [ # # ]: 0 : if (sgi)
3539 : 0 : arsta->tx_info.status.rates[0].flags |=
3540 : : IEEE80211_TX_RC_SHORT_GI;
3541 : 0 : arsta->tx_info.status.rates[0].flags |= IEEE80211_TX_RC_MCS;
3542 : 0 : break;
3543 : 0 : case WMI_RATE_PREAMBLE_VHT:
3544 : 0 : ieee80211_rate_set_vht(&arsta->tx_info.status.rates[0],
3545 : : txrate.mcs, txrate.nss);
3546 [ # # ]: 0 : if (sgi)
3547 : 0 : arsta->tx_info.status.rates[0].flags |=
3548 : : IEEE80211_TX_RC_SHORT_GI;
3549 : 0 : arsta->tx_info.status.rates[0].flags |= IEEE80211_TX_RC_VHT_MCS;
3550 : 0 : break;
3551 : : }
3552 : :
3553 : 0 : arsta->txrate.nss = txrate.nss;
3554 [ # # ]: 0 : arsta->txrate.bw = ath10k_bw_to_mac80211_bw(txrate.bw);
3555 : 0 : arsta->last_tx_bitrate = cfg80211_calculate_bitrate(&arsta->txrate);
3556 [ # # ]: 0 : if (sgi)
3557 : 0 : arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
3558 : :
3559 [ # # # ]: 0 : switch (arsta->txrate.bw) {
3560 : 0 : case RATE_INFO_BW_40:
3561 : 0 : arsta->tx_info.status.rates[0].flags |=
3562 : : IEEE80211_TX_RC_40_MHZ_WIDTH;
3563 : 0 : break;
3564 : 0 : case RATE_INFO_BW_80:
3565 : 0 : arsta->tx_info.status.rates[0].flags |=
3566 : : IEEE80211_TX_RC_80_MHZ_WIDTH;
3567 : 0 : break;
3568 : : }
3569 : :
3570 [ # # ]: 0 : if (peer_stats->succ_pkts) {
3571 : 0 : arsta->tx_info.flags = IEEE80211_TX_STAT_ACK;
3572 : 0 : arsta->tx_info.status.rates[0].count = 1;
3573 : 0 : ieee80211_tx_rate_update(ar->hw, sta, &arsta->tx_info);
3574 : : }
3575 : :
3576 [ # # ]: 0 : if (ath10k_debug_is_extd_tx_stats_enabled(ar))
3577 : 0 : ath10k_accumulate_per_peer_tx_stats(ar, arsta, peer_stats,
3578 : : rate_idx);
3579 : : }
3580 : :
3581 : : static void ath10k_htt_fetch_peer_stats(struct ath10k *ar,
3582 : : struct sk_buff *skb)
3583 : : {
3584 : : struct htt_resp *resp = (struct htt_resp *)skb->data;
3585 : : struct ath10k_per_peer_tx_stats *p_tx_stats = &ar->peer_tx_stats;
3586 : : struct htt_per_peer_tx_stats_ind *tx_stats;
3587 : : struct ieee80211_sta *sta;
3588 : : struct ath10k_peer *peer;
3589 : : int peer_id, i;
3590 : : u8 ppdu_len, num_ppdu;
3591 : :
3592 : : num_ppdu = resp->peer_tx_stats.num_ppdu;
3593 : : ppdu_len = resp->peer_tx_stats.ppdu_len * sizeof(__le32);
3594 : :
3595 : : if (skb->len < sizeof(struct htt_resp_hdr) + num_ppdu * ppdu_len) {
3596 : : ath10k_warn(ar, "Invalid peer stats buf length %d\n", skb->len);
3597 : : return;
3598 : : }
3599 : :
3600 : : tx_stats = (struct htt_per_peer_tx_stats_ind *)
3601 : : (resp->peer_tx_stats.payload);
3602 : : peer_id = __le16_to_cpu(tx_stats->peer_id);
3603 : :
3604 : : rcu_read_lock();
3605 : : spin_lock_bh(&ar->data_lock);
3606 : : peer = ath10k_peer_find_by_id(ar, peer_id);
3607 : : if (!peer || !peer->sta) {
3608 : : ath10k_warn(ar, "Invalid peer id %d peer stats buffer\n",
3609 : : peer_id);
3610 : : goto out;
3611 : : }
3612 : :
3613 : : sta = peer->sta;
3614 : : for (i = 0; i < num_ppdu; i++) {
3615 : : tx_stats = (struct htt_per_peer_tx_stats_ind *)
3616 : : (resp->peer_tx_stats.payload + i * ppdu_len);
3617 : :
3618 : : p_tx_stats->succ_bytes = __le32_to_cpu(tx_stats->succ_bytes);
3619 : : p_tx_stats->retry_bytes = __le32_to_cpu(tx_stats->retry_bytes);
3620 : : p_tx_stats->failed_bytes =
3621 : : __le32_to_cpu(tx_stats->failed_bytes);
3622 : : p_tx_stats->ratecode = tx_stats->ratecode;
3623 : : p_tx_stats->flags = tx_stats->flags;
3624 : : p_tx_stats->succ_pkts = __le16_to_cpu(tx_stats->succ_pkts);
3625 : : p_tx_stats->retry_pkts = __le16_to_cpu(tx_stats->retry_pkts);
3626 : : p_tx_stats->failed_pkts = __le16_to_cpu(tx_stats->failed_pkts);
3627 : : p_tx_stats->duration = __le16_to_cpu(tx_stats->tx_duration);
3628 : :
3629 : : ath10k_update_per_peer_tx_stats(ar, sta, p_tx_stats);
3630 : : }
3631 : :
3632 : : out:
3633 : : spin_unlock_bh(&ar->data_lock);
3634 : : rcu_read_unlock();
3635 : : }
3636 : :
3637 : 0 : static void ath10k_fetch_10_2_tx_stats(struct ath10k *ar, u8 *data)
3638 : : {
3639 : 0 : struct ath10k_pktlog_hdr *hdr = (struct ath10k_pktlog_hdr *)data;
3640 : 0 : struct ath10k_per_peer_tx_stats *p_tx_stats = &ar->peer_tx_stats;
3641 : 0 : struct ath10k_10_2_peer_tx_stats *tx_stats;
3642 : 0 : struct ieee80211_sta *sta;
3643 : 0 : struct ath10k_peer *peer;
3644 : 0 : u16 log_type = __le16_to_cpu(hdr->log_type);
3645 : 0 : u32 peer_id = 0, i;
3646 : :
3647 [ # # ]: 0 : if (log_type != ATH_PKTLOG_TYPE_TX_STAT)
3648 : : return;
3649 : :
3650 : 0 : tx_stats = (struct ath10k_10_2_peer_tx_stats *)((hdr->payload) +
3651 : : ATH10K_10_2_TX_STATS_OFFSET);
3652 : :
3653 [ # # ]: 0 : if (!tx_stats->tx_ppdu_cnt)
3654 : : return;
3655 : :
3656 : 0 : peer_id = tx_stats->peer_id;
3657 : :
3658 : 0 : rcu_read_lock();
3659 : 0 : spin_lock_bh(&ar->data_lock);
3660 : 0 : peer = ath10k_peer_find_by_id(ar, peer_id);
3661 [ # # # # ]: 0 : if (!peer || !peer->sta) {
3662 : 0 : ath10k_warn(ar, "Invalid peer id %d in peer stats buffer\n",
3663 : : peer_id);
3664 : 0 : goto out;
3665 : : }
3666 : :
3667 : : sta = peer->sta;
3668 [ # # ]: 0 : for (i = 0; i < tx_stats->tx_ppdu_cnt; i++) {
3669 : 0 : p_tx_stats->succ_bytes =
3670 : 0 : __le16_to_cpu(tx_stats->success_bytes[i]);
3671 : 0 : p_tx_stats->retry_bytes =
3672 : 0 : __le16_to_cpu(tx_stats->retry_bytes[i]);
3673 : 0 : p_tx_stats->failed_bytes =
3674 : 0 : __le16_to_cpu(tx_stats->failed_bytes[i]);
3675 : 0 : p_tx_stats->ratecode = tx_stats->ratecode[i];
3676 : 0 : p_tx_stats->flags = tx_stats->flags[i];
3677 : 0 : p_tx_stats->succ_pkts = tx_stats->success_pkts[i];
3678 : 0 : p_tx_stats->retry_pkts = tx_stats->retry_pkts[i];
3679 : 0 : p_tx_stats->failed_pkts = tx_stats->failed_pkts[i];
3680 : :
3681 : 0 : ath10k_update_per_peer_tx_stats(ar, sta, p_tx_stats);
3682 : : }
3683 : 0 : spin_unlock_bh(&ar->data_lock);
3684 : 0 : rcu_read_unlock();
3685 : :
3686 : : return;
3687 : :
3688 : : out:
3689 : 0 : spin_unlock_bh(&ar->data_lock);
3690 : 0 : rcu_read_unlock();
3691 : : }
3692 : :
3693 : 0 : static int ath10k_htt_rx_pn_len(enum htt_security_types sec_type)
3694 : : {
3695 : 0 : switch (sec_type) {
3696 : : case HTT_SECURITY_TKIP:
3697 : : case HTT_SECURITY_TKIP_NOMIC:
3698 : : case HTT_SECURITY_AES_CCMP:
3699 : : return 48;
3700 : 0 : default:
3701 : 0 : return 0;
3702 : : }
3703 : : }
3704 : :
3705 : 0 : static void ath10k_htt_rx_sec_ind_handler(struct ath10k *ar,
3706 : : struct htt_security_indication *ev)
3707 : : {
3708 : 0 : enum htt_txrx_sec_cast_type sec_index;
3709 : 0 : enum htt_security_types sec_type;
3710 : 0 : struct ath10k_peer *peer;
3711 : :
3712 : 0 : spin_lock_bh(&ar->data_lock);
3713 : :
3714 : 0 : peer = ath10k_peer_find_by_id(ar, __le16_to_cpu(ev->peer_id));
3715 [ # # ]: 0 : if (!peer) {
3716 : 0 : ath10k_warn(ar, "failed to find peer id %d for security indication",
3717 : 0 : __le16_to_cpu(ev->peer_id));
3718 : 0 : goto out;
3719 : : }
3720 : :
3721 : 0 : sec_type = MS(ev->flags, HTT_SECURITY_TYPE);
3722 : :
3723 [ # # ]: 0 : if (ev->flags & HTT_SECURITY_IS_UNICAST)
3724 : : sec_index = HTT_TXRX_SEC_UCAST;
3725 : : else
3726 : 0 : sec_index = HTT_TXRX_SEC_MCAST;
3727 : :
3728 : 0 : peer->rx_pn[sec_index].sec_type = sec_type;
3729 [ # # ]: 0 : peer->rx_pn[sec_index].pn_len = ath10k_htt_rx_pn_len(sec_type);
3730 : :
3731 : 0 : memset(peer->tids_last_pn_valid, 0, sizeof(peer->tids_last_pn_valid));
3732 : 0 : memset(peer->tids_last_pn, 0, sizeof(peer->tids_last_pn));
3733 : :
3734 : 0 : out:
3735 : 0 : spin_unlock_bh(&ar->data_lock);
3736 : 0 : }
3737 : :
3738 : 0 : bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
3739 : : {
3740 : 0 : struct ath10k_htt *htt = &ar->htt;
3741 : 0 : struct htt_resp *resp = (struct htt_resp *)skb->data;
3742 : 0 : enum htt_t2h_msg_type type;
3743 : :
3744 : : /* confirm alignment */
3745 [ # # ]: 0 : if (!IS_ALIGNED((unsigned long)skb->data, 4))
3746 : 0 : ath10k_warn(ar, "unaligned htt message, expect trouble\n");
3747 : :
3748 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx, msg_type: 0x%0X\n",
3749 : : resp->hdr.msg_type);
3750 : :
3751 [ # # ]: 0 : if (resp->hdr.msg_type >= ar->htt.t2h_msg_types_max) {
3752 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx, unsupported msg_type: 0x%0X\n max: 0x%0X",
3753 : : resp->hdr.msg_type, ar->htt.t2h_msg_types_max);
3754 : 0 : return true;
3755 : : }
3756 : 0 : type = ar->htt.t2h_msg_types[resp->hdr.msg_type];
3757 : :
3758 [ # # # # : 0 : switch (type) {
# # # # #
# # # # #
# # # # #
# # ]
3759 : 0 : case HTT_T2H_MSG_TYPE_VERSION_CONF: {
3760 : 0 : htt->target_version_major = resp->ver_resp.major;
3761 : 0 : htt->target_version_minor = resp->ver_resp.minor;
3762 : 0 : complete(&htt->target_version_received);
3763 : 0 : break;
3764 : : }
3765 : 0 : case HTT_T2H_MSG_TYPE_RX_IND:
3766 [ # # ]: 0 : if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL) {
3767 : 0 : ath10k_htt_rx_proc_rx_ind_ll(htt, &resp->rx_ind);
3768 : : } else {
3769 : 0 : skb_queue_tail(&htt->rx_indication_head, skb);
3770 : 0 : return false;
3771 : : }
3772 : 0 : break;
3773 : 0 : case HTT_T2H_MSG_TYPE_PEER_MAP: {
3774 : 0 : struct htt_peer_map_event ev = {
3775 : 0 : .vdev_id = resp->peer_map.vdev_id,
3776 : 0 : .peer_id = __le16_to_cpu(resp->peer_map.peer_id),
3777 : : };
3778 : 0 : memcpy(ev.addr, resp->peer_map.addr, sizeof(ev.addr));
3779 : 0 : ath10k_peer_map_event(htt, &ev);
3780 : 0 : break;
3781 : : }
3782 : 0 : case HTT_T2H_MSG_TYPE_PEER_UNMAP: {
3783 : 0 : struct htt_peer_unmap_event ev = {
3784 : 0 : .peer_id = __le16_to_cpu(resp->peer_unmap.peer_id),
3785 : : };
3786 : 0 : ath10k_peer_unmap_event(htt, &ev);
3787 : 0 : break;
3788 : : }
3789 : 0 : case HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION: {
3790 : 0 : struct htt_tx_done tx_done = {};
3791 : 0 : int status = __le32_to_cpu(resp->mgmt_tx_completion.status);
3792 : 0 : int info = __le32_to_cpu(resp->mgmt_tx_completion.info);
3793 : :
3794 : 0 : tx_done.msdu_id = __le32_to_cpu(resp->mgmt_tx_completion.desc_id);
3795 : :
3796 [ # # # # ]: 0 : switch (status) {
3797 : 0 : case HTT_MGMT_TX_STATUS_OK:
3798 : 0 : tx_done.status = HTT_TX_COMPL_STATE_ACK;
3799 [ # # ]: 0 : if (test_bit(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
3800 : 0 : ar->wmi.svc_map) &&
3801 [ # # ]: 0 : (resp->mgmt_tx_completion.flags &
3802 : : HTT_MGMT_TX_CMPL_FLAG_ACK_RSSI)) {
3803 : 0 : tx_done.ack_rssi =
3804 : 0 : FIELD_GET(HTT_MGMT_TX_CMPL_INFO_ACK_RSSI_MASK,
3805 : : info);
3806 : : }
3807 : : break;
3808 : 0 : case HTT_MGMT_TX_STATUS_RETRY:
3809 : 0 : tx_done.status = HTT_TX_COMPL_STATE_NOACK;
3810 : 0 : break;
3811 : 0 : case HTT_MGMT_TX_STATUS_DROP:
3812 : 0 : tx_done.status = HTT_TX_COMPL_STATE_DISCARD;
3813 : 0 : break;
3814 : : }
3815 : :
3816 : 0 : status = ath10k_txrx_tx_unref(htt, &tx_done);
3817 [ # # ]: 0 : if (!status) {
3818 : 0 : spin_lock_bh(&htt->tx_lock);
3819 : 0 : ath10k_htt_tx_mgmt_dec_pending(htt);
3820 : 0 : spin_unlock_bh(&htt->tx_lock);
3821 : : }
3822 : 0 : break;
3823 : : }
3824 : 0 : case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
3825 : 0 : ath10k_htt_rx_tx_compl_ind(htt->ar, skb);
3826 : 0 : break;
3827 : 0 : case HTT_T2H_MSG_TYPE_SEC_IND: {
3828 : 0 : struct ath10k *ar = htt->ar;
3829 : 0 : struct htt_security_indication *ev = &resp->security_indication;
3830 : :
3831 : 0 : ath10k_htt_rx_sec_ind_handler(ar, ev);
3832 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT,
3833 : : "sec ind peer_id %d unicast %d type %d\n",
3834 : : __le16_to_cpu(ev->peer_id),
3835 : : !!(ev->flags & HTT_SECURITY_IS_UNICAST),
3836 : : MS(ev->flags, HTT_SECURITY_TYPE));
3837 : 0 : complete(&ar->install_key_done);
3838 : 0 : break;
3839 : : }
3840 : 0 : case HTT_T2H_MSG_TYPE_RX_FRAG_IND: {
3841 : 0 : ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ",
3842 : 0 : skb->data, skb->len);
3843 : 0 : atomic_inc(&htt->num_mpdus_ready);
3844 : :
3845 [ # # ]: 0 : return ath10k_htt_rx_proc_rx_frag_ind(htt,
3846 : : &resp->rx_frag_ind,
3847 : : skb);
3848 : : break;
3849 : : }
3850 : : case HTT_T2H_MSG_TYPE_TEST:
3851 : : break;
3852 : 0 : case HTT_T2H_MSG_TYPE_STATS_CONF:
3853 : 0 : trace_ath10k_htt_stats(ar, skb->data, skb->len);
3854 : 0 : break;
3855 : 0 : case HTT_T2H_MSG_TYPE_TX_INSPECT_IND:
3856 : : /* Firmware can return tx frames if it's unable to fully
3857 : : * process them and suspects host may be able to fix it. ath10k
3858 : : * sends all tx frames as already inspected so this shouldn't
3859 : : * happen unless fw has a bug.
3860 : : */
3861 : 0 : ath10k_warn(ar, "received an unexpected htt tx inspect event\n");
3862 : 0 : break;
3863 : 0 : case HTT_T2H_MSG_TYPE_RX_ADDBA:
3864 : 0 : ath10k_htt_rx_addba(ar, resp);
3865 : 0 : break;
3866 : 0 : case HTT_T2H_MSG_TYPE_RX_DELBA:
3867 : 0 : ath10k_htt_rx_delba(ar, resp);
3868 : 0 : break;
3869 : 0 : case HTT_T2H_MSG_TYPE_PKTLOG: {
3870 : 0 : trace_ath10k_htt_pktlog(ar, resp->pktlog_msg.payload,
3871 : 0 : skb->len -
3872 : : offsetof(struct htt_resp,
3873 : : pktlog_msg.payload));
3874 : :
3875 [ # # ]: 0 : if (ath10k_peer_stats_enabled(ar))
3876 : 0 : ath10k_fetch_10_2_tx_stats(ar,
3877 : : resp->pktlog_msg.payload);
3878 : : break;
3879 : : }
3880 : : case HTT_T2H_MSG_TYPE_RX_FLUSH: {
3881 : : /* Ignore this event because mac80211 takes care of Rx
3882 : : * aggregation reordering.
3883 : : */
3884 : : break;
3885 : : }
3886 : 0 : case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND: {
3887 : 0 : skb_queue_tail(&htt->rx_in_ord_compl_q, skb);
3888 : 0 : return false;
3889 : : }
3890 : : case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND:
3891 : : break;
3892 : 0 : case HTT_T2H_MSG_TYPE_CHAN_CHANGE: {
3893 : 0 : u32 phymode = __le32_to_cpu(resp->chan_change.phymode);
3894 : 0 : u32 freq = __le32_to_cpu(resp->chan_change.freq);
3895 : :
3896 : 0 : ar->tgt_oper_chan = ieee80211_get_channel(ar->hw->wiphy, freq);
3897 [ # # # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT,
3898 : : "htt chan change freq %u phymode %s\n",
3899 : : freq, ath10k_wmi_phymode_str(phymode));
3900 : : break;
3901 : : }
3902 : : case HTT_T2H_MSG_TYPE_AGGR_CONF:
3903 : : break;
3904 : 0 : case HTT_T2H_MSG_TYPE_TX_FETCH_IND: {
3905 : 0 : struct sk_buff *tx_fetch_ind = skb_copy(skb, GFP_ATOMIC);
3906 : :
3907 [ # # ]: 0 : if (!tx_fetch_ind) {
3908 : 0 : ath10k_warn(ar, "failed to copy htt tx fetch ind\n");
3909 : 0 : break;
3910 : : }
3911 : 0 : skb_queue_tail(&htt->tx_fetch_ind_q, tx_fetch_ind);
3912 : 0 : break;
3913 : : }
3914 : 0 : case HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM:
3915 : 0 : ath10k_htt_rx_tx_fetch_confirm(ar, skb);
3916 : 0 : break;
3917 : 0 : case HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND:
3918 : 0 : ath10k_htt_rx_tx_mode_switch_ind(ar, skb);
3919 : 0 : break;
3920 : 0 : case HTT_T2H_MSG_TYPE_PEER_STATS:
3921 : 0 : ath10k_htt_fetch_peer_stats(ar, skb);
3922 : 0 : break;
3923 : 0 : case HTT_T2H_MSG_TYPE_EN_STATS:
3924 : : default:
3925 : 0 : ath10k_warn(ar, "htt event (%d) not handled\n",
3926 : : resp->hdr.msg_type);
3927 : 0 : ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ",
3928 : 0 : skb->data, skb->len);
3929 : 0 : break;
3930 : : }
3931 : : return true;
3932 : : }
3933 : : EXPORT_SYMBOL(ath10k_htt_t2h_msg_handler);
3934 : :
3935 : 0 : void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
3936 : : struct sk_buff *skb)
3937 : : {
3938 : 0 : trace_ath10k_htt_pktlog(ar, skb->data, skb->len);
3939 : 0 : dev_kfree_skb_any(skb);
3940 : 0 : }
3941 : : EXPORT_SYMBOL(ath10k_htt_rx_pktlog_completion_handler);
3942 : :
3943 : 0 : static int ath10k_htt_rx_deliver_msdu(struct ath10k *ar, int quota, int budget)
3944 : : {
3945 : 0 : struct sk_buff *skb;
3946 : :
3947 [ # # ]: 0 : while (quota < budget) {
3948 [ # # ]: 0 : if (skb_queue_empty(&ar->htt.rx_msdus_q))
3949 : : break;
3950 : :
3951 : 0 : skb = skb_dequeue(&ar->htt.rx_msdus_q);
3952 [ # # ]: 0 : if (!skb)
3953 : : break;
3954 : 0 : ath10k_process_rx(ar, skb);
3955 : 0 : quota++;
3956 : : }
3957 : :
3958 : 0 : return quota;
3959 : : }
3960 : :
3961 : 0 : int ath10k_htt_rx_hl_indication(struct ath10k *ar, int budget)
3962 : : {
3963 : 0 : struct htt_resp *resp;
3964 : 0 : struct ath10k_htt *htt = &ar->htt;
3965 : 0 : struct sk_buff *skb;
3966 : 0 : bool release;
3967 : 0 : int quota;
3968 : :
3969 [ # # ]: 0 : for (quota = 0; quota < budget; quota++) {
3970 : 0 : skb = skb_dequeue(&htt->rx_indication_head);
3971 [ # # ]: 0 : if (!skb)
3972 : : break;
3973 : :
3974 : 0 : resp = (struct htt_resp *)skb->data;
3975 : :
3976 : 0 : release = ath10k_htt_rx_proc_rx_ind_hl(htt,
3977 : : &resp->rx_ind_hl,
3978 : : skb,
3979 : : HTT_RX_PN_CHECK,
3980 : : HTT_RX_NON_TKIP_MIC);
3981 : :
3982 [ # # ]: 0 : if (release)
3983 : 0 : dev_kfree_skb_any(skb);
3984 : :
3985 [ # # ]: 0 : ath10k_dbg(ar, ATH10K_DBG_HTT, "rx indication poll pending count:%d\n",
3986 : : skb_queue_len(&htt->rx_indication_head));
3987 : : }
3988 : 0 : return quota;
3989 : : }
3990 : : EXPORT_SYMBOL(ath10k_htt_rx_hl_indication);
3991 : :
3992 : 0 : int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget)
3993 : : {
3994 : 0 : struct ath10k_htt *htt = &ar->htt;
3995 : 0 : struct htt_tx_done tx_done = {};
3996 : 0 : struct sk_buff_head tx_ind_q;
3997 : 0 : struct sk_buff *skb;
3998 : 0 : unsigned long flags;
3999 : 0 : int quota = 0, done, ret;
4000 : 0 : bool resched_napi = false;
4001 : :
4002 : 0 : __skb_queue_head_init(&tx_ind_q);
4003 : :
4004 : : /* Process pending frames before dequeuing more data
4005 : : * from hardware.
4006 : : */
4007 : 0 : quota = ath10k_htt_rx_deliver_msdu(ar, quota, budget);
4008 [ # # ]: 0 : if (quota == budget) {
4009 : 0 : resched_napi = true;
4010 : 0 : goto exit;
4011 : : }
4012 : :
4013 [ # # ]: 0 : while ((skb = skb_dequeue(&htt->rx_in_ord_compl_q))) {
4014 : 0 : spin_lock_bh(&htt->rx_ring.lock);
4015 : 0 : ret = ath10k_htt_rx_in_ord_ind(ar, skb);
4016 : 0 : spin_unlock_bh(&htt->rx_ring.lock);
4017 : :
4018 : 0 : dev_kfree_skb_any(skb);
4019 [ # # ]: 0 : if (ret == -EIO) {
4020 : 0 : resched_napi = true;
4021 : 0 : goto exit;
4022 : : }
4023 : : }
4024 : :
4025 [ # # ]: 0 : while (atomic_read(&htt->num_mpdus_ready)) {
4026 : 0 : ret = ath10k_htt_rx_handle_amsdu(htt);
4027 [ # # ]: 0 : if (ret == -EIO) {
4028 : 0 : resched_napi = true;
4029 : 0 : goto exit;
4030 : : }
4031 : 0 : atomic_dec(&htt->num_mpdus_ready);
4032 : : }
4033 : :
4034 : : /* Deliver received data after processing data from hardware */
4035 : 0 : quota = ath10k_htt_rx_deliver_msdu(ar, quota, budget);
4036 : :
4037 : : /* From NAPI documentation:
4038 : : * The napi poll() function may also process TX completions, in which
4039 : : * case if it processes the entire TX ring then it should count that
4040 : : * work as the rest of the budget.
4041 : : */
4042 [ # # # # ]: 0 : if ((quota < budget) && !kfifo_is_empty(&htt->txdone_fifo))
4043 : 0 : quota = budget;
4044 : :
4045 : : /* kfifo_get: called only within txrx_tasklet so it's neatly serialized.
4046 : : * From kfifo_get() documentation:
4047 : : * Note that with only one concurrent reader and one concurrent writer,
4048 : : * you don't need extra locking to use these macro.
4049 : : */
4050 [ # # # # ]: 0 : while (kfifo_get(&htt->txdone_fifo, &tx_done))
4051 : 0 : ath10k_txrx_tx_unref(htt, &tx_done);
4052 : :
4053 : 0 : ath10k_mac_tx_push_pending(ar);
4054 : :
4055 : 0 : spin_lock_irqsave(&htt->tx_fetch_ind_q.lock, flags);
4056 [ # # ]: 0 : skb_queue_splice_init(&htt->tx_fetch_ind_q, &tx_ind_q);
4057 : 0 : spin_unlock_irqrestore(&htt->tx_fetch_ind_q.lock, flags);
4058 : :
4059 [ # # # # ]: 0 : while ((skb = __skb_dequeue(&tx_ind_q))) {
4060 : 0 : ath10k_htt_rx_tx_fetch_ind(ar, skb);
4061 : 0 : dev_kfree_skb_any(skb);
4062 : : }
4063 : :
4064 : 0 : exit:
4065 : 0 : ath10k_htt_rx_msdu_buff_replenish(htt);
4066 : : /* In case of rx failure or more data to read, report budget
4067 : : * to reschedule NAPI poll
4068 : : */
4069 [ # # ]: 0 : done = resched_napi ? budget : quota;
4070 : :
4071 : 0 : return done;
4072 : : }
4073 : : EXPORT_SYMBOL(ath10k_htt_txrx_compl_task);
4074 : :
4075 : : static const struct ath10k_htt_rx_ops htt_rx_ops_32 = {
4076 : : .htt_get_rx_ring_size = ath10k_htt_get_rx_ring_size_32,
4077 : : .htt_config_paddrs_ring = ath10k_htt_config_paddrs_ring_32,
4078 : : .htt_set_paddrs_ring = ath10k_htt_set_paddrs_ring_32,
4079 : : .htt_get_vaddr_ring = ath10k_htt_get_vaddr_ring_32,
4080 : : .htt_reset_paddrs_ring = ath10k_htt_reset_paddrs_ring_32,
4081 : : };
4082 : :
4083 : : static const struct ath10k_htt_rx_ops htt_rx_ops_64 = {
4084 : : .htt_get_rx_ring_size = ath10k_htt_get_rx_ring_size_64,
4085 : : .htt_config_paddrs_ring = ath10k_htt_config_paddrs_ring_64,
4086 : : .htt_set_paddrs_ring = ath10k_htt_set_paddrs_ring_64,
4087 : : .htt_get_vaddr_ring = ath10k_htt_get_vaddr_ring_64,
4088 : : .htt_reset_paddrs_ring = ath10k_htt_reset_paddrs_ring_64,
4089 : : };
4090 : :
4091 : : static const struct ath10k_htt_rx_ops htt_rx_ops_hl = {
4092 : : .htt_rx_proc_rx_frag_ind = ath10k_htt_rx_proc_rx_frag_ind_hl,
4093 : : };
4094 : :
4095 : 0 : void ath10k_htt_set_rx_ops(struct ath10k_htt *htt)
4096 : : {
4097 : 0 : struct ath10k *ar = htt->ar;
4098 : :
4099 [ # # ]: 0 : if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
4100 : 0 : htt->rx_ops = &htt_rx_ops_hl;
4101 [ # # ]: 0 : else if (ar->hw_params.target_64bit)
4102 : 0 : htt->rx_ops = &htt_rx_ops_64;
4103 : : else
4104 : 0 : htt->rx_ops = &htt_rx_ops_32;
4105 : 0 : }
|