5800 lines · c
1// SPDX-License-Identifier: BSD-3-Clause-Clear2/*3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.5 */6 7#include <linux/ieee80211.h>8#include <linux/kernel.h>9#include <linux/skbuff.h>10#include <crypto/hash.h>11#include "core.h"12#include "debug.h"13#include "debugfs_htt_stats.h"14#include "debugfs_sta.h"15#include "hal_desc.h"16#include "hw.h"17#include "dp_rx.h"18#include "hal_rx.h"19#include "dp_tx.h"20#include "peer.h"21 22#define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ)23 24static inline25u8 *ath11k_dp_rx_h_80211_hdr(struct ath11k_base *ab, struct hal_rx_desc *desc)26{27 return ab->hw_params.hw_ops->rx_desc_get_hdr_status(desc);28}29 30static inline31enum hal_encrypt_type ath11k_dp_rx_h_mpdu_start_enctype(struct ath11k_base *ab,32 struct hal_rx_desc *desc)33{34 if (!ab->hw_params.hw_ops->rx_desc_encrypt_valid(desc))35 return HAL_ENCRYPT_TYPE_OPEN;36 37 return ab->hw_params.hw_ops->rx_desc_get_encrypt_type(desc);38}39 40static inline u8 ath11k_dp_rx_h_msdu_start_decap_type(struct ath11k_base *ab,41 struct hal_rx_desc *desc)42{43 return ab->hw_params.hw_ops->rx_desc_get_decap_type(desc);44}45 46static inline47bool ath11k_dp_rx_h_msdu_start_ldpc_support(struct ath11k_base *ab,48 struct hal_rx_desc *desc)49{50 return ab->hw_params.hw_ops->rx_desc_get_ldpc_support(desc);51}52 53static inline54u8 ath11k_dp_rx_h_msdu_start_mesh_ctl_present(struct ath11k_base *ab,55 struct hal_rx_desc *desc)56{57 return ab->hw_params.hw_ops->rx_desc_get_mesh_ctl(desc);58}59 60static inline61bool ath11k_dp_rx_h_mpdu_start_seq_ctrl_valid(struct ath11k_base *ab,62 struct hal_rx_desc *desc)63{64 return ab->hw_params.hw_ops->rx_desc_get_mpdu_seq_ctl_vld(desc);65}66 67static inline bool ath11k_dp_rx_h_mpdu_start_fc_valid(struct ath11k_base *ab,68 struct hal_rx_desc *desc)69{70 return ab->hw_params.hw_ops->rx_desc_get_mpdu_fc_valid(desc);71}72 73static inline bool ath11k_dp_rx_h_mpdu_start_more_frags(struct ath11k_base *ab,74 struct sk_buff *skb)75{76 struct ieee80211_hdr *hdr;77 78 hdr = (struct ieee80211_hdr *)(skb->data + ab->hw_params.hal_desc_sz);79 return ieee80211_has_morefrags(hdr->frame_control);80}81 82static inline u16 ath11k_dp_rx_h_mpdu_start_frag_no(struct ath11k_base *ab,83 struct sk_buff *skb)84{85 struct ieee80211_hdr *hdr;86 87 hdr = (struct ieee80211_hdr *)(skb->data + ab->hw_params.hal_desc_sz);88 return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;89}90 91static inline u16 ath11k_dp_rx_h_mpdu_start_seq_no(struct ath11k_base *ab,92 struct hal_rx_desc *desc)93{94 return ab->hw_params.hw_ops->rx_desc_get_mpdu_start_seq_no(desc);95}96 97static inline void *ath11k_dp_rx_get_attention(struct ath11k_base *ab,98 struct hal_rx_desc *desc)99{100 return ab->hw_params.hw_ops->rx_desc_get_attention(desc);101}102 103static inline bool ath11k_dp_rx_h_attn_msdu_done(struct rx_attention *attn)104{105 return !!FIELD_GET(RX_ATTENTION_INFO2_MSDU_DONE,106 __le32_to_cpu(attn->info2));107}108 109static inline bool ath11k_dp_rx_h_attn_l4_cksum_fail(struct rx_attention *attn)110{111 return !!FIELD_GET(RX_ATTENTION_INFO1_TCP_UDP_CKSUM_FAIL,112 __le32_to_cpu(attn->info1));113}114 115static inline bool ath11k_dp_rx_h_attn_ip_cksum_fail(struct rx_attention *attn)116{117 return !!FIELD_GET(RX_ATTENTION_INFO1_IP_CKSUM_FAIL,118 __le32_to_cpu(attn->info1));119}120 121static inline bool ath11k_dp_rx_h_attn_is_decrypted(struct rx_attention *attn)122{123 return (FIELD_GET(RX_ATTENTION_INFO2_DCRYPT_STATUS_CODE,124 __le32_to_cpu(attn->info2)) ==125 RX_DESC_DECRYPT_STATUS_CODE_OK);126}127 128static u32 ath11k_dp_rx_h_attn_mpdu_err(struct rx_attention *attn)129{130 u32 info = __le32_to_cpu(attn->info1);131 u32 errmap = 0;132 133 if (info & RX_ATTENTION_INFO1_FCS_ERR)134 errmap |= DP_RX_MPDU_ERR_FCS;135 136 if (info & RX_ATTENTION_INFO1_DECRYPT_ERR)137 errmap |= DP_RX_MPDU_ERR_DECRYPT;138 139 if (info & RX_ATTENTION_INFO1_TKIP_MIC_ERR)140 errmap |= DP_RX_MPDU_ERR_TKIP_MIC;141 142 if (info & RX_ATTENTION_INFO1_A_MSDU_ERROR)143 errmap |= DP_RX_MPDU_ERR_AMSDU_ERR;144 145 if (info & RX_ATTENTION_INFO1_OVERFLOW_ERR)146 errmap |= DP_RX_MPDU_ERR_OVERFLOW;147 148 if (info & RX_ATTENTION_INFO1_MSDU_LEN_ERR)149 errmap |= DP_RX_MPDU_ERR_MSDU_LEN;150 151 if (info & RX_ATTENTION_INFO1_MPDU_LEN_ERR)152 errmap |= DP_RX_MPDU_ERR_MPDU_LEN;153 154 return errmap;155}156 157static bool ath11k_dp_rx_h_attn_msdu_len_err(struct ath11k_base *ab,158 struct hal_rx_desc *desc)159{160 struct rx_attention *rx_attention;161 u32 errmap;162 163 rx_attention = ath11k_dp_rx_get_attention(ab, desc);164 errmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention);165 166 return errmap & DP_RX_MPDU_ERR_MSDU_LEN;167}168 169static inline u16 ath11k_dp_rx_h_msdu_start_msdu_len(struct ath11k_base *ab,170 struct hal_rx_desc *desc)171{172 return ab->hw_params.hw_ops->rx_desc_get_msdu_len(desc);173}174 175static inline u8 ath11k_dp_rx_h_msdu_start_sgi(struct ath11k_base *ab,176 struct hal_rx_desc *desc)177{178 return ab->hw_params.hw_ops->rx_desc_get_msdu_sgi(desc);179}180 181static inline u8 ath11k_dp_rx_h_msdu_start_rate_mcs(struct ath11k_base *ab,182 struct hal_rx_desc *desc)183{184 return ab->hw_params.hw_ops->rx_desc_get_msdu_rate_mcs(desc);185}186 187static inline u8 ath11k_dp_rx_h_msdu_start_rx_bw(struct ath11k_base *ab,188 struct hal_rx_desc *desc)189{190 return ab->hw_params.hw_ops->rx_desc_get_msdu_rx_bw(desc);191}192 193static inline u32 ath11k_dp_rx_h_msdu_start_freq(struct ath11k_base *ab,194 struct hal_rx_desc *desc)195{196 return ab->hw_params.hw_ops->rx_desc_get_msdu_freq(desc);197}198 199static inline u8 ath11k_dp_rx_h_msdu_start_pkt_type(struct ath11k_base *ab,200 struct hal_rx_desc *desc)201{202 return ab->hw_params.hw_ops->rx_desc_get_msdu_pkt_type(desc);203}204 205static inline u8 ath11k_dp_rx_h_msdu_start_nss(struct ath11k_base *ab,206 struct hal_rx_desc *desc)207{208 return hweight8(ab->hw_params.hw_ops->rx_desc_get_msdu_nss(desc));209}210 211static inline u8 ath11k_dp_rx_h_mpdu_start_tid(struct ath11k_base *ab,212 struct hal_rx_desc *desc)213{214 return ab->hw_params.hw_ops->rx_desc_get_mpdu_tid(desc);215}216 217static inline u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab,218 struct hal_rx_desc *desc)219{220 return ab->hw_params.hw_ops->rx_desc_get_mpdu_peer_id(desc);221}222 223static inline u8 ath11k_dp_rx_h_msdu_end_l3pad(struct ath11k_base *ab,224 struct hal_rx_desc *desc)225{226 return ab->hw_params.hw_ops->rx_desc_get_l3_pad_bytes(desc);227}228 229static inline bool ath11k_dp_rx_h_msdu_end_first_msdu(struct ath11k_base *ab,230 struct hal_rx_desc *desc)231{232 return ab->hw_params.hw_ops->rx_desc_get_first_msdu(desc);233}234 235static bool ath11k_dp_rx_h_msdu_end_last_msdu(struct ath11k_base *ab,236 struct hal_rx_desc *desc)237{238 return ab->hw_params.hw_ops->rx_desc_get_last_msdu(desc);239}240 241static void ath11k_dp_rx_desc_end_tlv_copy(struct ath11k_base *ab,242 struct hal_rx_desc *fdesc,243 struct hal_rx_desc *ldesc)244{245 ab->hw_params.hw_ops->rx_desc_copy_attn_end_tlv(fdesc, ldesc);246}247 248static inline u32 ath11k_dp_rxdesc_get_mpdulen_err(struct rx_attention *attn)249{250 return FIELD_GET(RX_ATTENTION_INFO1_MPDU_LEN_ERR,251 __le32_to_cpu(attn->info1));252}253 254static inline u8 *ath11k_dp_rxdesc_get_80211hdr(struct ath11k_base *ab,255 struct hal_rx_desc *rx_desc)256{257 u8 *rx_pkt_hdr;258 259 rx_pkt_hdr = ab->hw_params.hw_ops->rx_desc_get_msdu_payload(rx_desc);260 261 return rx_pkt_hdr;262}263 264static inline bool ath11k_dp_rxdesc_mpdu_valid(struct ath11k_base *ab,265 struct hal_rx_desc *rx_desc)266{267 u32 tlv_tag;268 269 tlv_tag = ab->hw_params.hw_ops->rx_desc_get_mpdu_start_tag(rx_desc);270 271 return tlv_tag == HAL_RX_MPDU_START;272}273 274static inline u32 ath11k_dp_rxdesc_get_ppduid(struct ath11k_base *ab,275 struct hal_rx_desc *rx_desc)276{277 return ab->hw_params.hw_ops->rx_desc_get_mpdu_ppdu_id(rx_desc);278}279 280static inline void ath11k_dp_rxdesc_set_msdu_len(struct ath11k_base *ab,281 struct hal_rx_desc *desc,282 u16 len)283{284 ab->hw_params.hw_ops->rx_desc_set_msdu_len(desc, len);285}286 287static bool ath11k_dp_rx_h_attn_is_mcbc(struct ath11k_base *ab,288 struct hal_rx_desc *desc)289{290 struct rx_attention *attn = ath11k_dp_rx_get_attention(ab, desc);291 292 return ath11k_dp_rx_h_msdu_end_first_msdu(ab, desc) &&293 (!!FIELD_GET(RX_ATTENTION_INFO1_MCAST_BCAST,294 __le32_to_cpu(attn->info1)));295}296 297static bool ath11k_dp_rxdesc_mac_addr2_valid(struct ath11k_base *ab,298 struct hal_rx_desc *desc)299{300 return ab->hw_params.hw_ops->rx_desc_mac_addr2_valid(desc);301}302 303static u8 *ath11k_dp_rxdesc_mpdu_start_addr2(struct ath11k_base *ab,304 struct hal_rx_desc *desc)305{306 return ab->hw_params.hw_ops->rx_desc_mpdu_start_addr2(desc);307}308 309static void ath11k_dp_service_mon_ring(struct timer_list *t)310{311 struct ath11k_base *ab = from_timer(ab, t, mon_reap_timer);312 int i;313 314 for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++)315 ath11k_dp_rx_process_mon_rings(ab, i, NULL, DP_MON_SERVICE_BUDGET);316 317 mod_timer(&ab->mon_reap_timer, jiffies +318 msecs_to_jiffies(ATH11K_MON_TIMER_INTERVAL));319}320 321static int ath11k_dp_purge_mon_ring(struct ath11k_base *ab)322{323 int i, reaped = 0;324 unsigned long timeout = jiffies + msecs_to_jiffies(DP_MON_PURGE_TIMEOUT_MS);325 326 do {327 for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++)328 reaped += ath11k_dp_rx_process_mon_rings(ab, i,329 NULL,330 DP_MON_SERVICE_BUDGET);331 332 /* nothing more to reap */333 if (reaped < DP_MON_SERVICE_BUDGET)334 return 0;335 336 } while (time_before(jiffies, timeout));337 338 ath11k_warn(ab, "dp mon ring purge timeout");339 340 return -ETIMEDOUT;341}342 343/* Returns number of Rx buffers replenished */344int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id,345 struct dp_rxdma_ring *rx_ring,346 int req_entries,347 enum hal_rx_buf_return_buf_manager mgr)348{349 struct hal_srng *srng;350 u32 *desc;351 struct sk_buff *skb;352 int num_free;353 int num_remain;354 int buf_id;355 u32 cookie;356 dma_addr_t paddr;357 358 req_entries = min(req_entries, rx_ring->bufs_max);359 360 srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id];361 362 spin_lock_bh(&srng->lock);363 364 ath11k_hal_srng_access_begin(ab, srng);365 366 num_free = ath11k_hal_srng_src_num_free(ab, srng, true);367 if (!req_entries && (num_free > (rx_ring->bufs_max * 3) / 4))368 req_entries = num_free;369 370 req_entries = min(num_free, req_entries);371 num_remain = req_entries;372 373 while (num_remain > 0) {374 skb = dev_alloc_skb(DP_RX_BUFFER_SIZE +375 DP_RX_BUFFER_ALIGN_SIZE);376 if (!skb)377 break;378 379 if (!IS_ALIGNED((unsigned long)skb->data,380 DP_RX_BUFFER_ALIGN_SIZE)) {381 skb_pull(skb,382 PTR_ALIGN(skb->data, DP_RX_BUFFER_ALIGN_SIZE) -383 skb->data);384 }385 386 paddr = dma_map_single(ab->dev, skb->data,387 skb->len + skb_tailroom(skb),388 DMA_FROM_DEVICE);389 if (dma_mapping_error(ab->dev, paddr))390 goto fail_free_skb;391 392 spin_lock_bh(&rx_ring->idr_lock);393 buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 1,394 (rx_ring->bufs_max * 3) + 1, GFP_ATOMIC);395 spin_unlock_bh(&rx_ring->idr_lock);396 if (buf_id <= 0)397 goto fail_dma_unmap;398 399 desc = ath11k_hal_srng_src_get_next_entry(ab, srng);400 if (!desc)401 goto fail_idr_remove;402 403 ATH11K_SKB_RXCB(skb)->paddr = paddr;404 405 cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, mac_id) |406 FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id);407 408 num_remain--;409 410 ath11k_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr);411 }412 413 ath11k_hal_srng_access_end(ab, srng);414 415 spin_unlock_bh(&srng->lock);416 417 return req_entries - num_remain;418 419fail_idr_remove:420 spin_lock_bh(&rx_ring->idr_lock);421 idr_remove(&rx_ring->bufs_idr, buf_id);422 spin_unlock_bh(&rx_ring->idr_lock);423fail_dma_unmap:424 dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb),425 DMA_FROM_DEVICE);426fail_free_skb:427 dev_kfree_skb_any(skb);428 429 ath11k_hal_srng_access_end(ab, srng);430 431 spin_unlock_bh(&srng->lock);432 433 return req_entries - num_remain;434}435 436static int ath11k_dp_rxdma_buf_ring_free(struct ath11k *ar,437 struct dp_rxdma_ring *rx_ring)438{439 struct sk_buff *skb;440 int buf_id;441 442 spin_lock_bh(&rx_ring->idr_lock);443 idr_for_each_entry(&rx_ring->bufs_idr, skb, buf_id) {444 idr_remove(&rx_ring->bufs_idr, buf_id);445 /* TODO: Understand where internal driver does this dma_unmap446 * of rxdma_buffer.447 */448 dma_unmap_single(ar->ab->dev, ATH11K_SKB_RXCB(skb)->paddr,449 skb->len + skb_tailroom(skb), DMA_FROM_DEVICE);450 dev_kfree_skb_any(skb);451 }452 453 idr_destroy(&rx_ring->bufs_idr);454 spin_unlock_bh(&rx_ring->idr_lock);455 456 return 0;457}458 459static int ath11k_dp_rxdma_pdev_buf_free(struct ath11k *ar)460{461 struct ath11k_pdev_dp *dp = &ar->dp;462 struct ath11k_base *ab = ar->ab;463 struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;464 int i;465 466 ath11k_dp_rxdma_buf_ring_free(ar, rx_ring);467 468 rx_ring = &dp->rxdma_mon_buf_ring;469 ath11k_dp_rxdma_buf_ring_free(ar, rx_ring);470 471 for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {472 rx_ring = &dp->rx_mon_status_refill_ring[i];473 ath11k_dp_rxdma_buf_ring_free(ar, rx_ring);474 }475 476 return 0;477}478 479static int ath11k_dp_rxdma_ring_buf_setup(struct ath11k *ar,480 struct dp_rxdma_ring *rx_ring,481 u32 ringtype)482{483 struct ath11k_pdev_dp *dp = &ar->dp;484 int num_entries;485 486 num_entries = rx_ring->refill_buf_ring.size /487 ath11k_hal_srng_get_entrysize(ar->ab, ringtype);488 489 rx_ring->bufs_max = num_entries;490 ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, rx_ring, num_entries,491 ar->ab->hw_params.hal_params->rx_buf_rbm);492 return 0;493}494 495static int ath11k_dp_rxdma_pdev_buf_setup(struct ath11k *ar)496{497 struct ath11k_pdev_dp *dp = &ar->dp;498 struct ath11k_base *ab = ar->ab;499 struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;500 int i;501 502 ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_BUF);503 504 if (ar->ab->hw_params.rxdma1_enable) {505 rx_ring = &dp->rxdma_mon_buf_ring;506 ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_MONITOR_BUF);507 }508 509 for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {510 rx_ring = &dp->rx_mon_status_refill_ring[i];511 ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_MONITOR_STATUS);512 }513 514 return 0;515}516 517static void ath11k_dp_rx_pdev_srng_free(struct ath11k *ar)518{519 struct ath11k_pdev_dp *dp = &ar->dp;520 struct ath11k_base *ab = ar->ab;521 int i;522 523 ath11k_dp_srng_cleanup(ab, &dp->rx_refill_buf_ring.refill_buf_ring);524 525 for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {526 if (ab->hw_params.rx_mac_buf_ring)527 ath11k_dp_srng_cleanup(ab, &dp->rx_mac_buf_ring[i]);528 529 ath11k_dp_srng_cleanup(ab, &dp->rxdma_err_dst_ring[i]);530 ath11k_dp_srng_cleanup(ab,531 &dp->rx_mon_status_refill_ring[i].refill_buf_ring);532 }533 534 ath11k_dp_srng_cleanup(ab, &dp->rxdma_mon_buf_ring.refill_buf_ring);535}536 537void ath11k_dp_pdev_reo_cleanup(struct ath11k_base *ab)538{539 struct ath11k_dp *dp = &ab->dp;540 int i;541 542 for (i = 0; i < DP_REO_DST_RING_MAX; i++)543 ath11k_dp_srng_cleanup(ab, &dp->reo_dst_ring[i]);544}545 546int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab)547{548 struct ath11k_dp *dp = &ab->dp;549 int ret;550 int i;551 552 for (i = 0; i < DP_REO_DST_RING_MAX; i++) {553 ret = ath11k_dp_srng_setup(ab, &dp->reo_dst_ring[i],554 HAL_REO_DST, i, 0,555 DP_REO_DST_RING_SIZE);556 if (ret) {557 ath11k_warn(ab, "failed to setup reo_dst_ring\n");558 goto err_reo_cleanup;559 }560 }561 562 return 0;563 564err_reo_cleanup:565 ath11k_dp_pdev_reo_cleanup(ab);566 567 return ret;568}569 570static int ath11k_dp_rx_pdev_srng_alloc(struct ath11k *ar)571{572 struct ath11k_pdev_dp *dp = &ar->dp;573 struct ath11k_base *ab = ar->ab;574 struct dp_srng *srng = NULL;575 int i;576 int ret;577 578 ret = ath11k_dp_srng_setup(ar->ab,579 &dp->rx_refill_buf_ring.refill_buf_ring,580 HAL_RXDMA_BUF, 0,581 dp->mac_id, DP_RXDMA_BUF_RING_SIZE);582 if (ret) {583 ath11k_warn(ar->ab, "failed to setup rx_refill_buf_ring\n");584 return ret;585 }586 587 if (ar->ab->hw_params.rx_mac_buf_ring) {588 for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {589 ret = ath11k_dp_srng_setup(ar->ab,590 &dp->rx_mac_buf_ring[i],591 HAL_RXDMA_BUF, 1,592 dp->mac_id + i, 1024);593 if (ret) {594 ath11k_warn(ar->ab, "failed to setup rx_mac_buf_ring %d\n",595 i);596 return ret;597 }598 }599 }600 601 for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {602 ret = ath11k_dp_srng_setup(ar->ab, &dp->rxdma_err_dst_ring[i],603 HAL_RXDMA_DST, 0, dp->mac_id + i,604 DP_RXDMA_ERR_DST_RING_SIZE);605 if (ret) {606 ath11k_warn(ar->ab, "failed to setup rxdma_err_dst_ring %d\n", i);607 return ret;608 }609 }610 611 for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {612 srng = &dp->rx_mon_status_refill_ring[i].refill_buf_ring;613 ret = ath11k_dp_srng_setup(ar->ab,614 srng,615 HAL_RXDMA_MONITOR_STATUS, 0, dp->mac_id + i,616 DP_RXDMA_MON_STATUS_RING_SIZE);617 if (ret) {618 ath11k_warn(ar->ab,619 "failed to setup rx_mon_status_refill_ring %d\n", i);620 return ret;621 }622 }623 624 /* if rxdma1_enable is false, then it doesn't need625 * to setup rxdam_mon_buf_ring, rxdma_mon_dst_ring626 * and rxdma_mon_desc_ring.627 * init reap timer for QCA6390.628 */629 if (!ar->ab->hw_params.rxdma1_enable) {630 //init mon status buffer reap timer631 timer_setup(&ar->ab->mon_reap_timer,632 ath11k_dp_service_mon_ring, 0);633 return 0;634 }635 636 ret = ath11k_dp_srng_setup(ar->ab,637 &dp->rxdma_mon_buf_ring.refill_buf_ring,638 HAL_RXDMA_MONITOR_BUF, 0, dp->mac_id,639 DP_RXDMA_MONITOR_BUF_RING_SIZE);640 if (ret) {641 ath11k_warn(ar->ab,642 "failed to setup HAL_RXDMA_MONITOR_BUF\n");643 return ret;644 }645 646 ret = ath11k_dp_srng_setup(ar->ab, &dp->rxdma_mon_dst_ring,647 HAL_RXDMA_MONITOR_DST, 0, dp->mac_id,648 DP_RXDMA_MONITOR_DST_RING_SIZE);649 if (ret) {650 ath11k_warn(ar->ab,651 "failed to setup HAL_RXDMA_MONITOR_DST\n");652 return ret;653 }654 655 ret = ath11k_dp_srng_setup(ar->ab, &dp->rxdma_mon_desc_ring,656 HAL_RXDMA_MONITOR_DESC, 0, dp->mac_id,657 DP_RXDMA_MONITOR_DESC_RING_SIZE);658 if (ret) {659 ath11k_warn(ar->ab,660 "failed to setup HAL_RXDMA_MONITOR_DESC\n");661 return ret;662 }663 664 return 0;665}666 667void ath11k_dp_reo_cmd_list_cleanup(struct ath11k_base *ab)668{669 struct ath11k_dp *dp = &ab->dp;670 struct dp_reo_cmd *cmd, *tmp;671 struct dp_reo_cache_flush_elem *cmd_cache, *tmp_cache;672 struct dp_rx_tid *rx_tid;673 674 spin_lock_bh(&dp->reo_cmd_lock);675 list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) {676 list_del(&cmd->list);677 rx_tid = &cmd->data;678 if (rx_tid->vaddr) {679 dma_unmap_single(ab->dev, rx_tid->paddr,680 rx_tid->size, DMA_BIDIRECTIONAL);681 kfree(rx_tid->vaddr);682 rx_tid->vaddr = NULL;683 }684 kfree(cmd);685 }686 687 list_for_each_entry_safe(cmd_cache, tmp_cache,688 &dp->reo_cmd_cache_flush_list, list) {689 list_del(&cmd_cache->list);690 dp->reo_cmd_cache_flush_count--;691 rx_tid = &cmd_cache->data;692 if (rx_tid->vaddr) {693 dma_unmap_single(ab->dev, rx_tid->paddr,694 rx_tid->size, DMA_BIDIRECTIONAL);695 kfree(rx_tid->vaddr);696 rx_tid->vaddr = NULL;697 }698 kfree(cmd_cache);699 }700 spin_unlock_bh(&dp->reo_cmd_lock);701}702 703static void ath11k_dp_reo_cmd_free(struct ath11k_dp *dp, void *ctx,704 enum hal_reo_cmd_status status)705{706 struct dp_rx_tid *rx_tid = ctx;707 708 if (status != HAL_REO_CMD_SUCCESS)709 ath11k_warn(dp->ab, "failed to flush rx tid hw desc, tid %d status %d\n",710 rx_tid->tid, status);711 if (rx_tid->vaddr) {712 dma_unmap_single(dp->ab->dev, rx_tid->paddr, rx_tid->size,713 DMA_BIDIRECTIONAL);714 kfree(rx_tid->vaddr);715 rx_tid->vaddr = NULL;716 }717}718 719static void ath11k_dp_reo_cache_flush(struct ath11k_base *ab,720 struct dp_rx_tid *rx_tid)721{722 struct ath11k_hal_reo_cmd cmd = {0};723 unsigned long tot_desc_sz, desc_sz;724 int ret;725 726 tot_desc_sz = rx_tid->size;727 desc_sz = ath11k_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID);728 729 while (tot_desc_sz > desc_sz) {730 tot_desc_sz -= desc_sz;731 cmd.addr_lo = lower_32_bits(rx_tid->paddr + tot_desc_sz);732 cmd.addr_hi = upper_32_bits(rx_tid->paddr);733 ret = ath11k_dp_tx_send_reo_cmd(ab, rx_tid,734 HAL_REO_CMD_FLUSH_CACHE, &cmd,735 NULL);736 if (ret)737 ath11k_warn(ab,738 "failed to send HAL_REO_CMD_FLUSH_CACHE, tid %d (%d)\n",739 rx_tid->tid, ret);740 }741 742 memset(&cmd, 0, sizeof(cmd));743 cmd.addr_lo = lower_32_bits(rx_tid->paddr);744 cmd.addr_hi = upper_32_bits(rx_tid->paddr);745 cmd.flag |= HAL_REO_CMD_FLG_NEED_STATUS;746 ret = ath11k_dp_tx_send_reo_cmd(ab, rx_tid,747 HAL_REO_CMD_FLUSH_CACHE,748 &cmd, ath11k_dp_reo_cmd_free);749 if (ret) {750 ath11k_err(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n",751 rx_tid->tid, ret);752 dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size,753 DMA_BIDIRECTIONAL);754 kfree(rx_tid->vaddr);755 rx_tid->vaddr = NULL;756 }757}758 759static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx,760 enum hal_reo_cmd_status status)761{762 struct ath11k_base *ab = dp->ab;763 struct dp_rx_tid *rx_tid = ctx;764 struct dp_reo_cache_flush_elem *elem, *tmp;765 766 if (status == HAL_REO_CMD_DRAIN) {767 goto free_desc;768 } else if (status != HAL_REO_CMD_SUCCESS) {769 /* Shouldn't happen! Cleanup in case of other failure? */770 ath11k_warn(ab, "failed to delete rx tid %d hw descriptor %d\n",771 rx_tid->tid, status);772 return;773 }774 775 elem = kzalloc(sizeof(*elem), GFP_ATOMIC);776 if (!elem)777 goto free_desc;778 779 elem->ts = jiffies;780 memcpy(&elem->data, rx_tid, sizeof(*rx_tid));781 782 spin_lock_bh(&dp->reo_cmd_lock);783 list_add_tail(&elem->list, &dp->reo_cmd_cache_flush_list);784 dp->reo_cmd_cache_flush_count++;785 786 /* Flush and invalidate aged REO desc from HW cache */787 list_for_each_entry_safe(elem, tmp, &dp->reo_cmd_cache_flush_list,788 list) {789 if (dp->reo_cmd_cache_flush_count > DP_REO_DESC_FREE_THRESHOLD ||790 time_after(jiffies, elem->ts +791 msecs_to_jiffies(DP_REO_DESC_FREE_TIMEOUT_MS))) {792 list_del(&elem->list);793 dp->reo_cmd_cache_flush_count--;794 spin_unlock_bh(&dp->reo_cmd_lock);795 796 ath11k_dp_reo_cache_flush(ab, &elem->data);797 kfree(elem);798 spin_lock_bh(&dp->reo_cmd_lock);799 }800 }801 spin_unlock_bh(&dp->reo_cmd_lock);802 803 return;804free_desc:805 dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size,806 DMA_BIDIRECTIONAL);807 kfree(rx_tid->vaddr);808 rx_tid->vaddr = NULL;809}810 811void ath11k_peer_rx_tid_delete(struct ath11k *ar,812 struct ath11k_peer *peer, u8 tid)813{814 struct ath11k_hal_reo_cmd cmd = {0};815 struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];816 int ret;817 818 if (!rx_tid->active)819 return;820 821 rx_tid->active = false;822 823 cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS;824 cmd.addr_lo = lower_32_bits(rx_tid->paddr);825 cmd.addr_hi = upper_32_bits(rx_tid->paddr);826 cmd.upd0 |= HAL_REO_CMD_UPD0_VLD;827 ret = ath11k_dp_tx_send_reo_cmd(ar->ab, rx_tid,828 HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd,829 ath11k_dp_rx_tid_del_func);830 if (ret) {831 if (ret != -ESHUTDOWN)832 ath11k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n",833 tid, ret);834 dma_unmap_single(ar->ab->dev, rx_tid->paddr, rx_tid->size,835 DMA_BIDIRECTIONAL);836 kfree(rx_tid->vaddr);837 rx_tid->vaddr = NULL;838 }839 840 rx_tid->paddr = 0;841 rx_tid->size = 0;842}843 844static int ath11k_dp_rx_link_desc_return(struct ath11k_base *ab,845 u32 *link_desc,846 enum hal_wbm_rel_bm_act action)847{848 struct ath11k_dp *dp = &ab->dp;849 struct hal_srng *srng;850 u32 *desc;851 int ret = 0;852 853 srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id];854 855 spin_lock_bh(&srng->lock);856 857 ath11k_hal_srng_access_begin(ab, srng);858 859 desc = ath11k_hal_srng_src_get_next_entry(ab, srng);860 if (!desc) {861 ret = -ENOBUFS;862 goto exit;863 }864 865 ath11k_hal_rx_msdu_link_desc_set(ab, (void *)desc, (void *)link_desc,866 action);867 868exit:869 ath11k_hal_srng_access_end(ab, srng);870 871 spin_unlock_bh(&srng->lock);872 873 return ret;874}875 876static void ath11k_dp_rx_frags_cleanup(struct dp_rx_tid *rx_tid, bool rel_link_desc)877{878 struct ath11k_base *ab = rx_tid->ab;879 880 lockdep_assert_held(&ab->base_lock);881 882 if (rx_tid->dst_ring_desc) {883 if (rel_link_desc)884 ath11k_dp_rx_link_desc_return(ab, (u32 *)rx_tid->dst_ring_desc,885 HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);886 kfree(rx_tid->dst_ring_desc);887 rx_tid->dst_ring_desc = NULL;888 }889 890 rx_tid->cur_sn = 0;891 rx_tid->last_frag_no = 0;892 rx_tid->rx_frag_bitmap = 0;893 __skb_queue_purge(&rx_tid->rx_frags);894}895 896void ath11k_peer_frags_flush(struct ath11k *ar, struct ath11k_peer *peer)897{898 struct dp_rx_tid *rx_tid;899 int i;900 901 lockdep_assert_held(&ar->ab->base_lock);902 903 for (i = 0; i <= IEEE80211_NUM_TIDS; i++) {904 rx_tid = &peer->rx_tid[i];905 906 spin_unlock_bh(&ar->ab->base_lock);907 del_timer_sync(&rx_tid->frag_timer);908 spin_lock_bh(&ar->ab->base_lock);909 910 ath11k_dp_rx_frags_cleanup(rx_tid, true);911 }912}913 914void ath11k_peer_rx_tid_cleanup(struct ath11k *ar, struct ath11k_peer *peer)915{916 struct dp_rx_tid *rx_tid;917 int i;918 919 lockdep_assert_held(&ar->ab->base_lock);920 921 for (i = 0; i <= IEEE80211_NUM_TIDS; i++) {922 rx_tid = &peer->rx_tid[i];923 924 ath11k_peer_rx_tid_delete(ar, peer, i);925 ath11k_dp_rx_frags_cleanup(rx_tid, true);926 927 spin_unlock_bh(&ar->ab->base_lock);928 del_timer_sync(&rx_tid->frag_timer);929 spin_lock_bh(&ar->ab->base_lock);930 }931}932 933static int ath11k_peer_rx_tid_reo_update(struct ath11k *ar,934 struct ath11k_peer *peer,935 struct dp_rx_tid *rx_tid,936 u32 ba_win_sz, u16 ssn,937 bool update_ssn)938{939 struct ath11k_hal_reo_cmd cmd = {0};940 int ret;941 942 cmd.addr_lo = lower_32_bits(rx_tid->paddr);943 cmd.addr_hi = upper_32_bits(rx_tid->paddr);944 cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS;945 cmd.upd0 = HAL_REO_CMD_UPD0_BA_WINDOW_SIZE;946 cmd.ba_window_size = ba_win_sz;947 948 if (update_ssn) {949 cmd.upd0 |= HAL_REO_CMD_UPD0_SSN;950 cmd.upd2 = FIELD_PREP(HAL_REO_CMD_UPD2_SSN, ssn);951 }952 953 ret = ath11k_dp_tx_send_reo_cmd(ar->ab, rx_tid,954 HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd,955 NULL);956 if (ret) {957 ath11k_warn(ar->ab, "failed to update rx tid queue, tid %d (%d)\n",958 rx_tid->tid, ret);959 return ret;960 }961 962 rx_tid->ba_win_sz = ba_win_sz;963 964 return 0;965}966 967static void ath11k_dp_rx_tid_mem_free(struct ath11k_base *ab,968 const u8 *peer_mac, int vdev_id, u8 tid)969{970 struct ath11k_peer *peer;971 struct dp_rx_tid *rx_tid;972 973 spin_lock_bh(&ab->base_lock);974 975 peer = ath11k_peer_find(ab, vdev_id, peer_mac);976 if (!peer) {977 ath11k_warn(ab, "failed to find the peer to free up rx tid mem\n");978 goto unlock_exit;979 }980 981 rx_tid = &peer->rx_tid[tid];982 if (!rx_tid->active)983 goto unlock_exit;984 985 dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size,986 DMA_BIDIRECTIONAL);987 kfree(rx_tid->vaddr);988 rx_tid->vaddr = NULL;989 990 rx_tid->active = false;991 992unlock_exit:993 spin_unlock_bh(&ab->base_lock);994}995 996int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id,997 u8 tid, u32 ba_win_sz, u16 ssn,998 enum hal_pn_type pn_type)999{1000 struct ath11k_base *ab = ar->ab;1001 struct ath11k_peer *peer;1002 struct dp_rx_tid *rx_tid;1003 u32 hw_desc_sz;1004 u32 *addr_aligned;1005 void *vaddr;1006 dma_addr_t paddr;1007 int ret;1008 1009 spin_lock_bh(&ab->base_lock);1010 1011 peer = ath11k_peer_find(ab, vdev_id, peer_mac);1012 if (!peer) {1013 ath11k_warn(ab, "failed to find the peer %pM to set up rx tid\n",1014 peer_mac);1015 spin_unlock_bh(&ab->base_lock);1016 return -ENOENT;1017 }1018 1019 rx_tid = &peer->rx_tid[tid];1020 /* Update the tid queue if it is already setup */1021 if (rx_tid->active) {1022 paddr = rx_tid->paddr;1023 ret = ath11k_peer_rx_tid_reo_update(ar, peer, rx_tid,1024 ba_win_sz, ssn, true);1025 spin_unlock_bh(&ab->base_lock);1026 if (ret) {1027 ath11k_warn(ab, "failed to update reo for peer %pM rx tid %d\n: %d",1028 peer_mac, tid, ret);1029 return ret;1030 }1031 1032 ret = ath11k_wmi_peer_rx_reorder_queue_setup(ar, vdev_id,1033 peer_mac, paddr,1034 tid, 1, ba_win_sz);1035 if (ret)1036 ath11k_warn(ab, "failed to send wmi rx reorder queue for peer %pM tid %d: %d\n",1037 peer_mac, tid, ret);1038 return ret;1039 }1040 1041 rx_tid->tid = tid;1042 1043 rx_tid->ba_win_sz = ba_win_sz;1044 1045 /* TODO: Optimize the memory allocation for qos tid based on1046 * the actual BA window size in REO tid update path.1047 */1048 if (tid == HAL_DESC_REO_NON_QOS_TID)1049 hw_desc_sz = ath11k_hal_reo_qdesc_size(ba_win_sz, tid);1050 else1051 hw_desc_sz = ath11k_hal_reo_qdesc_size(DP_BA_WIN_SZ_MAX, tid);1052 1053 vaddr = kzalloc(hw_desc_sz + HAL_LINK_DESC_ALIGN - 1, GFP_ATOMIC);1054 if (!vaddr) {1055 spin_unlock_bh(&ab->base_lock);1056 return -ENOMEM;1057 }1058 1059 addr_aligned = PTR_ALIGN(vaddr, HAL_LINK_DESC_ALIGN);1060 1061 ath11k_hal_reo_qdesc_setup(addr_aligned, tid, ba_win_sz,1062 ssn, pn_type);1063 1064 paddr = dma_map_single(ab->dev, addr_aligned, hw_desc_sz,1065 DMA_BIDIRECTIONAL);1066 1067 ret = dma_mapping_error(ab->dev, paddr);1068 if (ret) {1069 spin_unlock_bh(&ab->base_lock);1070 ath11k_warn(ab, "failed to setup dma map for peer %pM rx tid %d: %d\n",1071 peer_mac, tid, ret);1072 goto err_mem_free;1073 }1074 1075 rx_tid->vaddr = vaddr;1076 rx_tid->paddr = paddr;1077 rx_tid->size = hw_desc_sz;1078 rx_tid->active = true;1079 1080 spin_unlock_bh(&ab->base_lock);1081 1082 ret = ath11k_wmi_peer_rx_reorder_queue_setup(ar, vdev_id, peer_mac,1083 paddr, tid, 1, ba_win_sz);1084 if (ret) {1085 ath11k_warn(ar->ab, "failed to setup rx reorder queue for peer %pM tid %d: %d\n",1086 peer_mac, tid, ret);1087 ath11k_dp_rx_tid_mem_free(ab, peer_mac, vdev_id, tid);1088 }1089 1090 return ret;1091 1092err_mem_free:1093 kfree(rx_tid->vaddr);1094 rx_tid->vaddr = NULL;1095 1096 return ret;1097}1098 1099int ath11k_dp_rx_ampdu_start(struct ath11k *ar,1100 struct ieee80211_ampdu_params *params)1101{1102 struct ath11k_base *ab = ar->ab;1103 struct ath11k_sta *arsta = ath11k_sta_to_arsta(params->sta);1104 int vdev_id = arsta->arvif->vdev_id;1105 int ret;1106 1107 ret = ath11k_peer_rx_tid_setup(ar, params->sta->addr, vdev_id,1108 params->tid, params->buf_size,1109 params->ssn, arsta->pn_type);1110 if (ret)1111 ath11k_warn(ab, "failed to setup rx tid %d\n", ret);1112 1113 return ret;1114}1115 1116int ath11k_dp_rx_ampdu_stop(struct ath11k *ar,1117 struct ieee80211_ampdu_params *params)1118{1119 struct ath11k_base *ab = ar->ab;1120 struct ath11k_peer *peer;1121 struct ath11k_sta *arsta = ath11k_sta_to_arsta(params->sta);1122 int vdev_id = arsta->arvif->vdev_id;1123 dma_addr_t paddr;1124 bool active;1125 int ret;1126 1127 spin_lock_bh(&ab->base_lock);1128 1129 peer = ath11k_peer_find(ab, vdev_id, params->sta->addr);1130 if (!peer) {1131 ath11k_warn(ab, "failed to find the peer to stop rx aggregation\n");1132 spin_unlock_bh(&ab->base_lock);1133 return -ENOENT;1134 }1135 1136 paddr = peer->rx_tid[params->tid].paddr;1137 active = peer->rx_tid[params->tid].active;1138 1139 if (!active) {1140 spin_unlock_bh(&ab->base_lock);1141 return 0;1142 }1143 1144 ret = ath11k_peer_rx_tid_reo_update(ar, peer, peer->rx_tid, 1, 0, false);1145 spin_unlock_bh(&ab->base_lock);1146 if (ret) {1147 ath11k_warn(ab, "failed to update reo for rx tid %d: %d\n",1148 params->tid, ret);1149 return ret;1150 }1151 1152 ret = ath11k_wmi_peer_rx_reorder_queue_setup(ar, vdev_id,1153 params->sta->addr, paddr,1154 params->tid, 1, 1);1155 if (ret)1156 ath11k_warn(ab, "failed to send wmi to delete rx tid %d\n",1157 ret);1158 1159 return ret;1160}1161 1162int ath11k_dp_peer_rx_pn_replay_config(struct ath11k_vif *arvif,1163 const u8 *peer_addr,1164 enum set_key_cmd key_cmd,1165 struct ieee80211_key_conf *key)1166{1167 struct ath11k *ar = arvif->ar;1168 struct ath11k_base *ab = ar->ab;1169 struct ath11k_hal_reo_cmd cmd = {0};1170 struct ath11k_peer *peer;1171 struct dp_rx_tid *rx_tid;1172 u8 tid;1173 int ret = 0;1174 1175 /* NOTE: Enable PN/TSC replay check offload only for unicast frames.1176 * We use mac80211 PN/TSC replay check functionality for bcast/mcast1177 * for now.1178 */1179 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))1180 return 0;1181 1182 cmd.flag |= HAL_REO_CMD_FLG_NEED_STATUS;1183 cmd.upd0 |= HAL_REO_CMD_UPD0_PN |1184 HAL_REO_CMD_UPD0_PN_SIZE |1185 HAL_REO_CMD_UPD0_PN_VALID |1186 HAL_REO_CMD_UPD0_PN_CHECK |1187 HAL_REO_CMD_UPD0_SVLD;1188 1189 switch (key->cipher) {1190 case WLAN_CIPHER_SUITE_TKIP:1191 case WLAN_CIPHER_SUITE_CCMP:1192 case WLAN_CIPHER_SUITE_CCMP_256:1193 case WLAN_CIPHER_SUITE_GCMP:1194 case WLAN_CIPHER_SUITE_GCMP_256:1195 if (key_cmd == SET_KEY) {1196 cmd.upd1 |= HAL_REO_CMD_UPD1_PN_CHECK;1197 cmd.pn_size = 48;1198 }1199 break;1200 default:1201 break;1202 }1203 1204 spin_lock_bh(&ab->base_lock);1205 1206 peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr);1207 if (!peer) {1208 ath11k_warn(ab, "failed to find the peer to configure pn replay detection\n");1209 spin_unlock_bh(&ab->base_lock);1210 return -ENOENT;1211 }1212 1213 for (tid = 0; tid <= IEEE80211_NUM_TIDS; tid++) {1214 rx_tid = &peer->rx_tid[tid];1215 if (!rx_tid->active)1216 continue;1217 cmd.addr_lo = lower_32_bits(rx_tid->paddr);1218 cmd.addr_hi = upper_32_bits(rx_tid->paddr);1219 ret = ath11k_dp_tx_send_reo_cmd(ab, rx_tid,1220 HAL_REO_CMD_UPDATE_RX_QUEUE,1221 &cmd, NULL);1222 if (ret) {1223 ath11k_warn(ab, "failed to configure rx tid %d queue for pn replay detection %d\n",1224 tid, ret);1225 break;1226 }1227 }1228 1229 spin_unlock_bh(&ab->base_lock);1230 1231 return ret;1232}1233 1234static inline int ath11k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats,1235 u16 peer_id)1236{1237 int i;1238 1239 for (i = 0; i < HTT_PPDU_STATS_MAX_USERS - 1; i++) {1240 if (ppdu_stats->user_stats[i].is_valid_peer_id) {1241 if (peer_id == ppdu_stats->user_stats[i].peer_id)1242 return i;1243 } else {1244 return i;1245 }1246 }1247 1248 return -EINVAL;1249}1250 1251static int ath11k_htt_tlv_ppdu_stats_parse(struct ath11k_base *ab,1252 u16 tag, u16 len, const void *ptr,1253 void *data)1254{1255 struct htt_ppdu_stats_info *ppdu_info;1256 struct htt_ppdu_user_stats *user_stats;1257 int cur_user;1258 u16 peer_id;1259 1260 ppdu_info = data;1261 1262 switch (tag) {1263 case HTT_PPDU_STATS_TAG_COMMON:1264 if (len < sizeof(struct htt_ppdu_stats_common)) {1265 ath11k_warn(ab, "Invalid len %d for the tag 0x%x\n",1266 len, tag);1267 return -EINVAL;1268 }1269 memcpy((void *)&ppdu_info->ppdu_stats.common, ptr,1270 sizeof(struct htt_ppdu_stats_common));1271 break;1272 case HTT_PPDU_STATS_TAG_USR_RATE:1273 if (len < sizeof(struct htt_ppdu_stats_user_rate)) {1274 ath11k_warn(ab, "Invalid len %d for the tag 0x%x\n",1275 len, tag);1276 return -EINVAL;1277 }1278 1279 peer_id = ((struct htt_ppdu_stats_user_rate *)ptr)->sw_peer_id;1280 cur_user = ath11k_get_ppdu_user_index(&ppdu_info->ppdu_stats,1281 peer_id);1282 if (cur_user < 0)1283 return -EINVAL;1284 user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user];1285 user_stats->peer_id = peer_id;1286 user_stats->is_valid_peer_id = true;1287 memcpy((void *)&user_stats->rate, ptr,1288 sizeof(struct htt_ppdu_stats_user_rate));1289 user_stats->tlv_flags |= BIT(tag);1290 break;1291 case HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON:1292 if (len < sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn)) {1293 ath11k_warn(ab, "Invalid len %d for the tag 0x%x\n",1294 len, tag);1295 return -EINVAL;1296 }1297 1298 peer_id = ((struct htt_ppdu_stats_usr_cmpltn_cmn *)ptr)->sw_peer_id;1299 cur_user = ath11k_get_ppdu_user_index(&ppdu_info->ppdu_stats,1300 peer_id);1301 if (cur_user < 0)1302 return -EINVAL;1303 user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user];1304 user_stats->peer_id = peer_id;1305 user_stats->is_valid_peer_id = true;1306 memcpy((void *)&user_stats->cmpltn_cmn, ptr,1307 sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn));1308 user_stats->tlv_flags |= BIT(tag);1309 break;1310 case HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS:1311 if (len <1312 sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)) {1313 ath11k_warn(ab, "Invalid len %d for the tag 0x%x\n",1314 len, tag);1315 return -EINVAL;1316 }1317 1318 peer_id =1319 ((struct htt_ppdu_stats_usr_cmpltn_ack_ba_status *)ptr)->sw_peer_id;1320 cur_user = ath11k_get_ppdu_user_index(&ppdu_info->ppdu_stats,1321 peer_id);1322 if (cur_user < 0)1323 return -EINVAL;1324 user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user];1325 user_stats->peer_id = peer_id;1326 user_stats->is_valid_peer_id = true;1327 memcpy((void *)&user_stats->ack_ba, ptr,1328 sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status));1329 user_stats->tlv_flags |= BIT(tag);1330 break;1331 }1332 return 0;1333}1334 1335int ath11k_dp_htt_tlv_iter(struct ath11k_base *ab, const void *ptr, size_t len,1336 int (*iter)(struct ath11k_base *ar, u16 tag, u16 len,1337 const void *ptr, void *data),1338 void *data)1339{1340 const struct htt_tlv *tlv;1341 const void *begin = ptr;1342 u16 tlv_tag, tlv_len;1343 int ret = -EINVAL;1344 1345 while (len > 0) {1346 if (len < sizeof(*tlv)) {1347 ath11k_err(ab, "htt tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n",1348 ptr - begin, len, sizeof(*tlv));1349 return -EINVAL;1350 }1351 tlv = (struct htt_tlv *)ptr;1352 tlv_tag = FIELD_GET(HTT_TLV_TAG, tlv->header);1353 tlv_len = FIELD_GET(HTT_TLV_LEN, tlv->header);1354 ptr += sizeof(*tlv);1355 len -= sizeof(*tlv);1356 1357 if (tlv_len > len) {1358 ath11k_err(ab, "htt tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n",1359 tlv_tag, ptr - begin, len, tlv_len);1360 return -EINVAL;1361 }1362 ret = iter(ab, tlv_tag, tlv_len, ptr, data);1363 if (ret == -ENOMEM)1364 return ret;1365 1366 ptr += tlv_len;1367 len -= tlv_len;1368 }1369 return 0;1370}1371 1372static void1373ath11k_update_per_peer_tx_stats(struct ath11k *ar,1374 struct htt_ppdu_stats *ppdu_stats, u8 user)1375{1376 struct ath11k_base *ab = ar->ab;1377 struct ath11k_peer *peer;1378 struct ieee80211_sta *sta;1379 struct ath11k_sta *arsta;1380 struct htt_ppdu_stats_user_rate *user_rate;1381 struct ath11k_per_peer_tx_stats *peer_stats = &ar->peer_tx_stats;1382 struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user];1383 struct htt_ppdu_stats_common *common = &ppdu_stats->common;1384 int ret;1385 u8 flags, mcs, nss, bw, sgi, dcm, rate_idx = 0;1386 u32 succ_bytes = 0;1387 u16 rate = 0, succ_pkts = 0;1388 u32 tx_duration = 0;1389 u8 tid = HTT_PPDU_STATS_NON_QOS_TID;1390 bool is_ampdu = false;1391 1392 if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE)))1393 return;1394 1395 if (usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON))1396 is_ampdu =1397 HTT_USR_CMPLTN_IS_AMPDU(usr_stats->cmpltn_cmn.flags);1398 1399 if (usr_stats->tlv_flags &1400 BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS)) {1401 succ_bytes = usr_stats->ack_ba.success_bytes;1402 succ_pkts = FIELD_GET(HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M,1403 usr_stats->ack_ba.info);1404 tid = FIELD_GET(HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM,1405 usr_stats->ack_ba.info);1406 }1407 1408 if (common->fes_duration_us)1409 tx_duration = common->fes_duration_us;1410 1411 user_rate = &usr_stats->rate;1412 flags = HTT_USR_RATE_PREAMBLE(user_rate->rate_flags);1413 bw = HTT_USR_RATE_BW(user_rate->rate_flags) - 2;1414 nss = HTT_USR_RATE_NSS(user_rate->rate_flags) + 1;1415 mcs = HTT_USR_RATE_MCS(user_rate->rate_flags);1416 sgi = HTT_USR_RATE_GI(user_rate->rate_flags);1417 dcm = HTT_USR_RATE_DCM(user_rate->rate_flags);1418 1419 /* Note: If host configured fixed rates and in some other special1420 * cases, the broadcast/management frames are sent in different rates.1421 * Firmware rate's control to be skipped for this?1422 */1423 1424 if (flags == WMI_RATE_PREAMBLE_HE && mcs > ATH11K_HE_MCS_MAX) {1425 ath11k_warn(ab, "Invalid HE mcs %d peer stats", mcs);1426 return;1427 }1428 1429 if (flags == WMI_RATE_PREAMBLE_VHT && mcs > ATH11K_VHT_MCS_MAX) {1430 ath11k_warn(ab, "Invalid VHT mcs %d peer stats", mcs);1431 return;1432 }1433 1434 if (flags == WMI_RATE_PREAMBLE_HT && (mcs > ATH11K_HT_MCS_MAX || nss < 1)) {1435 ath11k_warn(ab, "Invalid HT mcs %d nss %d peer stats",1436 mcs, nss);1437 return;1438 }1439 1440 if (flags == WMI_RATE_PREAMBLE_CCK || flags == WMI_RATE_PREAMBLE_OFDM) {1441 ret = ath11k_mac_hw_ratecode_to_legacy_rate(mcs,1442 flags,1443 &rate_idx,1444 &rate);1445 if (ret < 0)1446 return;1447 }1448 1449 rcu_read_lock();1450 spin_lock_bh(&ab->base_lock);1451 peer = ath11k_peer_find_by_id(ab, usr_stats->peer_id);1452 1453 if (!peer || !peer->sta) {1454 spin_unlock_bh(&ab->base_lock);1455 rcu_read_unlock();1456 return;1457 }1458 1459 sta = peer->sta;1460 arsta = ath11k_sta_to_arsta(sta);1461 1462 memset(&arsta->txrate, 0, sizeof(arsta->txrate));1463 1464 switch (flags) {1465 case WMI_RATE_PREAMBLE_OFDM:1466 arsta->txrate.legacy = rate;1467 break;1468 case WMI_RATE_PREAMBLE_CCK:1469 arsta->txrate.legacy = rate;1470 break;1471 case WMI_RATE_PREAMBLE_HT:1472 arsta->txrate.mcs = mcs + 8 * (nss - 1);1473 arsta->txrate.flags = RATE_INFO_FLAGS_MCS;1474 if (sgi)1475 arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;1476 break;1477 case WMI_RATE_PREAMBLE_VHT:1478 arsta->txrate.mcs = mcs;1479 arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;1480 if (sgi)1481 arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;1482 break;1483 case WMI_RATE_PREAMBLE_HE:1484 arsta->txrate.mcs = mcs;1485 arsta->txrate.flags = RATE_INFO_FLAGS_HE_MCS;1486 arsta->txrate.he_dcm = dcm;1487 arsta->txrate.he_gi = ath11k_mac_he_gi_to_nl80211_he_gi(sgi);1488 arsta->txrate.he_ru_alloc = ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc1489 ((user_rate->ru_end -1490 user_rate->ru_start) + 1);1491 break;1492 }1493 1494 arsta->txrate.nss = nss;1495 1496 arsta->txrate.bw = ath11k_mac_bw_to_mac80211_bw(bw);1497 arsta->tx_duration += tx_duration;1498 memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info));1499 1500 /* PPDU stats reported for mgmt packet doesn't have valid tx bytes.1501 * So skip peer stats update for mgmt packets.1502 */1503 if (tid < HTT_PPDU_STATS_NON_QOS_TID) {1504 memset(peer_stats, 0, sizeof(*peer_stats));1505 peer_stats->succ_pkts = succ_pkts;1506 peer_stats->succ_bytes = succ_bytes;1507 peer_stats->is_ampdu = is_ampdu;1508 peer_stats->duration = tx_duration;1509 peer_stats->ba_fails =1510 HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) +1511 HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags);1512 1513 if (ath11k_debugfs_is_extd_tx_stats_enabled(ar))1514 ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx);1515 }1516 1517 spin_unlock_bh(&ab->base_lock);1518 rcu_read_unlock();1519}1520 1521static void ath11k_htt_update_ppdu_stats(struct ath11k *ar,1522 struct htt_ppdu_stats *ppdu_stats)1523{1524 u8 user;1525 1526 for (user = 0; user < HTT_PPDU_STATS_MAX_USERS - 1; user++)1527 ath11k_update_per_peer_tx_stats(ar, ppdu_stats, user);1528}1529 1530static1531struct htt_ppdu_stats_info *ath11k_dp_htt_get_ppdu_desc(struct ath11k *ar,1532 u32 ppdu_id)1533{1534 struct htt_ppdu_stats_info *ppdu_info;1535 1536 lockdep_assert_held(&ar->data_lock);1537 1538 if (!list_empty(&ar->ppdu_stats_info)) {1539 list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) {1540 if (ppdu_info->ppdu_id == ppdu_id)1541 return ppdu_info;1542 }1543 1544 if (ar->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) {1545 ppdu_info = list_first_entry(&ar->ppdu_stats_info,1546 typeof(*ppdu_info), list);1547 list_del(&ppdu_info->list);1548 ar->ppdu_stat_list_depth--;1549 ath11k_htt_update_ppdu_stats(ar, &ppdu_info->ppdu_stats);1550 kfree(ppdu_info);1551 }1552 }1553 1554 ppdu_info = kzalloc(sizeof(*ppdu_info), GFP_ATOMIC);1555 if (!ppdu_info)1556 return NULL;1557 1558 list_add_tail(&ppdu_info->list, &ar->ppdu_stats_info);1559 ar->ppdu_stat_list_depth++;1560 1561 return ppdu_info;1562}1563 1564static int ath11k_htt_pull_ppdu_stats(struct ath11k_base *ab,1565 struct sk_buff *skb)1566{1567 struct ath11k_htt_ppdu_stats_msg *msg;1568 struct htt_ppdu_stats_info *ppdu_info;1569 struct ath11k *ar;1570 int ret;1571 u8 pdev_id;1572 u32 ppdu_id, len;1573 1574 msg = (struct ath11k_htt_ppdu_stats_msg *)skb->data;1575 len = FIELD_GET(HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE, msg->info);1576 pdev_id = FIELD_GET(HTT_T2H_PPDU_STATS_INFO_PDEV_ID, msg->info);1577 ppdu_id = msg->ppdu_id;1578 1579 rcu_read_lock();1580 ar = ath11k_mac_get_ar_by_pdev_id(ab, pdev_id);1581 if (!ar) {1582 ret = -EINVAL;1583 goto out;1584 }1585 1586 if (ath11k_debugfs_is_pktlog_lite_mode_enabled(ar))1587 trace_ath11k_htt_ppdu_stats(ar, skb->data, len);1588 1589 spin_lock_bh(&ar->data_lock);1590 ppdu_info = ath11k_dp_htt_get_ppdu_desc(ar, ppdu_id);1591 if (!ppdu_info) {1592 ret = -EINVAL;1593 goto out_unlock_data;1594 }1595 1596 ppdu_info->ppdu_id = ppdu_id;1597 ret = ath11k_dp_htt_tlv_iter(ab, msg->data, len,1598 ath11k_htt_tlv_ppdu_stats_parse,1599 (void *)ppdu_info);1600 if (ret) {1601 ath11k_warn(ab, "Failed to parse tlv %d\n", ret);1602 goto out_unlock_data;1603 }1604 1605out_unlock_data:1606 spin_unlock_bh(&ar->data_lock);1607 1608out:1609 rcu_read_unlock();1610 1611 return ret;1612}1613 1614static void ath11k_htt_pktlog(struct ath11k_base *ab, struct sk_buff *skb)1615{1616 struct htt_pktlog_msg *data = (struct htt_pktlog_msg *)skb->data;1617 struct ath_pktlog_hdr *hdr = (struct ath_pktlog_hdr *)data;1618 struct ath11k *ar;1619 u8 pdev_id;1620 1621 pdev_id = FIELD_GET(HTT_T2H_PPDU_STATS_INFO_PDEV_ID, data->hdr);1622 1623 rcu_read_lock();1624 1625 ar = ath11k_mac_get_ar_by_pdev_id(ab, pdev_id);1626 if (!ar) {1627 ath11k_warn(ab, "invalid pdev id %d on htt pktlog\n", pdev_id);1628 goto out;1629 }1630 1631 trace_ath11k_htt_pktlog(ar, data->payload, hdr->size,1632 ar->ab->pktlog_defs_checksum);1633 1634out:1635 rcu_read_unlock();1636}1637 1638static void ath11k_htt_backpressure_event_handler(struct ath11k_base *ab,1639 struct sk_buff *skb)1640{1641 u32 *data = (u32 *)skb->data;1642 u8 pdev_id, ring_type, ring_id, pdev_idx;1643 u16 hp, tp;1644 u32 backpressure_time;1645 struct ath11k_bp_stats *bp_stats;1646 1647 pdev_id = FIELD_GET(HTT_BACKPRESSURE_EVENT_PDEV_ID_M, *data);1648 ring_type = FIELD_GET(HTT_BACKPRESSURE_EVENT_RING_TYPE_M, *data);1649 ring_id = FIELD_GET(HTT_BACKPRESSURE_EVENT_RING_ID_M, *data);1650 ++data;1651 1652 hp = FIELD_GET(HTT_BACKPRESSURE_EVENT_HP_M, *data);1653 tp = FIELD_GET(HTT_BACKPRESSURE_EVENT_TP_M, *data);1654 ++data;1655 1656 backpressure_time = *data;1657 1658 ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "backpressure event, pdev %d, ring type %d,ring id %d, hp %d tp %d, backpressure time %d\n",1659 pdev_id, ring_type, ring_id, hp, tp, backpressure_time);1660 1661 if (ring_type == HTT_BACKPRESSURE_UMAC_RING_TYPE) {1662 if (ring_id >= HTT_SW_UMAC_RING_IDX_MAX)1663 return;1664 1665 bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[ring_id];1666 } else if (ring_type == HTT_BACKPRESSURE_LMAC_RING_TYPE) {1667 pdev_idx = DP_HW2SW_MACID(pdev_id);1668 1669 if (ring_id >= HTT_SW_LMAC_RING_IDX_MAX || pdev_idx >= MAX_RADIOS)1670 return;1671 1672 bp_stats = &ab->soc_stats.bp_stats.lmac_ring_bp_stats[ring_id][pdev_idx];1673 } else {1674 ath11k_warn(ab, "unknown ring type received in htt bp event %d\n",1675 ring_type);1676 return;1677 }1678 1679 spin_lock_bh(&ab->base_lock);1680 bp_stats->hp = hp;1681 bp_stats->tp = tp;1682 bp_stats->count++;1683 bp_stats->jiffies = jiffies;1684 spin_unlock_bh(&ab->base_lock);1685}1686 1687void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab,1688 struct sk_buff *skb)1689{1690 struct ath11k_dp *dp = &ab->dp;1691 struct htt_resp_msg *resp = (struct htt_resp_msg *)skb->data;1692 enum htt_t2h_msg_type type = FIELD_GET(HTT_T2H_MSG_TYPE, *(u32 *)resp);1693 u16 peer_id;1694 u8 vdev_id;1695 u8 mac_addr[ETH_ALEN];1696 u16 peer_mac_h16;1697 u16 ast_hash;1698 u16 hw_peer_id;1699 1700 ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type);1701 1702 switch (type) {1703 case HTT_T2H_MSG_TYPE_VERSION_CONF:1704 dp->htt_tgt_ver_major = FIELD_GET(HTT_T2H_VERSION_CONF_MAJOR,1705 resp->version_msg.version);1706 dp->htt_tgt_ver_minor = FIELD_GET(HTT_T2H_VERSION_CONF_MINOR,1707 resp->version_msg.version);1708 complete(&dp->htt_tgt_version_received);1709 break;1710 case HTT_T2H_MSG_TYPE_PEER_MAP:1711 vdev_id = FIELD_GET(HTT_T2H_PEER_MAP_INFO_VDEV_ID,1712 resp->peer_map_ev.info);1713 peer_id = FIELD_GET(HTT_T2H_PEER_MAP_INFO_PEER_ID,1714 resp->peer_map_ev.info);1715 peer_mac_h16 = FIELD_GET(HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16,1716 resp->peer_map_ev.info1);1717 ath11k_dp_get_mac_addr(resp->peer_map_ev.mac_addr_l32,1718 peer_mac_h16, mac_addr);1719 ath11k_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0);1720 break;1721 case HTT_T2H_MSG_TYPE_PEER_MAP2:1722 vdev_id = FIELD_GET(HTT_T2H_PEER_MAP_INFO_VDEV_ID,1723 resp->peer_map_ev.info);1724 peer_id = FIELD_GET(HTT_T2H_PEER_MAP_INFO_PEER_ID,1725 resp->peer_map_ev.info);1726 peer_mac_h16 = FIELD_GET(HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16,1727 resp->peer_map_ev.info1);1728 ath11k_dp_get_mac_addr(resp->peer_map_ev.mac_addr_l32,1729 peer_mac_h16, mac_addr);1730 ast_hash = FIELD_GET(HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL,1731 resp->peer_map_ev.info2);1732 hw_peer_id = FIELD_GET(HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID,1733 resp->peer_map_ev.info1);1734 ath11k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash,1735 hw_peer_id);1736 break;1737 case HTT_T2H_MSG_TYPE_PEER_UNMAP:1738 case HTT_T2H_MSG_TYPE_PEER_UNMAP2:1739 peer_id = FIELD_GET(HTT_T2H_PEER_UNMAP_INFO_PEER_ID,1740 resp->peer_unmap_ev.info);1741 ath11k_peer_unmap_event(ab, peer_id);1742 break;1743 case HTT_T2H_MSG_TYPE_PPDU_STATS_IND:1744 ath11k_htt_pull_ppdu_stats(ab, skb);1745 break;1746 case HTT_T2H_MSG_TYPE_EXT_STATS_CONF:1747 ath11k_debugfs_htt_ext_stats_handler(ab, skb);1748 break;1749 case HTT_T2H_MSG_TYPE_PKTLOG:1750 ath11k_htt_pktlog(ab, skb);1751 break;1752 case HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND:1753 ath11k_htt_backpressure_event_handler(ab, skb);1754 break;1755 default:1756 ath11k_warn(ab, "htt event %d not handled\n", type);1757 break;1758 }1759 1760 dev_kfree_skb_any(skb);1761}1762 1763static int ath11k_dp_rx_msdu_coalesce(struct ath11k *ar,1764 struct sk_buff_head *msdu_list,1765 struct sk_buff *first, struct sk_buff *last,1766 u8 l3pad_bytes, int msdu_len)1767{1768 struct ath11k_base *ab = ar->ab;1769 struct sk_buff *skb;1770 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(first);1771 int buf_first_hdr_len, buf_first_len;1772 struct hal_rx_desc *ldesc;1773 int space_extra, rem_len, buf_len;1774 u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;1775 1776 /* As the msdu is spread across multiple rx buffers,1777 * find the offset to the start of msdu for computing1778 * the length of the msdu in the first buffer.1779 */1780 buf_first_hdr_len = hal_rx_desc_sz + l3pad_bytes;1781 buf_first_len = DP_RX_BUFFER_SIZE - buf_first_hdr_len;1782 1783 if (WARN_ON_ONCE(msdu_len <= buf_first_len)) {1784 skb_put(first, buf_first_hdr_len + msdu_len);1785 skb_pull(first, buf_first_hdr_len);1786 return 0;1787 }1788 1789 ldesc = (struct hal_rx_desc *)last->data;1790 rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(ab, ldesc);1791 rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(ab, ldesc);1792 1793 /* MSDU spans over multiple buffers because the length of the MSDU1794 * exceeds DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. So assume the data1795 * in the first buf is of length DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE.1796 */1797 skb_put(first, DP_RX_BUFFER_SIZE);1798 skb_pull(first, buf_first_hdr_len);1799 1800 /* When an MSDU spread over multiple buffers attention, MSDU_END and1801 * MPDU_END tlvs are valid only in the last buffer. Copy those tlvs.1802 */1803 ath11k_dp_rx_desc_end_tlv_copy(ab, rxcb->rx_desc, ldesc);1804 1805 space_extra = msdu_len - (buf_first_len + skb_tailroom(first));1806 if (space_extra > 0 &&1807 (pskb_expand_head(first, 0, space_extra, GFP_ATOMIC) < 0)) {1808 /* Free up all buffers of the MSDU */1809 while ((skb = __skb_dequeue(msdu_list)) != NULL) {1810 rxcb = ATH11K_SKB_RXCB(skb);1811 if (!rxcb->is_continuation) {1812 dev_kfree_skb_any(skb);1813 break;1814 }1815 dev_kfree_skb_any(skb);1816 }1817 return -ENOMEM;1818 }1819 1820 rem_len = msdu_len - buf_first_len;1821 while ((skb = __skb_dequeue(msdu_list)) != NULL && rem_len > 0) {1822 rxcb = ATH11K_SKB_RXCB(skb);1823 if (rxcb->is_continuation)1824 buf_len = DP_RX_BUFFER_SIZE - hal_rx_desc_sz;1825 else1826 buf_len = rem_len;1827 1828 if (buf_len > (DP_RX_BUFFER_SIZE - hal_rx_desc_sz)) {1829 WARN_ON_ONCE(1);1830 dev_kfree_skb_any(skb);1831 return -EINVAL;1832 }1833 1834 skb_put(skb, buf_len + hal_rx_desc_sz);1835 skb_pull(skb, hal_rx_desc_sz);1836 skb_copy_from_linear_data(skb, skb_put(first, buf_len),1837 buf_len);1838 dev_kfree_skb_any(skb);1839 1840 rem_len -= buf_len;1841 if (!rxcb->is_continuation)1842 break;1843 }1844 1845 return 0;1846}1847 1848static struct sk_buff *ath11k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list,1849 struct sk_buff *first)1850{1851 struct sk_buff *skb;1852 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(first);1853 1854 if (!rxcb->is_continuation)1855 return first;1856 1857 skb_queue_walk(msdu_list, skb) {1858 rxcb = ATH11K_SKB_RXCB(skb);1859 if (!rxcb->is_continuation)1860 return skb;1861 }1862 1863 return NULL;1864}1865 1866static void ath11k_dp_rx_h_csum_offload(struct ath11k *ar, struct sk_buff *msdu)1867{1868 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);1869 struct rx_attention *rx_attention;1870 bool ip_csum_fail, l4_csum_fail;1871 1872 rx_attention = ath11k_dp_rx_get_attention(ar->ab, rxcb->rx_desc);1873 ip_csum_fail = ath11k_dp_rx_h_attn_ip_cksum_fail(rx_attention);1874 l4_csum_fail = ath11k_dp_rx_h_attn_l4_cksum_fail(rx_attention);1875 1876 msdu->ip_summed = (ip_csum_fail || l4_csum_fail) ?1877 CHECKSUM_NONE : CHECKSUM_UNNECESSARY;1878}1879 1880int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, enum hal_encrypt_type enctype)1881{1882 switch (enctype) {1883 case HAL_ENCRYPT_TYPE_OPEN:1884 case HAL_ENCRYPT_TYPE_TKIP_NO_MIC:1885 case HAL_ENCRYPT_TYPE_TKIP_MIC:1886 return 0;1887 case HAL_ENCRYPT_TYPE_CCMP_128:1888 return IEEE80211_CCMP_MIC_LEN;1889 case HAL_ENCRYPT_TYPE_CCMP_256:1890 return IEEE80211_CCMP_256_MIC_LEN;1891 case HAL_ENCRYPT_TYPE_GCMP_128:1892 case HAL_ENCRYPT_TYPE_AES_GCMP_256:1893 return IEEE80211_GCMP_MIC_LEN;1894 case HAL_ENCRYPT_TYPE_WEP_40:1895 case HAL_ENCRYPT_TYPE_WEP_104:1896 case HAL_ENCRYPT_TYPE_WEP_128:1897 case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4:1898 case HAL_ENCRYPT_TYPE_WAPI:1899 break;1900 }1901 1902 ath11k_warn(ar->ab, "unsupported encryption type %d for mic len\n", enctype);1903 return 0;1904}1905 1906static int ath11k_dp_rx_crypto_param_len(struct ath11k *ar,1907 enum hal_encrypt_type enctype)1908{1909 switch (enctype) {1910 case HAL_ENCRYPT_TYPE_OPEN:1911 return 0;1912 case HAL_ENCRYPT_TYPE_TKIP_NO_MIC:1913 case HAL_ENCRYPT_TYPE_TKIP_MIC:1914 return IEEE80211_TKIP_IV_LEN;1915 case HAL_ENCRYPT_TYPE_CCMP_128:1916 return IEEE80211_CCMP_HDR_LEN;1917 case HAL_ENCRYPT_TYPE_CCMP_256:1918 return IEEE80211_CCMP_256_HDR_LEN;1919 case HAL_ENCRYPT_TYPE_GCMP_128:1920 case HAL_ENCRYPT_TYPE_AES_GCMP_256:1921 return IEEE80211_GCMP_HDR_LEN;1922 case HAL_ENCRYPT_TYPE_WEP_40:1923 case HAL_ENCRYPT_TYPE_WEP_104:1924 case HAL_ENCRYPT_TYPE_WEP_128:1925 case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4:1926 case HAL_ENCRYPT_TYPE_WAPI:1927 break;1928 }1929 1930 ath11k_warn(ar->ab, "unsupported encryption type %d\n", enctype);1931 return 0;1932}1933 1934static int ath11k_dp_rx_crypto_icv_len(struct ath11k *ar,1935 enum hal_encrypt_type enctype)1936{1937 switch (enctype) {1938 case HAL_ENCRYPT_TYPE_OPEN:1939 case HAL_ENCRYPT_TYPE_CCMP_128:1940 case HAL_ENCRYPT_TYPE_CCMP_256:1941 case HAL_ENCRYPT_TYPE_GCMP_128:1942 case HAL_ENCRYPT_TYPE_AES_GCMP_256:1943 return 0;1944 case HAL_ENCRYPT_TYPE_TKIP_NO_MIC:1945 case HAL_ENCRYPT_TYPE_TKIP_MIC:1946 return IEEE80211_TKIP_ICV_LEN;1947 case HAL_ENCRYPT_TYPE_WEP_40:1948 case HAL_ENCRYPT_TYPE_WEP_104:1949 case HAL_ENCRYPT_TYPE_WEP_128:1950 case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4:1951 case HAL_ENCRYPT_TYPE_WAPI:1952 break;1953 }1954 1955 ath11k_warn(ar->ab, "unsupported encryption type %d\n", enctype);1956 return 0;1957}1958 1959static void ath11k_dp_rx_h_undecap_nwifi(struct ath11k *ar,1960 struct sk_buff *msdu,1961 u8 *first_hdr,1962 enum hal_encrypt_type enctype,1963 struct ieee80211_rx_status *status)1964{1965 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);1966 u8 decap_hdr[DP_MAX_NWIFI_HDR_LEN];1967 struct ieee80211_hdr *hdr;1968 size_t hdr_len;1969 u8 da[ETH_ALEN];1970 u8 sa[ETH_ALEN];1971 u16 qos_ctl = 0;1972 u8 *qos;1973 1974 /* copy SA & DA and pull decapped header */1975 hdr = (struct ieee80211_hdr *)msdu->data;1976 hdr_len = ieee80211_hdrlen(hdr->frame_control);1977 ether_addr_copy(da, ieee80211_get_DA(hdr));1978 ether_addr_copy(sa, ieee80211_get_SA(hdr));1979 skb_pull(msdu, ieee80211_hdrlen(hdr->frame_control));1980 1981 if (rxcb->is_first_msdu) {1982 /* original 802.11 header is valid for the first msdu1983 * hence we can reuse the same header1984 */1985 hdr = (struct ieee80211_hdr *)first_hdr;1986 hdr_len = ieee80211_hdrlen(hdr->frame_control);1987 1988 /* Each A-MSDU subframe will be reported as a separate MSDU,1989 * so strip the A-MSDU bit from QoS Ctl.1990 */1991 if (ieee80211_is_data_qos(hdr->frame_control)) {1992 qos = ieee80211_get_qos_ctl(hdr);1993 qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;1994 }1995 } else {1996 /* Rebuild qos header if this is a middle/last msdu */1997 hdr->frame_control |= __cpu_to_le16(IEEE80211_STYPE_QOS_DATA);1998 1999 /* Reset the order bit as the HT_Control header is stripped */2000 hdr->frame_control &= ~(__cpu_to_le16(IEEE80211_FCTL_ORDER));2001 2002 qos_ctl = rxcb->tid;2003 2004 if (ath11k_dp_rx_h_msdu_start_mesh_ctl_present(ar->ab, rxcb->rx_desc))2005 qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT;2006 2007 /* TODO Add other QoS ctl fields when required */2008 2009 /* copy decap header before overwriting for reuse below */2010 memcpy(decap_hdr, (uint8_t *)hdr, hdr_len);2011 }2012 2013 if (!(status->flag & RX_FLAG_IV_STRIPPED)) {2014 memcpy(skb_push(msdu,2015 ath11k_dp_rx_crypto_param_len(ar, enctype)),2016 (void *)hdr + hdr_len,2017 ath11k_dp_rx_crypto_param_len(ar, enctype));2018 }2019 2020 if (!rxcb->is_first_msdu) {2021 memcpy(skb_push(msdu,2022 IEEE80211_QOS_CTL_LEN), &qos_ctl,2023 IEEE80211_QOS_CTL_LEN);2024 memcpy(skb_push(msdu, hdr_len), decap_hdr, hdr_len);2025 return;2026 }2027 2028 memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);2029 2030 /* original 802.11 header has a different DA and in2031 * case of 4addr it may also have different SA2032 */2033 hdr = (struct ieee80211_hdr *)msdu->data;2034 ether_addr_copy(ieee80211_get_DA(hdr), da);2035 ether_addr_copy(ieee80211_get_SA(hdr), sa);2036}2037 2038static void ath11k_dp_rx_h_undecap_raw(struct ath11k *ar, struct sk_buff *msdu,2039 enum hal_encrypt_type enctype,2040 struct ieee80211_rx_status *status,2041 bool decrypted)2042{2043 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);2044 struct ieee80211_hdr *hdr;2045 size_t hdr_len;2046 size_t crypto_len;2047 2048 if (!rxcb->is_first_msdu ||2049 !(rxcb->is_first_msdu && rxcb->is_last_msdu)) {2050 WARN_ON_ONCE(1);2051 return;2052 }2053 2054 skb_trim(msdu, msdu->len - FCS_LEN);2055 2056 if (!decrypted)2057 return;2058 2059 hdr = (void *)msdu->data;2060 2061 /* Tail */2062 if (status->flag & RX_FLAG_IV_STRIPPED) {2063 skb_trim(msdu, msdu->len -2064 ath11k_dp_rx_crypto_mic_len(ar, enctype));2065 2066 skb_trim(msdu, msdu->len -2067 ath11k_dp_rx_crypto_icv_len(ar, enctype));2068 } else {2069 /* MIC */2070 if (status->flag & RX_FLAG_MIC_STRIPPED)2071 skb_trim(msdu, msdu->len -2072 ath11k_dp_rx_crypto_mic_len(ar, enctype));2073 2074 /* ICV */2075 if (status->flag & RX_FLAG_ICV_STRIPPED)2076 skb_trim(msdu, msdu->len -2077 ath11k_dp_rx_crypto_icv_len(ar, enctype));2078 }2079 2080 /* MMIC */2081 if ((status->flag & RX_FLAG_MMIC_STRIPPED) &&2082 !ieee80211_has_morefrags(hdr->frame_control) &&2083 enctype == HAL_ENCRYPT_TYPE_TKIP_MIC)2084 skb_trim(msdu, msdu->len - IEEE80211_CCMP_MIC_LEN);2085 2086 /* Head */2087 if (status->flag & RX_FLAG_IV_STRIPPED) {2088 hdr_len = ieee80211_hdrlen(hdr->frame_control);2089 crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype);2090 2091 memmove((void *)msdu->data + crypto_len,2092 (void *)msdu->data, hdr_len);2093 skb_pull(msdu, crypto_len);2094 }2095}2096 2097static void *ath11k_dp_rx_h_find_rfc1042(struct ath11k *ar,2098 struct sk_buff *msdu,2099 enum hal_encrypt_type enctype)2100{2101 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);2102 struct ieee80211_hdr *hdr;2103 size_t hdr_len, crypto_len;2104 void *rfc1042;2105 bool is_amsdu;2106 2107 is_amsdu = !(rxcb->is_first_msdu && rxcb->is_last_msdu);2108 hdr = (struct ieee80211_hdr *)ath11k_dp_rx_h_80211_hdr(ar->ab, rxcb->rx_desc);2109 rfc1042 = hdr;2110 2111 if (rxcb->is_first_msdu) {2112 hdr_len = ieee80211_hdrlen(hdr->frame_control);2113 crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype);2114 2115 rfc1042 += hdr_len + crypto_len;2116 }2117 2118 if (is_amsdu)2119 rfc1042 += sizeof(struct ath11k_dp_amsdu_subframe_hdr);2120 2121 return rfc1042;2122}2123 2124static void ath11k_dp_rx_h_undecap_eth(struct ath11k *ar,2125 struct sk_buff *msdu,2126 u8 *first_hdr,2127 enum hal_encrypt_type enctype,2128 struct ieee80211_rx_status *status)2129{2130 struct ieee80211_hdr *hdr;2131 struct ethhdr *eth;2132 size_t hdr_len;2133 u8 da[ETH_ALEN];2134 u8 sa[ETH_ALEN];2135 void *rfc1042;2136 2137 rfc1042 = ath11k_dp_rx_h_find_rfc1042(ar, msdu, enctype);2138 if (WARN_ON_ONCE(!rfc1042))2139 return;2140 2141 /* pull decapped header and copy SA & DA */2142 eth = (struct ethhdr *)msdu->data;2143 ether_addr_copy(da, eth->h_dest);2144 ether_addr_copy(sa, eth->h_source);2145 skb_pull(msdu, sizeof(struct ethhdr));2146 2147 /* push rfc1042/llc/snap */2148 memcpy(skb_push(msdu, sizeof(struct ath11k_dp_rfc1042_hdr)), rfc1042,2149 sizeof(struct ath11k_dp_rfc1042_hdr));2150 2151 /* push original 802.11 header */2152 hdr = (struct ieee80211_hdr *)first_hdr;2153 hdr_len = ieee80211_hdrlen(hdr->frame_control);2154 2155 if (!(status->flag & RX_FLAG_IV_STRIPPED)) {2156 memcpy(skb_push(msdu,2157 ath11k_dp_rx_crypto_param_len(ar, enctype)),2158 (void *)hdr + hdr_len,2159 ath11k_dp_rx_crypto_param_len(ar, enctype));2160 }2161 2162 memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);2163 2164 /* original 802.11 header has a different DA and in2165 * case of 4addr it may also have different SA2166 */2167 hdr = (struct ieee80211_hdr *)msdu->data;2168 ether_addr_copy(ieee80211_get_DA(hdr), da);2169 ether_addr_copy(ieee80211_get_SA(hdr), sa);2170}2171 2172static void ath11k_dp_rx_h_undecap(struct ath11k *ar, struct sk_buff *msdu,2173 struct hal_rx_desc *rx_desc,2174 enum hal_encrypt_type enctype,2175 struct ieee80211_rx_status *status,2176 bool decrypted)2177{2178 u8 *first_hdr;2179 u8 decap;2180 struct ethhdr *ehdr;2181 2182 first_hdr = ath11k_dp_rx_h_80211_hdr(ar->ab, rx_desc);2183 decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc);2184 2185 switch (decap) {2186 case DP_RX_DECAP_TYPE_NATIVE_WIFI:2187 ath11k_dp_rx_h_undecap_nwifi(ar, msdu, first_hdr,2188 enctype, status);2189 break;2190 case DP_RX_DECAP_TYPE_RAW:2191 ath11k_dp_rx_h_undecap_raw(ar, msdu, enctype, status,2192 decrypted);2193 break;2194 case DP_RX_DECAP_TYPE_ETHERNET2_DIX:2195 ehdr = (struct ethhdr *)msdu->data;2196 2197 /* mac80211 allows fast path only for authorized STA */2198 if (ehdr->h_proto == cpu_to_be16(ETH_P_PAE)) {2199 ATH11K_SKB_RXCB(msdu)->is_eapol = true;2200 ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr,2201 enctype, status);2202 break;2203 }2204 2205 /* PN for mcast packets will be validated in mac80211;2206 * remove eth header and add 802.11 header.2207 */2208 if (ATH11K_SKB_RXCB(msdu)->is_mcbc && decrypted)2209 ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr,2210 enctype, status);2211 break;2212 case DP_RX_DECAP_TYPE_8023:2213 /* TODO: Handle undecap for these formats */2214 break;2215 }2216}2217 2218static struct ath11k_peer *2219ath11k_dp_rx_h_find_peer(struct ath11k_base *ab, struct sk_buff *msdu)2220{2221 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);2222 struct hal_rx_desc *rx_desc = rxcb->rx_desc;2223 struct ath11k_peer *peer = NULL;2224 2225 lockdep_assert_held(&ab->base_lock);2226 2227 if (rxcb->peer_id)2228 peer = ath11k_peer_find_by_id(ab, rxcb->peer_id);2229 2230 if (peer)2231 return peer;2232 2233 if (!rx_desc || !(ath11k_dp_rxdesc_mac_addr2_valid(ab, rx_desc)))2234 return NULL;2235 2236 peer = ath11k_peer_find_by_addr(ab,2237 ath11k_dp_rxdesc_mpdu_start_addr2(ab, rx_desc));2238 return peer;2239}2240 2241static void ath11k_dp_rx_h_mpdu(struct ath11k *ar,2242 struct sk_buff *msdu,2243 struct hal_rx_desc *rx_desc,2244 struct ieee80211_rx_status *rx_status)2245{2246 bool fill_crypto_hdr;2247 enum hal_encrypt_type enctype;2248 bool is_decrypted = false;2249 struct ath11k_skb_rxcb *rxcb;2250 struct ieee80211_hdr *hdr;2251 struct ath11k_peer *peer;2252 struct rx_attention *rx_attention;2253 u32 err_bitmap;2254 2255 /* PN for multicast packets will be checked in mac80211 */2256 rxcb = ATH11K_SKB_RXCB(msdu);2257 fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc);2258 rxcb->is_mcbc = fill_crypto_hdr;2259 2260 if (rxcb->is_mcbc) {2261 rxcb->peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(ar->ab, rx_desc);2262 rxcb->seq_no = ath11k_dp_rx_h_mpdu_start_seq_no(ar->ab, rx_desc);2263 }2264 2265 spin_lock_bh(&ar->ab->base_lock);2266 peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu);2267 if (peer) {2268 if (rxcb->is_mcbc)2269 enctype = peer->sec_type_grp;2270 else2271 enctype = peer->sec_type;2272 } else {2273 enctype = ath11k_dp_rx_h_mpdu_start_enctype(ar->ab, rx_desc);2274 }2275 spin_unlock_bh(&ar->ab->base_lock);2276 2277 rx_attention = ath11k_dp_rx_get_attention(ar->ab, rx_desc);2278 err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention);2279 if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap)2280 is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_attention);2281 2282 /* Clear per-MPDU flags while leaving per-PPDU flags intact */2283 rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC |2284 RX_FLAG_MMIC_ERROR |2285 RX_FLAG_DECRYPTED |2286 RX_FLAG_IV_STRIPPED |2287 RX_FLAG_MMIC_STRIPPED);2288 2289 if (err_bitmap & DP_RX_MPDU_ERR_FCS)2290 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;2291 if (err_bitmap & DP_RX_MPDU_ERR_TKIP_MIC)2292 rx_status->flag |= RX_FLAG_MMIC_ERROR;2293 2294 if (is_decrypted) {2295 rx_status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_MMIC_STRIPPED;2296 2297 if (fill_crypto_hdr)2298 rx_status->flag |= RX_FLAG_MIC_STRIPPED |2299 RX_FLAG_ICV_STRIPPED;2300 else2301 rx_status->flag |= RX_FLAG_IV_STRIPPED |2302 RX_FLAG_PN_VALIDATED;2303 }2304 2305 ath11k_dp_rx_h_csum_offload(ar, msdu);2306 ath11k_dp_rx_h_undecap(ar, msdu, rx_desc,2307 enctype, rx_status, is_decrypted);2308 2309 if (!is_decrypted || fill_crypto_hdr)2310 return;2311 2312 if (ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc) !=2313 DP_RX_DECAP_TYPE_ETHERNET2_DIX) {2314 hdr = (void *)msdu->data;2315 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);2316 }2317}2318 2319static void ath11k_dp_rx_h_rate(struct ath11k *ar, struct hal_rx_desc *rx_desc,2320 struct ieee80211_rx_status *rx_status)2321{2322 struct ieee80211_supported_band *sband;2323 enum rx_msdu_start_pkt_type pkt_type;2324 u8 bw;2325 u8 rate_mcs, nss;2326 u8 sgi;2327 bool is_cck, is_ldpc;2328 2329 pkt_type = ath11k_dp_rx_h_msdu_start_pkt_type(ar->ab, rx_desc);2330 bw = ath11k_dp_rx_h_msdu_start_rx_bw(ar->ab, rx_desc);2331 rate_mcs = ath11k_dp_rx_h_msdu_start_rate_mcs(ar->ab, rx_desc);2332 nss = ath11k_dp_rx_h_msdu_start_nss(ar->ab, rx_desc);2333 sgi = ath11k_dp_rx_h_msdu_start_sgi(ar->ab, rx_desc);2334 2335 switch (pkt_type) {2336 case RX_MSDU_START_PKT_TYPE_11A:2337 case RX_MSDU_START_PKT_TYPE_11B:2338 is_cck = (pkt_type == RX_MSDU_START_PKT_TYPE_11B);2339 sband = &ar->mac.sbands[rx_status->band];2340 rx_status->rate_idx = ath11k_mac_hw_rate_to_idx(sband, rate_mcs,2341 is_cck);2342 break;2343 case RX_MSDU_START_PKT_TYPE_11N:2344 rx_status->encoding = RX_ENC_HT;2345 if (rate_mcs > ATH11K_HT_MCS_MAX) {2346 ath11k_warn(ar->ab,2347 "Received with invalid mcs in HT mode %d\n",2348 rate_mcs);2349 break;2350 }2351 rx_status->rate_idx = rate_mcs + (8 * (nss - 1));2352 if (sgi)2353 rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;2354 rx_status->bw = ath11k_mac_bw_to_mac80211_bw(bw);2355 break;2356 case RX_MSDU_START_PKT_TYPE_11AC:2357 rx_status->encoding = RX_ENC_VHT;2358 rx_status->rate_idx = rate_mcs;2359 if (rate_mcs > ATH11K_VHT_MCS_MAX) {2360 ath11k_warn(ar->ab,2361 "Received with invalid mcs in VHT mode %d\n",2362 rate_mcs);2363 break;2364 }2365 rx_status->nss = nss;2366 if (sgi)2367 rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;2368 rx_status->bw = ath11k_mac_bw_to_mac80211_bw(bw);2369 is_ldpc = ath11k_dp_rx_h_msdu_start_ldpc_support(ar->ab, rx_desc);2370 if (is_ldpc)2371 rx_status->enc_flags |= RX_ENC_FLAG_LDPC;2372 break;2373 case RX_MSDU_START_PKT_TYPE_11AX:2374 rx_status->rate_idx = rate_mcs;2375 if (rate_mcs > ATH11K_HE_MCS_MAX) {2376 ath11k_warn(ar->ab,2377 "Received with invalid mcs in HE mode %d\n",2378 rate_mcs);2379 break;2380 }2381 rx_status->encoding = RX_ENC_HE;2382 rx_status->nss = nss;2383 rx_status->he_gi = ath11k_mac_he_gi_to_nl80211_he_gi(sgi);2384 rx_status->bw = ath11k_mac_bw_to_mac80211_bw(bw);2385 break;2386 }2387}2388 2389static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc,2390 struct ieee80211_rx_status *rx_status)2391{2392 u8 channel_num;2393 u32 center_freq, meta_data;2394 struct ieee80211_channel *channel;2395 2396 rx_status->freq = 0;2397 rx_status->rate_idx = 0;2398 rx_status->nss = 0;2399 rx_status->encoding = RX_ENC_LEGACY;2400 rx_status->bw = RATE_INFO_BW_20;2401 2402 rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;2403 2404 meta_data = ath11k_dp_rx_h_msdu_start_freq(ar->ab, rx_desc);2405 channel_num = meta_data;2406 center_freq = meta_data >> 16;2407 2408 if (center_freq >= ATH11K_MIN_6G_FREQ &&2409 center_freq <= ATH11K_MAX_6G_FREQ) {2410 rx_status->band = NL80211_BAND_6GHZ;2411 rx_status->freq = center_freq;2412 } else if (channel_num >= 1 && channel_num <= 14) {2413 rx_status->band = NL80211_BAND_2GHZ;2414 } else if (channel_num >= 36 && channel_num <= 177) {2415 rx_status->band = NL80211_BAND_5GHZ;2416 } else {2417 spin_lock_bh(&ar->data_lock);2418 channel = ar->rx_channel;2419 if (channel) {2420 rx_status->band = channel->band;2421 channel_num =2422 ieee80211_frequency_to_channel(channel->center_freq);2423 }2424 spin_unlock_bh(&ar->data_lock);2425 ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "rx_desc: ",2426 rx_desc, sizeof(struct hal_rx_desc));2427 }2428 2429 if (rx_status->band != NL80211_BAND_6GHZ)2430 rx_status->freq = ieee80211_channel_to_frequency(channel_num,2431 rx_status->band);2432 2433 ath11k_dp_rx_h_rate(ar, rx_desc, rx_status);2434}2435 2436static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *napi,2437 struct sk_buff *msdu,2438 struct ieee80211_rx_status *status)2439{2440 static const struct ieee80211_radiotap_he known = {2441 .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |2442 IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN),2443 .data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN),2444 };2445 struct ieee80211_rx_status *rx_status;2446 struct ieee80211_radiotap_he *he = NULL;2447 struct ieee80211_sta *pubsta = NULL;2448 struct ath11k_peer *peer;2449 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);2450 u8 decap = DP_RX_DECAP_TYPE_RAW;2451 bool is_mcbc = rxcb->is_mcbc;2452 bool is_eapol = rxcb->is_eapol;2453 2454 if (status->encoding == RX_ENC_HE &&2455 !(status->flag & RX_FLAG_RADIOTAP_HE) &&2456 !(status->flag & RX_FLAG_SKIP_MONITOR)) {2457 he = skb_push(msdu, sizeof(known));2458 memcpy(he, &known, sizeof(known));2459 status->flag |= RX_FLAG_RADIOTAP_HE;2460 }2461 2462 if (!(status->flag & RX_FLAG_ONLY_MONITOR))2463 decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rxcb->rx_desc);2464 2465 spin_lock_bh(&ar->ab->base_lock);2466 peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu);2467 if (peer && peer->sta)2468 pubsta = peer->sta;2469 spin_unlock_bh(&ar->ab->base_lock);2470 2471 ath11k_dbg(ar->ab, ATH11K_DBG_DATA,2472 "rx skb %p len %u peer %pM %d %s sn %u %s%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",2473 msdu,2474 msdu->len,2475 peer ? peer->addr : NULL,2476 rxcb->tid,2477 is_mcbc ? "mcast" : "ucast",2478 rxcb->seq_no,2479 (status->encoding == RX_ENC_LEGACY) ? "legacy" : "",2480 (status->encoding == RX_ENC_HT) ? "ht" : "",2481 (status->encoding == RX_ENC_VHT) ? "vht" : "",2482 (status->encoding == RX_ENC_HE) ? "he" : "",2483 (status->bw == RATE_INFO_BW_40) ? "40" : "",2484 (status->bw == RATE_INFO_BW_80) ? "80" : "",2485 (status->bw == RATE_INFO_BW_160) ? "160" : "",2486 status->enc_flags & RX_ENC_FLAG_SHORT_GI ? "sgi " : "",2487 status->rate_idx,2488 status->nss,2489 status->freq,2490 status->band, status->flag,2491 !!(status->flag & RX_FLAG_FAILED_FCS_CRC),2492 !!(status->flag & RX_FLAG_MMIC_ERROR),2493 !!(status->flag & RX_FLAG_AMSDU_MORE));2494 2495 ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_RX, NULL, "dp rx msdu: ",2496 msdu->data, msdu->len);2497 2498 rx_status = IEEE80211_SKB_RXCB(msdu);2499 *rx_status = *status;2500 2501 /* TODO: trace rx packet */2502 2503 /* PN for multicast packets are not validate in HW,2504 * so skip 802.3 rx path2505 * Also, fast_rx expects the STA to be authorized, hence2506 * eapol packets are sent in slow path.2507 */2508 if (decap == DP_RX_DECAP_TYPE_ETHERNET2_DIX && !is_eapol &&2509 !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED))2510 rx_status->flag |= RX_FLAG_8023;2511 2512 ieee80211_rx_napi(ar->hw, pubsta, msdu, napi);2513}2514 2515static int ath11k_dp_rx_process_msdu(struct ath11k *ar,2516 struct sk_buff *msdu,2517 struct sk_buff_head *msdu_list,2518 struct ieee80211_rx_status *rx_status)2519{2520 struct ath11k_base *ab = ar->ab;2521 struct hal_rx_desc *rx_desc, *lrx_desc;2522 struct rx_attention *rx_attention;2523 struct ath11k_skb_rxcb *rxcb;2524 struct sk_buff *last_buf;2525 u8 l3_pad_bytes;2526 u8 *hdr_status;2527 u16 msdu_len;2528 int ret;2529 u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;2530 2531 last_buf = ath11k_dp_rx_get_msdu_last_buf(msdu_list, msdu);2532 if (!last_buf) {2533 ath11k_warn(ab,2534 "No valid Rx buffer to access Atten/MSDU_END/MPDU_END tlvs\n");2535 ret = -EIO;2536 goto free_out;2537 }2538 2539 rx_desc = (struct hal_rx_desc *)msdu->data;2540 if (ath11k_dp_rx_h_attn_msdu_len_err(ab, rx_desc)) {2541 ath11k_warn(ar->ab, "msdu len not valid\n");2542 ret = -EIO;2543 goto free_out;2544 }2545 2546 lrx_desc = (struct hal_rx_desc *)last_buf->data;2547 rx_attention = ath11k_dp_rx_get_attention(ab, lrx_desc);2548 if (!ath11k_dp_rx_h_attn_msdu_done(rx_attention)) {2549 ath11k_warn(ab, "msdu_done bit in attention is not set\n");2550 ret = -EIO;2551 goto free_out;2552 }2553 2554 rxcb = ATH11K_SKB_RXCB(msdu);2555 rxcb->rx_desc = rx_desc;2556 msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ab, rx_desc);2557 l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(ab, lrx_desc);2558 2559 if (rxcb->is_frag) {2560 skb_pull(msdu, hal_rx_desc_sz);2561 } else if (!rxcb->is_continuation) {2562 if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) {2563 hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc);2564 ret = -EINVAL;2565 ath11k_warn(ab, "invalid msdu len %u\n", msdu_len);2566 ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status,2567 sizeof(struct ieee80211_hdr));2568 ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", rx_desc,2569 sizeof(struct hal_rx_desc));2570 goto free_out;2571 }2572 skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len);2573 skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes);2574 } else {2575 ret = ath11k_dp_rx_msdu_coalesce(ar, msdu_list,2576 msdu, last_buf,2577 l3_pad_bytes, msdu_len);2578 if (ret) {2579 ath11k_warn(ab,2580 "failed to coalesce msdu rx buffer%d\n", ret);2581 goto free_out;2582 }2583 }2584 2585 ath11k_dp_rx_h_ppdu(ar, rx_desc, rx_status);2586 ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status);2587 2588 rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;2589 2590 return 0;2591 2592free_out:2593 return ret;2594}2595 2596static void ath11k_dp_rx_process_received_packets(struct ath11k_base *ab,2597 struct napi_struct *napi,2598 struct sk_buff_head *msdu_list,2599 int mac_id)2600{2601 struct sk_buff *msdu;2602 struct ath11k *ar;2603 struct ieee80211_rx_status rx_status = {0};2604 int ret;2605 2606 if (skb_queue_empty(msdu_list))2607 return;2608 2609 if (unlikely(!rcu_access_pointer(ab->pdevs_active[mac_id]))) {2610 __skb_queue_purge(msdu_list);2611 return;2612 }2613 2614 ar = ab->pdevs[mac_id].ar;2615 if (unlikely(test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags))) {2616 __skb_queue_purge(msdu_list);2617 return;2618 }2619 2620 while ((msdu = __skb_dequeue(msdu_list))) {2621 ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status);2622 if (unlikely(ret)) {2623 ath11k_dbg(ab, ATH11K_DBG_DATA,2624 "Unable to process msdu %d", ret);2625 dev_kfree_skb_any(msdu);2626 continue;2627 }2628 2629 ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status);2630 }2631}2632 2633int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,2634 struct napi_struct *napi, int budget)2635{2636 struct ath11k_dp *dp = &ab->dp;2637 struct dp_rxdma_ring *rx_ring;2638 int num_buffs_reaped[MAX_RADIOS] = {0};2639 struct sk_buff_head msdu_list[MAX_RADIOS];2640 struct ath11k_skb_rxcb *rxcb;2641 int total_msdu_reaped = 0;2642 struct hal_srng *srng;2643 struct sk_buff *msdu;2644 bool done = false;2645 int buf_id, mac_id;2646 struct ath11k *ar;2647 struct hal_reo_dest_ring *desc;2648 enum hal_reo_dest_ring_push_reason push_reason;2649 u32 cookie;2650 int i;2651 2652 for (i = 0; i < MAX_RADIOS; i++)2653 __skb_queue_head_init(&msdu_list[i]);2654 2655 srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id];2656 2657 spin_lock_bh(&srng->lock);2658 2659try_again:2660 ath11k_hal_srng_access_begin(ab, srng);2661 2662 while (likely(desc =2663 (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab,2664 srng))) {2665 cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,2666 desc->buf_addr_info.info1);2667 buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,2668 cookie);2669 mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);2670 2671 if (unlikely(buf_id == 0))2672 continue;2673 2674 ar = ab->pdevs[mac_id].ar;2675 rx_ring = &ar->dp.rx_refill_buf_ring;2676 spin_lock_bh(&rx_ring->idr_lock);2677 msdu = idr_find(&rx_ring->bufs_idr, buf_id);2678 if (unlikely(!msdu)) {2679 ath11k_warn(ab, "frame rx with invalid buf_id %d\n",2680 buf_id);2681 spin_unlock_bh(&rx_ring->idr_lock);2682 continue;2683 }2684 2685 idr_remove(&rx_ring->bufs_idr, buf_id);2686 spin_unlock_bh(&rx_ring->idr_lock);2687 2688 rxcb = ATH11K_SKB_RXCB(msdu);2689 dma_unmap_single(ab->dev, rxcb->paddr,2690 msdu->len + skb_tailroom(msdu),2691 DMA_FROM_DEVICE);2692 2693 num_buffs_reaped[mac_id]++;2694 2695 push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,2696 desc->info0);2697 if (unlikely(push_reason !=2698 HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) {2699 dev_kfree_skb_any(msdu);2700 ab->soc_stats.hal_reo_error[ring_id]++;2701 continue;2702 }2703 2704 rxcb->is_first_msdu = !!(desc->rx_msdu_info.info0 &2705 RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);2706 rxcb->is_last_msdu = !!(desc->rx_msdu_info.info0 &2707 RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);2708 rxcb->is_continuation = !!(desc->rx_msdu_info.info0 &2709 RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);2710 rxcb->peer_id = FIELD_GET(RX_MPDU_DESC_META_DATA_PEER_ID,2711 desc->rx_mpdu_info.meta_data);2712 rxcb->seq_no = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM,2713 desc->rx_mpdu_info.info0);2714 rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,2715 desc->info0);2716 2717 rxcb->mac_id = mac_id;2718 __skb_queue_tail(&msdu_list[mac_id], msdu);2719 2720 if (rxcb->is_continuation) {2721 done = false;2722 } else {2723 total_msdu_reaped++;2724 done = true;2725 }2726 2727 if (total_msdu_reaped >= budget)2728 break;2729 }2730 2731 /* Hw might have updated the head pointer after we cached it.2732 * In this case, even though there are entries in the ring we'll2733 * get rx_desc NULL. Give the read another try with updated cached2734 * head pointer so that we can reap complete MPDU in the current2735 * rx processing.2736 */2737 if (unlikely(!done && ath11k_hal_srng_dst_num_free(ab, srng, true))) {2738 ath11k_hal_srng_access_end(ab, srng);2739 goto try_again;2740 }2741 2742 ath11k_hal_srng_access_end(ab, srng);2743 2744 spin_unlock_bh(&srng->lock);2745 2746 if (unlikely(!total_msdu_reaped))2747 goto exit;2748 2749 for (i = 0; i < ab->num_radios; i++) {2750 if (!num_buffs_reaped[i])2751 continue;2752 2753 ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list[i], i);2754 2755 ar = ab->pdevs[i].ar;2756 rx_ring = &ar->dp.rx_refill_buf_ring;2757 2758 ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i],2759 ab->hw_params.hal_params->rx_buf_rbm);2760 }2761exit:2762 return total_msdu_reaped;2763}2764 2765static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta,2766 struct hal_rx_mon_ppdu_info *ppdu_info)2767{2768 struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats;2769 u32 num_msdu;2770 int i;2771 2772 if (!rx_stats)2773 return;2774 2775 arsta->rssi_comb = ppdu_info->rssi_comb;2776 ewma_avg_rssi_add(&arsta->avg_rssi, ppdu_info->rssi_comb);2777 2778 num_msdu = ppdu_info->tcp_msdu_count + ppdu_info->tcp_ack_msdu_count +2779 ppdu_info->udp_msdu_count + ppdu_info->other_msdu_count;2780 2781 rx_stats->num_msdu += num_msdu;2782 rx_stats->tcp_msdu_count += ppdu_info->tcp_msdu_count +2783 ppdu_info->tcp_ack_msdu_count;2784 rx_stats->udp_msdu_count += ppdu_info->udp_msdu_count;2785 rx_stats->other_msdu_count += ppdu_info->other_msdu_count;2786 2787 if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A ||2788 ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) {2789 ppdu_info->nss = 1;2790 ppdu_info->mcs = HAL_RX_MAX_MCS;2791 ppdu_info->tid = IEEE80211_NUM_TIDS;2792 }2793 2794 if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS)2795 rx_stats->nss_count[ppdu_info->nss - 1] += num_msdu;2796 2797 if (ppdu_info->mcs <= HAL_RX_MAX_MCS)2798 rx_stats->mcs_count[ppdu_info->mcs] += num_msdu;2799 2800 if (ppdu_info->gi < HAL_RX_GI_MAX)2801 rx_stats->gi_count[ppdu_info->gi] += num_msdu;2802 2803 if (ppdu_info->bw < HAL_RX_BW_MAX)2804 rx_stats->bw_count[ppdu_info->bw] += num_msdu;2805 2806 if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX)2807 rx_stats->coding_count[ppdu_info->ldpc] += num_msdu;2808 2809 if (ppdu_info->tid <= IEEE80211_NUM_TIDS)2810 rx_stats->tid_count[ppdu_info->tid] += num_msdu;2811 2812 if (ppdu_info->preamble_type < HAL_RX_PREAMBLE_MAX)2813 rx_stats->pream_cnt[ppdu_info->preamble_type] += num_msdu;2814 2815 if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX)2816 rx_stats->reception_type[ppdu_info->reception_type] += num_msdu;2817 2818 if (ppdu_info->is_stbc)2819 rx_stats->stbc_count += num_msdu;2820 2821 if (ppdu_info->beamformed)2822 rx_stats->beamformed_count += num_msdu;2823 2824 if (ppdu_info->num_mpdu_fcs_ok > 1)2825 rx_stats->ampdu_msdu_count += num_msdu;2826 else2827 rx_stats->non_ampdu_msdu_count += num_msdu;2828 2829 rx_stats->num_mpdu_fcs_ok += ppdu_info->num_mpdu_fcs_ok;2830 rx_stats->num_mpdu_fcs_err += ppdu_info->num_mpdu_fcs_err;2831 rx_stats->dcm_count += ppdu_info->dcm;2832 rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu;2833 2834 arsta->rssi_comb = ppdu_info->rssi_comb;2835 2836 BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) >2837 ARRAY_SIZE(ppdu_info->rssi_chain_pri20));2838 2839 for (i = 0; i < ARRAY_SIZE(arsta->chain_signal); i++)2840 arsta->chain_signal[i] = ppdu_info->rssi_chain_pri20[i];2841 2842 rx_stats->rx_duration += ppdu_info->rx_duration;2843 arsta->rx_duration = rx_stats->rx_duration;2844}2845 2846static struct sk_buff *ath11k_dp_rx_alloc_mon_status_buf(struct ath11k_base *ab,2847 struct dp_rxdma_ring *rx_ring,2848 int *buf_id)2849{2850 struct sk_buff *skb;2851 dma_addr_t paddr;2852 2853 skb = dev_alloc_skb(DP_RX_BUFFER_SIZE +2854 DP_RX_BUFFER_ALIGN_SIZE);2855 2856 if (!skb)2857 goto fail_alloc_skb;2858 2859 if (!IS_ALIGNED((unsigned long)skb->data,2860 DP_RX_BUFFER_ALIGN_SIZE)) {2861 skb_pull(skb, PTR_ALIGN(skb->data, DP_RX_BUFFER_ALIGN_SIZE) -2862 skb->data);2863 }2864 2865 paddr = dma_map_single(ab->dev, skb->data,2866 skb->len + skb_tailroom(skb),2867 DMA_FROM_DEVICE);2868 if (unlikely(dma_mapping_error(ab->dev, paddr)))2869 goto fail_free_skb;2870 2871 spin_lock_bh(&rx_ring->idr_lock);2872 *buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 0,2873 rx_ring->bufs_max, GFP_ATOMIC);2874 spin_unlock_bh(&rx_ring->idr_lock);2875 if (*buf_id < 0)2876 goto fail_dma_unmap;2877 2878 ATH11K_SKB_RXCB(skb)->paddr = paddr;2879 return skb;2880 2881fail_dma_unmap:2882 dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb),2883 DMA_FROM_DEVICE);2884fail_free_skb:2885 dev_kfree_skb_any(skb);2886fail_alloc_skb:2887 return NULL;2888}2889 2890int ath11k_dp_rx_mon_status_bufs_replenish(struct ath11k_base *ab, int mac_id,2891 struct dp_rxdma_ring *rx_ring,2892 int req_entries,2893 enum hal_rx_buf_return_buf_manager mgr)2894{2895 struct hal_srng *srng;2896 u32 *desc;2897 struct sk_buff *skb;2898 int num_free;2899 int num_remain;2900 int buf_id;2901 u32 cookie;2902 dma_addr_t paddr;2903 2904 req_entries = min(req_entries, rx_ring->bufs_max);2905 2906 srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id];2907 2908 spin_lock_bh(&srng->lock);2909 2910 ath11k_hal_srng_access_begin(ab, srng);2911 2912 num_free = ath11k_hal_srng_src_num_free(ab, srng, true);2913 2914 req_entries = min(num_free, req_entries);2915 num_remain = req_entries;2916 2917 while (num_remain > 0) {2918 skb = ath11k_dp_rx_alloc_mon_status_buf(ab, rx_ring,2919 &buf_id);2920 if (!skb)2921 break;2922 paddr = ATH11K_SKB_RXCB(skb)->paddr;2923 2924 desc = ath11k_hal_srng_src_get_next_entry(ab, srng);2925 if (!desc)2926 goto fail_desc_get;2927 2928 cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, mac_id) |2929 FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id);2930 2931 num_remain--;2932 2933 ath11k_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr);2934 }2935 2936 ath11k_hal_srng_access_end(ab, srng);2937 2938 spin_unlock_bh(&srng->lock);2939 2940 return req_entries - num_remain;2941 2942fail_desc_get:2943 spin_lock_bh(&rx_ring->idr_lock);2944 idr_remove(&rx_ring->bufs_idr, buf_id);2945 spin_unlock_bh(&rx_ring->idr_lock);2946 dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb),2947 DMA_FROM_DEVICE);2948 dev_kfree_skb_any(skb);2949 ath11k_hal_srng_access_end(ab, srng);2950 spin_unlock_bh(&srng->lock);2951 2952 return req_entries - num_remain;2953}2954 2955#define ATH11K_DP_RX_FULL_MON_PPDU_ID_WRAP 325352956 2957static void2958ath11k_dp_rx_mon_update_status_buf_state(struct ath11k_mon_data *pmon,2959 struct hal_tlv_hdr *tlv)2960{2961 struct hal_rx_ppdu_start *ppdu_start;2962 u16 ppdu_id_diff, ppdu_id, tlv_len;2963 u8 *ptr;2964 2965 /* PPDU id is part of second tlv, move ptr to second tlv */2966 tlv_len = FIELD_GET(HAL_TLV_HDR_LEN, tlv->tl);2967 ptr = (u8 *)tlv;2968 ptr += sizeof(*tlv) + tlv_len;2969 tlv = (struct hal_tlv_hdr *)ptr;2970 2971 if (FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl) != HAL_RX_PPDU_START)2972 return;2973 2974 ptr += sizeof(*tlv);2975 ppdu_start = (struct hal_rx_ppdu_start *)ptr;2976 ppdu_id = FIELD_GET(HAL_RX_PPDU_START_INFO0_PPDU_ID,2977 __le32_to_cpu(ppdu_start->info0));2978 2979 if (pmon->sw_mon_entries.ppdu_id < ppdu_id) {2980 pmon->buf_state = DP_MON_STATUS_LEAD;2981 ppdu_id_diff = ppdu_id - pmon->sw_mon_entries.ppdu_id;2982 if (ppdu_id_diff > ATH11K_DP_RX_FULL_MON_PPDU_ID_WRAP)2983 pmon->buf_state = DP_MON_STATUS_LAG;2984 } else if (pmon->sw_mon_entries.ppdu_id > ppdu_id) {2985 pmon->buf_state = DP_MON_STATUS_LAG;2986 ppdu_id_diff = pmon->sw_mon_entries.ppdu_id - ppdu_id;2987 if (ppdu_id_diff > ATH11K_DP_RX_FULL_MON_PPDU_ID_WRAP)2988 pmon->buf_state = DP_MON_STATUS_LEAD;2989 }2990}2991 2992static enum dp_mon_status_buf_state2993ath11k_dp_rx_mon_buf_done(struct ath11k_base *ab, struct hal_srng *srng,2994 struct dp_rxdma_ring *rx_ring)2995{2996 struct ath11k_skb_rxcb *rxcb;2997 struct hal_tlv_hdr *tlv;2998 struct sk_buff *skb;2999 void *status_desc;3000 dma_addr_t paddr;3001 u32 cookie;3002 int buf_id;3003 u8 rbm;3004 3005 status_desc = ath11k_hal_srng_src_next_peek(ab, srng);3006 if (!status_desc)3007 return DP_MON_STATUS_NO_DMA;3008 3009 ath11k_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm);3010 3011 buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, cookie);3012 3013 spin_lock_bh(&rx_ring->idr_lock);3014 skb = idr_find(&rx_ring->bufs_idr, buf_id);3015 spin_unlock_bh(&rx_ring->idr_lock);3016 3017 if (!skb)3018 return DP_MON_STATUS_NO_DMA;3019 3020 rxcb = ATH11K_SKB_RXCB(skb);3021 dma_sync_single_for_cpu(ab->dev, rxcb->paddr,3022 skb->len + skb_tailroom(skb),3023 DMA_FROM_DEVICE);3024 3025 tlv = (struct hal_tlv_hdr *)skb->data;3026 if (FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl) != HAL_RX_STATUS_BUFFER_DONE)3027 return DP_MON_STATUS_NO_DMA;3028 3029 return DP_MON_STATUS_REPLINISH;3030}3031 3032static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id,3033 int *budget, struct sk_buff_head *skb_list)3034{3035 struct ath11k *ar;3036 const struct ath11k_hw_hal_params *hal_params;3037 enum dp_mon_status_buf_state reap_status;3038 struct ath11k_pdev_dp *dp;3039 struct dp_rxdma_ring *rx_ring;3040 struct ath11k_mon_data *pmon;3041 struct hal_srng *srng;3042 void *rx_mon_status_desc;3043 struct sk_buff *skb;3044 struct ath11k_skb_rxcb *rxcb;3045 struct hal_tlv_hdr *tlv;3046 u32 cookie;3047 int buf_id, srng_id;3048 dma_addr_t paddr;3049 u8 rbm;3050 int num_buffs_reaped = 0;3051 3052 ar = ab->pdevs[ath11k_hw_mac_id_to_pdev_id(&ab->hw_params, mac_id)].ar;3053 dp = &ar->dp;3054 pmon = &dp->mon_data;3055 srng_id = ath11k_hw_mac_id_to_srng_id(&ab->hw_params, mac_id);3056 rx_ring = &dp->rx_mon_status_refill_ring[srng_id];3057 3058 srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id];3059 3060 spin_lock_bh(&srng->lock);3061 3062 ath11k_hal_srng_access_begin(ab, srng);3063 while (*budget) {3064 *budget -= 1;3065 rx_mon_status_desc =3066 ath11k_hal_srng_src_peek(ab, srng);3067 if (!rx_mon_status_desc) {3068 pmon->buf_state = DP_MON_STATUS_REPLINISH;3069 break;3070 }3071 3072 ath11k_hal_rx_buf_addr_info_get(rx_mon_status_desc, &paddr,3073 &cookie, &rbm);3074 if (paddr) {3075 buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, cookie);3076 3077 spin_lock_bh(&rx_ring->idr_lock);3078 skb = idr_find(&rx_ring->bufs_idr, buf_id);3079 spin_unlock_bh(&rx_ring->idr_lock);3080 3081 if (!skb) {3082 ath11k_warn(ab, "rx monitor status with invalid buf_id %d\n",3083 buf_id);3084 pmon->buf_state = DP_MON_STATUS_REPLINISH;3085 goto move_next;3086 }3087 3088 rxcb = ATH11K_SKB_RXCB(skb);3089 3090 dma_sync_single_for_cpu(ab->dev, rxcb->paddr,3091 skb->len + skb_tailroom(skb),3092 DMA_FROM_DEVICE);3093 3094 tlv = (struct hal_tlv_hdr *)skb->data;3095 if (FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl) !=3096 HAL_RX_STATUS_BUFFER_DONE) {3097 ath11k_warn(ab, "mon status DONE not set %lx, buf_id %d\n",3098 FIELD_GET(HAL_TLV_HDR_TAG,3099 tlv->tl), buf_id);3100 /* RxDMA status done bit might not be set even3101 * though tp is moved by HW.3102 */3103 3104 /* If done status is missing:3105 * 1. As per MAC team's suggestion,3106 * when HP + 1 entry is peeked and if DMA3107 * is not done and if HP + 2 entry's DMA done3108 * is set. skip HP + 1 entry and3109 * start processing in next interrupt.3110 * 2. If HP + 2 entry's DMA done is not set,3111 * poll onto HP + 1 entry DMA done to be set.3112 * Check status for same buffer for next time3113 * dp_rx_mon_status_srng_process3114 */3115 3116 reap_status = ath11k_dp_rx_mon_buf_done(ab, srng,3117 rx_ring);3118 if (reap_status == DP_MON_STATUS_NO_DMA)3119 continue;3120 3121 spin_lock_bh(&rx_ring->idr_lock);3122 idr_remove(&rx_ring->bufs_idr, buf_id);3123 spin_unlock_bh(&rx_ring->idr_lock);3124 3125 dma_unmap_single(ab->dev, rxcb->paddr,3126 skb->len + skb_tailroom(skb),3127 DMA_FROM_DEVICE);3128 3129 dev_kfree_skb_any(skb);3130 pmon->buf_state = DP_MON_STATUS_REPLINISH;3131 goto move_next;3132 }3133 3134 spin_lock_bh(&rx_ring->idr_lock);3135 idr_remove(&rx_ring->bufs_idr, buf_id);3136 spin_unlock_bh(&rx_ring->idr_lock);3137 if (ab->hw_params.full_monitor_mode) {3138 ath11k_dp_rx_mon_update_status_buf_state(pmon, tlv);3139 if (paddr == pmon->mon_status_paddr)3140 pmon->buf_state = DP_MON_STATUS_MATCH;3141 }3142 3143 dma_unmap_single(ab->dev, rxcb->paddr,3144 skb->len + skb_tailroom(skb),3145 DMA_FROM_DEVICE);3146 3147 __skb_queue_tail(skb_list, skb);3148 } else {3149 pmon->buf_state = DP_MON_STATUS_REPLINISH;3150 }3151move_next:3152 skb = ath11k_dp_rx_alloc_mon_status_buf(ab, rx_ring,3153 &buf_id);3154 3155 if (!skb) {3156 hal_params = ab->hw_params.hal_params;3157 ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0,3158 hal_params->rx_buf_rbm);3159 num_buffs_reaped++;3160 break;3161 }3162 rxcb = ATH11K_SKB_RXCB(skb);3163 3164 cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, mac_id) |3165 FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id);3166 3167 ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr,3168 cookie,3169 ab->hw_params.hal_params->rx_buf_rbm);3170 ath11k_hal_srng_src_get_next_entry(ab, srng);3171 num_buffs_reaped++;3172 }3173 ath11k_hal_srng_access_end(ab, srng);3174 spin_unlock_bh(&srng->lock);3175 3176 return num_buffs_reaped;3177}3178 3179static void ath11k_dp_rx_frag_timer(struct timer_list *timer)3180{3181 struct dp_rx_tid *rx_tid = from_timer(rx_tid, timer, frag_timer);3182 3183 spin_lock_bh(&rx_tid->ab->base_lock);3184 if (rx_tid->last_frag_no &&3185 rx_tid->rx_frag_bitmap == GENMASK(rx_tid->last_frag_no, 0)) {3186 spin_unlock_bh(&rx_tid->ab->base_lock);3187 return;3188 }3189 ath11k_dp_rx_frags_cleanup(rx_tid, true);3190 spin_unlock_bh(&rx_tid->ab->base_lock);3191}3192 3193int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id)3194{3195 struct ath11k_base *ab = ar->ab;3196 struct crypto_shash *tfm;3197 struct ath11k_peer *peer;3198 struct dp_rx_tid *rx_tid;3199 int i;3200 3201 tfm = crypto_alloc_shash("michael_mic", 0, 0);3202 if (IS_ERR(tfm)) {3203 ath11k_warn(ab, "failed to allocate michael_mic shash: %ld\n",3204 PTR_ERR(tfm));3205 return PTR_ERR(tfm);3206 }3207 3208 spin_lock_bh(&ab->base_lock);3209 3210 peer = ath11k_peer_find(ab, vdev_id, peer_mac);3211 if (!peer) {3212 ath11k_warn(ab, "failed to find the peer to set up fragment info\n");3213 spin_unlock_bh(&ab->base_lock);3214 crypto_free_shash(tfm);3215 return -ENOENT;3216 }3217 3218 for (i = 0; i <= IEEE80211_NUM_TIDS; i++) {3219 rx_tid = &peer->rx_tid[i];3220 rx_tid->ab = ab;3221 timer_setup(&rx_tid->frag_timer, ath11k_dp_rx_frag_timer, 0);3222 skb_queue_head_init(&rx_tid->rx_frags);3223 }3224 3225 peer->tfm_mmic = tfm;3226 peer->dp_setup_done = true;3227 spin_unlock_bh(&ab->base_lock);3228 3229 return 0;3230}3231 3232static int ath11k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key,3233 struct ieee80211_hdr *hdr, u8 *data,3234 size_t data_len, u8 *mic)3235{3236 SHASH_DESC_ON_STACK(desc, tfm);3237 u8 mic_hdr[16] = {0};3238 u8 tid = 0;3239 int ret;3240 3241 if (!tfm)3242 return -EINVAL;3243 3244 desc->tfm = tfm;3245 3246 ret = crypto_shash_setkey(tfm, key, 8);3247 if (ret)3248 goto out;3249 3250 ret = crypto_shash_init(desc);3251 if (ret)3252 goto out;3253 3254 /* TKIP MIC header */3255 memcpy(mic_hdr, ieee80211_get_DA(hdr), ETH_ALEN);3256 memcpy(mic_hdr + ETH_ALEN, ieee80211_get_SA(hdr), ETH_ALEN);3257 if (ieee80211_is_data_qos(hdr->frame_control))3258 tid = ieee80211_get_tid(hdr);3259 mic_hdr[12] = tid;3260 3261 ret = crypto_shash_update(desc, mic_hdr, 16);3262 if (ret)3263 goto out;3264 ret = crypto_shash_update(desc, data, data_len);3265 if (ret)3266 goto out;3267 ret = crypto_shash_final(desc, mic);3268out:3269 shash_desc_zero(desc);3270 return ret;3271}3272 3273static int ath11k_dp_rx_h_verify_tkip_mic(struct ath11k *ar, struct ath11k_peer *peer,3274 struct sk_buff *msdu)3275{3276 struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data;3277 struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu);3278 struct ieee80211_key_conf *key_conf;3279 struct ieee80211_hdr *hdr;3280 u8 mic[IEEE80211_CCMP_MIC_LEN];3281 int head_len, tail_len, ret;3282 size_t data_len;3283 u32 hdr_len, hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;3284 u8 *key, *data;3285 u8 key_idx;3286 3287 if (ath11k_dp_rx_h_mpdu_start_enctype(ar->ab, rx_desc) !=3288 HAL_ENCRYPT_TYPE_TKIP_MIC)3289 return 0;3290 3291 hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz);3292 hdr_len = ieee80211_hdrlen(hdr->frame_control);3293 head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN;3294 tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN;3295 3296 if (!is_multicast_ether_addr(hdr->addr1))3297 key_idx = peer->ucast_keyidx;3298 else3299 key_idx = peer->mcast_keyidx;3300 3301 key_conf = peer->keys[key_idx];3302 3303 data = msdu->data + head_len;3304 data_len = msdu->len - head_len - tail_len;3305 key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];3306 3307 ret = ath11k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, data_len, mic);3308 if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN))3309 goto mic_fail;3310 3311 return 0;3312 3313mic_fail:3314 (ATH11K_SKB_RXCB(msdu))->is_first_msdu = true;3315 (ATH11K_SKB_RXCB(msdu))->is_last_msdu = true;3316 3317 rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED |3318 RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED;3319 skb_pull(msdu, hal_rx_desc_sz);3320 3321 ath11k_dp_rx_h_ppdu(ar, rx_desc, rxs);3322 ath11k_dp_rx_h_undecap(ar, msdu, rx_desc,3323 HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true);3324 ieee80211_rx(ar->hw, msdu);3325 return -EINVAL;3326}3327 3328static void ath11k_dp_rx_h_undecap_frag(struct ath11k *ar, struct sk_buff *msdu,3329 enum hal_encrypt_type enctype, u32 flags)3330{3331 struct ieee80211_hdr *hdr;3332 size_t hdr_len;3333 size_t crypto_len;3334 u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;3335 3336 if (!flags)3337 return;3338 3339 hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz);3340 3341 if (flags & RX_FLAG_MIC_STRIPPED)3342 skb_trim(msdu, msdu->len -3343 ath11k_dp_rx_crypto_mic_len(ar, enctype));3344 3345 if (flags & RX_FLAG_ICV_STRIPPED)3346 skb_trim(msdu, msdu->len -3347 ath11k_dp_rx_crypto_icv_len(ar, enctype));3348 3349 if (flags & RX_FLAG_IV_STRIPPED) {3350 hdr_len = ieee80211_hdrlen(hdr->frame_control);3351 crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype);3352 3353 memmove((void *)msdu->data + hal_rx_desc_sz + crypto_len,3354 (void *)msdu->data + hal_rx_desc_sz, hdr_len);3355 skb_pull(msdu, crypto_len);3356 }3357}3358 3359static int ath11k_dp_rx_h_defrag(struct ath11k *ar,3360 struct ath11k_peer *peer,3361 struct dp_rx_tid *rx_tid,3362 struct sk_buff **defrag_skb)3363{3364 struct hal_rx_desc *rx_desc;3365 struct sk_buff *skb, *first_frag, *last_frag;3366 struct ieee80211_hdr *hdr;3367 struct rx_attention *rx_attention;3368 enum hal_encrypt_type enctype;3369 bool is_decrypted = false;3370 int msdu_len = 0;3371 int extra_space;3372 u32 flags, hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;3373 3374 first_frag = skb_peek(&rx_tid->rx_frags);3375 last_frag = skb_peek_tail(&rx_tid->rx_frags);3376 3377 skb_queue_walk(&rx_tid->rx_frags, skb) {3378 flags = 0;3379 rx_desc = (struct hal_rx_desc *)skb->data;3380 hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz);3381 3382 enctype = ath11k_dp_rx_h_mpdu_start_enctype(ar->ab, rx_desc);3383 if (enctype != HAL_ENCRYPT_TYPE_OPEN) {3384 rx_attention = ath11k_dp_rx_get_attention(ar->ab, rx_desc);3385 is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_attention);3386 }3387 3388 if (is_decrypted) {3389 if (skb != first_frag)3390 flags |= RX_FLAG_IV_STRIPPED;3391 if (skb != last_frag)3392 flags |= RX_FLAG_ICV_STRIPPED |3393 RX_FLAG_MIC_STRIPPED;3394 }3395 3396 /* RX fragments are always raw packets */3397 if (skb != last_frag)3398 skb_trim(skb, skb->len - FCS_LEN);3399 ath11k_dp_rx_h_undecap_frag(ar, skb, enctype, flags);3400 3401 if (skb != first_frag)3402 skb_pull(skb, hal_rx_desc_sz +3403 ieee80211_hdrlen(hdr->frame_control));3404 msdu_len += skb->len;3405 }3406 3407 extra_space = msdu_len - (DP_RX_BUFFER_SIZE + skb_tailroom(first_frag));3408 if (extra_space > 0 &&3409 (pskb_expand_head(first_frag, 0, extra_space, GFP_ATOMIC) < 0))3410 return -ENOMEM;3411 3412 __skb_unlink(first_frag, &rx_tid->rx_frags);3413 while ((skb = __skb_dequeue(&rx_tid->rx_frags))) {3414 skb_put_data(first_frag, skb->data, skb->len);3415 dev_kfree_skb_any(skb);3416 }3417 3418 hdr = (struct ieee80211_hdr *)(first_frag->data + hal_rx_desc_sz);3419 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS);3420 ATH11K_SKB_RXCB(first_frag)->is_frag = 1;3421 3422 if (ath11k_dp_rx_h_verify_tkip_mic(ar, peer, first_frag))3423 first_frag = NULL;3424 3425 *defrag_skb = first_frag;3426 return 0;3427}3428 3429static int ath11k_dp_rx_h_defrag_reo_reinject(struct ath11k *ar, struct dp_rx_tid *rx_tid,3430 struct sk_buff *defrag_skb)3431{3432 struct ath11k_base *ab = ar->ab;3433 struct ath11k_pdev_dp *dp = &ar->dp;3434 struct dp_rxdma_ring *rx_refill_ring = &dp->rx_refill_buf_ring;3435 struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data;3436 struct hal_reo_entrance_ring *reo_ent_ring;3437 struct hal_reo_dest_ring *reo_dest_ring;3438 struct dp_link_desc_bank *link_desc_banks;3439 struct hal_rx_msdu_link *msdu_link;3440 struct hal_rx_msdu_details *msdu0;3441 struct hal_srng *srng;3442 dma_addr_t paddr;3443 u32 desc_bank, msdu_info, mpdu_info;3444 u32 dst_idx, cookie, hal_rx_desc_sz;3445 int ret, buf_id;3446 3447 hal_rx_desc_sz = ab->hw_params.hal_desc_sz;3448 link_desc_banks = ab->dp.link_desc_banks;3449 reo_dest_ring = rx_tid->dst_ring_desc;3450 3451 ath11k_hal_rx_reo_ent_paddr_get(ab, reo_dest_ring, &paddr, &desc_bank);3452 msdu_link = (struct hal_rx_msdu_link *)(link_desc_banks[desc_bank].vaddr +3453 (paddr - link_desc_banks[desc_bank].paddr));3454 msdu0 = &msdu_link->msdu_link[0];3455 dst_idx = FIELD_GET(RX_MSDU_DESC_INFO0_REO_DEST_IND, msdu0->rx_msdu_info.info0);3456 memset(msdu0, 0, sizeof(*msdu0));3457 3458 msdu_info = FIELD_PREP(RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU, 1) |3459 FIELD_PREP(RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU, 1) |3460 FIELD_PREP(RX_MSDU_DESC_INFO0_MSDU_CONTINUATION, 0) |3461 FIELD_PREP(RX_MSDU_DESC_INFO0_MSDU_LENGTH,3462 defrag_skb->len - hal_rx_desc_sz) |3463 FIELD_PREP(RX_MSDU_DESC_INFO0_REO_DEST_IND, dst_idx) |3464 FIELD_PREP(RX_MSDU_DESC_INFO0_VALID_SA, 1) |3465 FIELD_PREP(RX_MSDU_DESC_INFO0_VALID_DA, 1);3466 msdu0->rx_msdu_info.info0 = msdu_info;3467 3468 /* change msdu len in hal rx desc */3469 ath11k_dp_rxdesc_set_msdu_len(ab, rx_desc, defrag_skb->len - hal_rx_desc_sz);3470 3471 paddr = dma_map_single(ab->dev, defrag_skb->data,3472 defrag_skb->len + skb_tailroom(defrag_skb),3473 DMA_TO_DEVICE);3474 if (dma_mapping_error(ab->dev, paddr))3475 return -ENOMEM;3476 3477 spin_lock_bh(&rx_refill_ring->idr_lock);3478 buf_id = idr_alloc(&rx_refill_ring->bufs_idr, defrag_skb, 0,3479 rx_refill_ring->bufs_max * 3, GFP_ATOMIC);3480 spin_unlock_bh(&rx_refill_ring->idr_lock);3481 if (buf_id < 0) {3482 ret = -ENOMEM;3483 goto err_unmap_dma;3484 }3485 3486 ATH11K_SKB_RXCB(defrag_skb)->paddr = paddr;3487 cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, dp->mac_id) |3488 FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id);3489 3490 ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie,3491 ab->hw_params.hal_params->rx_buf_rbm);3492 3493 /* Fill mpdu details into reo entrance ring */3494 srng = &ab->hal.srng_list[ab->dp.reo_reinject_ring.ring_id];3495 3496 spin_lock_bh(&srng->lock);3497 ath11k_hal_srng_access_begin(ab, srng);3498 3499 reo_ent_ring = (struct hal_reo_entrance_ring *)3500 ath11k_hal_srng_src_get_next_entry(ab, srng);3501 if (!reo_ent_ring) {3502 ath11k_hal_srng_access_end(ab, srng);3503 spin_unlock_bh(&srng->lock);3504 ret = -ENOSPC;3505 goto err_free_idr;3506 }3507 memset(reo_ent_ring, 0, sizeof(*reo_ent_ring));3508 3509 ath11k_hal_rx_reo_ent_paddr_get(ab, reo_dest_ring, &paddr, &desc_bank);3510 ath11k_hal_rx_buf_addr_info_set(reo_ent_ring, paddr, desc_bank,3511 HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST);3512 3513 mpdu_info = FIELD_PREP(RX_MPDU_DESC_INFO0_MSDU_COUNT, 1) |3514 FIELD_PREP(RX_MPDU_DESC_INFO0_SEQ_NUM, rx_tid->cur_sn) |3515 FIELD_PREP(RX_MPDU_DESC_INFO0_FRAG_FLAG, 0) |3516 FIELD_PREP(RX_MPDU_DESC_INFO0_VALID_SA, 1) |3517 FIELD_PREP(RX_MPDU_DESC_INFO0_VALID_DA, 1) |3518 FIELD_PREP(RX_MPDU_DESC_INFO0_RAW_MPDU, 1) |3519 FIELD_PREP(RX_MPDU_DESC_INFO0_VALID_PN, 1);3520 3521 reo_ent_ring->rx_mpdu_info.info0 = mpdu_info;3522 reo_ent_ring->rx_mpdu_info.meta_data = reo_dest_ring->rx_mpdu_info.meta_data;3523 reo_ent_ring->queue_addr_lo = reo_dest_ring->queue_addr_lo;3524 reo_ent_ring->info0 = FIELD_PREP(HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI,3525 FIELD_GET(HAL_REO_DEST_RING_INFO0_QUEUE_ADDR_HI,3526 reo_dest_ring->info0)) |3527 FIELD_PREP(HAL_REO_ENTR_RING_INFO0_DEST_IND, dst_idx);3528 ath11k_hal_srng_access_end(ab, srng);3529 spin_unlock_bh(&srng->lock);3530 3531 return 0;3532 3533err_free_idr:3534 spin_lock_bh(&rx_refill_ring->idr_lock);3535 idr_remove(&rx_refill_ring->bufs_idr, buf_id);3536 spin_unlock_bh(&rx_refill_ring->idr_lock);3537err_unmap_dma:3538 dma_unmap_single(ab->dev, paddr, defrag_skb->len + skb_tailroom(defrag_skb),3539 DMA_TO_DEVICE);3540 return ret;3541}3542 3543static int ath11k_dp_rx_h_cmp_frags(struct ath11k *ar,3544 struct sk_buff *a, struct sk_buff *b)3545{3546 int frag1, frag2;3547 3548 frag1 = ath11k_dp_rx_h_mpdu_start_frag_no(ar->ab, a);3549 frag2 = ath11k_dp_rx_h_mpdu_start_frag_no(ar->ab, b);3550 3551 return frag1 - frag2;3552}3553 3554static void ath11k_dp_rx_h_sort_frags(struct ath11k *ar,3555 struct sk_buff_head *frag_list,3556 struct sk_buff *cur_frag)3557{3558 struct sk_buff *skb;3559 int cmp;3560 3561 skb_queue_walk(frag_list, skb) {3562 cmp = ath11k_dp_rx_h_cmp_frags(ar, skb, cur_frag);3563 if (cmp < 0)3564 continue;3565 __skb_queue_before(frag_list, skb, cur_frag);3566 return;3567 }3568 __skb_queue_tail(frag_list, cur_frag);3569}3570 3571static u64 ath11k_dp_rx_h_get_pn(struct ath11k *ar, struct sk_buff *skb)3572{3573 struct ieee80211_hdr *hdr;3574 u64 pn = 0;3575 u8 *ehdr;3576 u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;3577 3578 hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz);3579 ehdr = skb->data + hal_rx_desc_sz + ieee80211_hdrlen(hdr->frame_control);3580 3581 pn = ehdr[0];3582 pn |= (u64)ehdr[1] << 8;3583 pn |= (u64)ehdr[4] << 16;3584 pn |= (u64)ehdr[5] << 24;3585 pn |= (u64)ehdr[6] << 32;3586 pn |= (u64)ehdr[7] << 40;3587 3588 return pn;3589}3590 3591static bool3592ath11k_dp_rx_h_defrag_validate_incr_pn(struct ath11k *ar, struct dp_rx_tid *rx_tid)3593{3594 enum hal_encrypt_type encrypt_type;3595 struct sk_buff *first_frag, *skb;3596 struct hal_rx_desc *desc;3597 u64 last_pn;3598 u64 cur_pn;3599 3600 first_frag = skb_peek(&rx_tid->rx_frags);3601 desc = (struct hal_rx_desc *)first_frag->data;3602 3603 encrypt_type = ath11k_dp_rx_h_mpdu_start_enctype(ar->ab, desc);3604 if (encrypt_type != HAL_ENCRYPT_TYPE_CCMP_128 &&3605 encrypt_type != HAL_ENCRYPT_TYPE_CCMP_256 &&3606 encrypt_type != HAL_ENCRYPT_TYPE_GCMP_128 &&3607 encrypt_type != HAL_ENCRYPT_TYPE_AES_GCMP_256)3608 return true;3609 3610 last_pn = ath11k_dp_rx_h_get_pn(ar, first_frag);3611 skb_queue_walk(&rx_tid->rx_frags, skb) {3612 if (skb == first_frag)3613 continue;3614 3615 cur_pn = ath11k_dp_rx_h_get_pn(ar, skb);3616 if (cur_pn != last_pn + 1)3617 return false;3618 last_pn = cur_pn;3619 }3620 return true;3621}3622 3623static int ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar,3624 struct sk_buff *msdu,3625 u32 *ring_desc)3626{3627 struct ath11k_base *ab = ar->ab;3628 struct hal_rx_desc *rx_desc;3629 struct ath11k_peer *peer;3630 struct dp_rx_tid *rx_tid;3631 struct sk_buff *defrag_skb = NULL;3632 u32 peer_id;3633 u16 seqno, frag_no;3634 u8 tid;3635 int ret = 0;3636 bool more_frags;3637 bool is_mcbc;3638 3639 rx_desc = (struct hal_rx_desc *)msdu->data;3640 peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(ar->ab, rx_desc);3641 tid = ath11k_dp_rx_h_mpdu_start_tid(ar->ab, rx_desc);3642 seqno = ath11k_dp_rx_h_mpdu_start_seq_no(ar->ab, rx_desc);3643 frag_no = ath11k_dp_rx_h_mpdu_start_frag_no(ar->ab, msdu);3644 more_frags = ath11k_dp_rx_h_mpdu_start_more_frags(ar->ab, msdu);3645 is_mcbc = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc);3646 3647 /* Multicast/Broadcast fragments are not expected */3648 if (is_mcbc)3649 return -EINVAL;3650 3651 if (!ath11k_dp_rx_h_mpdu_start_seq_ctrl_valid(ar->ab, rx_desc) ||3652 !ath11k_dp_rx_h_mpdu_start_fc_valid(ar->ab, rx_desc) ||3653 tid > IEEE80211_NUM_TIDS)3654 return -EINVAL;3655 3656 /* received unfragmented packet in reo3657 * exception ring, this shouldn't happen3658 * as these packets typically come from3659 * reo2sw srngs.3660 */3661 if (WARN_ON_ONCE(!frag_no && !more_frags))3662 return -EINVAL;3663 3664 spin_lock_bh(&ab->base_lock);3665 peer = ath11k_peer_find_by_id(ab, peer_id);3666 if (!peer) {3667 ath11k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n",3668 peer_id);3669 ret = -ENOENT;3670 goto out_unlock;3671 }3672 if (!peer->dp_setup_done) {3673 ath11k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n",3674 peer->addr, peer_id);3675 ret = -ENOENT;3676 goto out_unlock;3677 }3678 3679 rx_tid = &peer->rx_tid[tid];3680 3681 if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) ||3682 skb_queue_empty(&rx_tid->rx_frags)) {3683 /* Flush stored fragments and start a new sequence */3684 ath11k_dp_rx_frags_cleanup(rx_tid, true);3685 rx_tid->cur_sn = seqno;3686 }3687 3688 if (rx_tid->rx_frag_bitmap & BIT(frag_no)) {3689 /* Fragment already present */3690 ret = -EINVAL;3691 goto out_unlock;3692 }3693 3694 if (!rx_tid->rx_frag_bitmap || (frag_no > __fls(rx_tid->rx_frag_bitmap)))3695 __skb_queue_tail(&rx_tid->rx_frags, msdu);3696 else3697 ath11k_dp_rx_h_sort_frags(ar, &rx_tid->rx_frags, msdu);3698 3699 rx_tid->rx_frag_bitmap |= BIT(frag_no);3700 if (!more_frags)3701 rx_tid->last_frag_no = frag_no;3702 3703 if (frag_no == 0) {3704 rx_tid->dst_ring_desc = kmemdup(ring_desc,3705 sizeof(*rx_tid->dst_ring_desc),3706 GFP_ATOMIC);3707 if (!rx_tid->dst_ring_desc) {3708 ret = -ENOMEM;3709 goto out_unlock;3710 }3711 } else {3712 ath11k_dp_rx_link_desc_return(ab, ring_desc,3713 HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);3714 }3715 3716 if (!rx_tid->last_frag_no ||3717 rx_tid->rx_frag_bitmap != GENMASK(rx_tid->last_frag_no, 0)) {3718 mod_timer(&rx_tid->frag_timer, jiffies +3719 ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS);3720 goto out_unlock;3721 }3722 3723 spin_unlock_bh(&ab->base_lock);3724 del_timer_sync(&rx_tid->frag_timer);3725 spin_lock_bh(&ab->base_lock);3726 3727 peer = ath11k_peer_find_by_id(ab, peer_id);3728 if (!peer)3729 goto err_frags_cleanup;3730 3731 if (!ath11k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid))3732 goto err_frags_cleanup;3733 3734 if (ath11k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb))3735 goto err_frags_cleanup;3736 3737 if (!defrag_skb)3738 goto err_frags_cleanup;3739 3740 if (ath11k_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb))3741 goto err_frags_cleanup;3742 3743 ath11k_dp_rx_frags_cleanup(rx_tid, false);3744 goto out_unlock;3745 3746err_frags_cleanup:3747 dev_kfree_skb_any(defrag_skb);3748 ath11k_dp_rx_frags_cleanup(rx_tid, true);3749out_unlock:3750 spin_unlock_bh(&ab->base_lock);3751 return ret;3752}3753 3754static int3755ath11k_dp_process_rx_err_buf(struct ath11k *ar, u32 *ring_desc, int buf_id, bool drop)3756{3757 struct ath11k_pdev_dp *dp = &ar->dp;3758 struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;3759 struct sk_buff *msdu;3760 struct ath11k_skb_rxcb *rxcb;3761 struct hal_rx_desc *rx_desc;3762 u8 *hdr_status;3763 u16 msdu_len;3764 u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;3765 3766 spin_lock_bh(&rx_ring->idr_lock);3767 msdu = idr_find(&rx_ring->bufs_idr, buf_id);3768 if (!msdu) {3769 ath11k_warn(ar->ab, "rx err buf with invalid buf_id %d\n",3770 buf_id);3771 spin_unlock_bh(&rx_ring->idr_lock);3772 return -EINVAL;3773 }3774 3775 idr_remove(&rx_ring->bufs_idr, buf_id);3776 spin_unlock_bh(&rx_ring->idr_lock);3777 3778 rxcb = ATH11K_SKB_RXCB(msdu);3779 dma_unmap_single(ar->ab->dev, rxcb->paddr,3780 msdu->len + skb_tailroom(msdu),3781 DMA_FROM_DEVICE);3782 3783 if (drop) {3784 dev_kfree_skb_any(msdu);3785 return 0;3786 }3787 3788 rcu_read_lock();3789 if (!rcu_dereference(ar->ab->pdevs_active[ar->pdev_idx])) {3790 dev_kfree_skb_any(msdu);3791 goto exit;3792 }3793 3794 if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) {3795 dev_kfree_skb_any(msdu);3796 goto exit;3797 }3798 3799 rx_desc = (struct hal_rx_desc *)msdu->data;3800 msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, rx_desc);3801 if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) {3802 hdr_status = ath11k_dp_rx_h_80211_hdr(ar->ab, rx_desc);3803 ath11k_warn(ar->ab, "invalid msdu leng %u", msdu_len);3804 ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status,3805 sizeof(struct ieee80211_hdr));3806 ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc,3807 sizeof(struct hal_rx_desc));3808 dev_kfree_skb_any(msdu);3809 goto exit;3810 }3811 3812 skb_put(msdu, hal_rx_desc_sz + msdu_len);3813 3814 if (ath11k_dp_rx_frag_h_mpdu(ar, msdu, ring_desc)) {3815 dev_kfree_skb_any(msdu);3816 ath11k_dp_rx_link_desc_return(ar->ab, ring_desc,3817 HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);3818 }3819exit:3820 rcu_read_unlock();3821 return 0;3822}3823 3824int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,3825 int budget)3826{3827 u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC];3828 struct dp_link_desc_bank *link_desc_banks;3829 enum hal_rx_buf_return_buf_manager rbm;3830 int tot_n_bufs_reaped, quota, ret, i;3831 int n_bufs_reaped[MAX_RADIOS] = {0};3832 struct dp_rxdma_ring *rx_ring;3833 struct dp_srng *reo_except;3834 u32 desc_bank, num_msdus;3835 struct hal_srng *srng;3836 struct ath11k_dp *dp;3837 void *link_desc_va;3838 int buf_id, mac_id;3839 struct ath11k *ar;3840 dma_addr_t paddr;3841 u32 *desc;3842 bool is_frag;3843 u8 drop = 0;3844 3845 tot_n_bufs_reaped = 0;3846 quota = budget;3847 3848 dp = &ab->dp;3849 reo_except = &dp->reo_except_ring;3850 link_desc_banks = dp->link_desc_banks;3851 3852 srng = &ab->hal.srng_list[reo_except->ring_id];3853 3854 spin_lock_bh(&srng->lock);3855 3856 ath11k_hal_srng_access_begin(ab, srng);3857 3858 while (budget &&3859 (desc = ath11k_hal_srng_dst_get_next_entry(ab, srng))) {3860 struct hal_reo_dest_ring *reo_desc = (struct hal_reo_dest_ring *)desc;3861 3862 ab->soc_stats.err_ring_pkts++;3863 ret = ath11k_hal_desc_reo_parse_err(ab, desc, &paddr,3864 &desc_bank);3865 if (ret) {3866 ath11k_warn(ab, "failed to parse error reo desc %d\n",3867 ret);3868 continue;3869 }3870 link_desc_va = link_desc_banks[desc_bank].vaddr +3871 (paddr - link_desc_banks[desc_bank].paddr);3872 ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,3873 &rbm);3874 if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST &&3875 rbm != HAL_RX_BUF_RBM_SW3_BM) {3876 ab->soc_stats.invalid_rbm++;3877 ath11k_warn(ab, "invalid return buffer manager %d\n", rbm);3878 ath11k_dp_rx_link_desc_return(ab, desc,3879 HAL_WBM_REL_BM_ACT_REL_MSDU);3880 continue;3881 }3882 3883 is_frag = !!(reo_desc->rx_mpdu_info.info0 & RX_MPDU_DESC_INFO0_FRAG_FLAG);3884 3885 /* Process only rx fragments with one msdu per link desc below, and drop3886 * msdu's indicated due to error reasons.3887 */3888 if (!is_frag || num_msdus > 1) {3889 drop = 1;3890 /* Return the link desc back to wbm idle list */3891 ath11k_dp_rx_link_desc_return(ab, desc,3892 HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);3893 }3894 3895 for (i = 0; i < num_msdus; i++) {3896 buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,3897 msdu_cookies[i]);3898 3899 mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID,3900 msdu_cookies[i]);3901 3902 ar = ab->pdevs[mac_id].ar;3903 3904 if (!ath11k_dp_process_rx_err_buf(ar, desc, buf_id, drop)) {3905 n_bufs_reaped[mac_id]++;3906 tot_n_bufs_reaped++;3907 }3908 }3909 3910 if (tot_n_bufs_reaped >= quota) {3911 tot_n_bufs_reaped = quota;3912 goto exit;3913 }3914 3915 budget = quota - tot_n_bufs_reaped;3916 }3917 3918exit:3919 ath11k_hal_srng_access_end(ab, srng);3920 3921 spin_unlock_bh(&srng->lock);3922 3923 for (i = 0; i < ab->num_radios; i++) {3924 if (!n_bufs_reaped[i])3925 continue;3926 3927 ar = ab->pdevs[i].ar;3928 rx_ring = &ar->dp.rx_refill_buf_ring;3929 3930 ath11k_dp_rxbufs_replenish(ab, i, rx_ring, n_bufs_reaped[i],3931 ab->hw_params.hal_params->rx_buf_rbm);3932 }3933 3934 return tot_n_bufs_reaped;3935}3936 3937static void ath11k_dp_rx_null_q_desc_sg_drop(struct ath11k *ar,3938 int msdu_len,3939 struct sk_buff_head *msdu_list)3940{3941 struct sk_buff *skb, *tmp;3942 struct ath11k_skb_rxcb *rxcb;3943 int n_buffs;3944 3945 n_buffs = DIV_ROUND_UP(msdu_len,3946 (DP_RX_BUFFER_SIZE - ar->ab->hw_params.hal_desc_sz));3947 3948 skb_queue_walk_safe(msdu_list, skb, tmp) {3949 rxcb = ATH11K_SKB_RXCB(skb);3950 if (rxcb->err_rel_src == HAL_WBM_REL_SRC_MODULE_REO &&3951 rxcb->err_code == HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO) {3952 if (!n_buffs)3953 break;3954 __skb_unlink(skb, msdu_list);3955 dev_kfree_skb_any(skb);3956 n_buffs--;3957 }3958 }3959}3960 3961static int ath11k_dp_rx_h_null_q_desc(struct ath11k *ar, struct sk_buff *msdu,3962 struct ieee80211_rx_status *status,3963 struct sk_buff_head *msdu_list)3964{3965 u16 msdu_len;3966 struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data;3967 struct rx_attention *rx_attention;3968 u8 l3pad_bytes;3969 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);3970 u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;3971 3972 msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, desc);3973 3974 if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) {3975 /* First buffer will be freed by the caller, so deduct it's length */3976 msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz);3977 ath11k_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list);3978 return -EINVAL;3979 }3980 3981 rx_attention = ath11k_dp_rx_get_attention(ar->ab, desc);3982 if (!ath11k_dp_rx_h_attn_msdu_done(rx_attention)) {3983 ath11k_warn(ar->ab,3984 "msdu_done bit not set in null_q_des processing\n");3985 __skb_queue_purge(msdu_list);3986 return -EIO;3987 }3988 3989 /* Handle NULL queue descriptor violations arising out a missing3990 * REO queue for a given peer or a given TID. This typically3991 * may happen if a packet is received on a QOS enabled TID before the3992 * ADDBA negotiation for that TID, when the TID queue is setup. Or3993 * it may also happen for MC/BC frames if they are not routed to the3994 * non-QOS TID queue, in the absence of any other default TID queue.3995 * This error can show up both in a REO destination or WBM release ring.3996 */3997 3998 rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(ar->ab, desc);3999 rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(ar->ab, desc);4000 4001 if (rxcb->is_frag) {4002 skb_pull(msdu, hal_rx_desc_sz);4003 } else {4004 l3pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, desc);4005 4006 if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE)4007 return -EINVAL;4008 4009 skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);4010 skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);4011 }4012 ath11k_dp_rx_h_ppdu(ar, desc, status);4013 4014 ath11k_dp_rx_h_mpdu(ar, msdu, desc, status);4015 4016 rxcb->tid = ath11k_dp_rx_h_mpdu_start_tid(ar->ab, desc);4017 4018 /* Please note that caller will having the access to msdu and completing4019 * rx with mac80211. Need not worry about cleaning up amsdu_list.4020 */4021 4022 return 0;4023}4024 4025static bool ath11k_dp_rx_h_reo_err(struct ath11k *ar, struct sk_buff *msdu,4026 struct ieee80211_rx_status *status,4027 struct sk_buff_head *msdu_list)4028{4029 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);4030 bool drop = false;4031 4032 ar->ab->soc_stats.reo_error[rxcb->err_code]++;4033 4034 switch (rxcb->err_code) {4035 case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO:4036 if (ath11k_dp_rx_h_null_q_desc(ar, msdu, status, msdu_list))4037 drop = true;4038 break;4039 case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED:4040 /* TODO: Do not drop PN failed packets in the driver;4041 * instead, it is good to drop such packets in mac802114042 * after incrementing the replay counters.4043 */4044 fallthrough;4045 default:4046 /* TODO: Review other errors and process them to mac802114047 * as appropriate.4048 */4049 drop = true;4050 break;4051 }4052 4053 return drop;4054}4055 4056static void ath11k_dp_rx_h_tkip_mic_err(struct ath11k *ar, struct sk_buff *msdu,4057 struct ieee80211_rx_status *status)4058{4059 u16 msdu_len;4060 struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data;4061 u8 l3pad_bytes;4062 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);4063 u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;4064 4065 rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(ar->ab, desc);4066 rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(ar->ab, desc);4067 4068 l3pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, desc);4069 msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, desc);4070 skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);4071 skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);4072 4073 ath11k_dp_rx_h_ppdu(ar, desc, status);4074 4075 status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR |4076 RX_FLAG_DECRYPTED);4077 4078 ath11k_dp_rx_h_undecap(ar, msdu, desc,4079 HAL_ENCRYPT_TYPE_TKIP_MIC, status, false);4080}4081 4082static bool ath11k_dp_rx_h_rxdma_err(struct ath11k *ar, struct sk_buff *msdu,4083 struct ieee80211_rx_status *status)4084{4085 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);4086 bool drop = false;4087 4088 ar->ab->soc_stats.rxdma_error[rxcb->err_code]++;4089 4090 switch (rxcb->err_code) {4091 case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR:4092 ath11k_dp_rx_h_tkip_mic_err(ar, msdu, status);4093 break;4094 default:4095 /* TODO: Review other rxdma error code to check if anything is4096 * worth reporting to mac802114097 */4098 drop = true;4099 break;4100 }4101 4102 return drop;4103}4104 4105static void ath11k_dp_rx_wbm_err(struct ath11k *ar,4106 struct napi_struct *napi,4107 struct sk_buff *msdu,4108 struct sk_buff_head *msdu_list)4109{4110 struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);4111 struct ieee80211_rx_status rxs = {0};4112 bool drop = true;4113 4114 switch (rxcb->err_rel_src) {4115 case HAL_WBM_REL_SRC_MODULE_REO:4116 drop = ath11k_dp_rx_h_reo_err(ar, msdu, &rxs, msdu_list);4117 break;4118 case HAL_WBM_REL_SRC_MODULE_RXDMA:4119 drop = ath11k_dp_rx_h_rxdma_err(ar, msdu, &rxs);4120 break;4121 default:4122 /* msdu will get freed */4123 break;4124 }4125 4126 if (drop) {4127 dev_kfree_skb_any(msdu);4128 return;4129 }4130 4131 ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rxs);4132}4133 4134int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab,4135 struct napi_struct *napi, int budget)4136{4137 struct ath11k *ar;4138 struct ath11k_dp *dp = &ab->dp;4139 struct dp_rxdma_ring *rx_ring;4140 struct hal_rx_wbm_rel_info err_info;4141 struct hal_srng *srng;4142 struct sk_buff *msdu;4143 struct sk_buff_head msdu_list[MAX_RADIOS];4144 struct ath11k_skb_rxcb *rxcb;4145 u32 *rx_desc;4146 int buf_id, mac_id;4147 int num_buffs_reaped[MAX_RADIOS] = {0};4148 int total_num_buffs_reaped = 0;4149 int ret, i;4150 4151 for (i = 0; i < ab->num_radios; i++)4152 __skb_queue_head_init(&msdu_list[i]);4153 4154 srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id];4155 4156 spin_lock_bh(&srng->lock);4157 4158 ath11k_hal_srng_access_begin(ab, srng);4159 4160 while (budget) {4161 rx_desc = ath11k_hal_srng_dst_get_next_entry(ab, srng);4162 if (!rx_desc)4163 break;4164 4165 ret = ath11k_hal_wbm_desc_parse_err(ab, rx_desc, &err_info);4166 if (ret) {4167 ath11k_warn(ab,4168 "failed to parse rx error in wbm_rel ring desc %d\n",4169 ret);4170 continue;4171 }4172 4173 buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, err_info.cookie);4174 mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, err_info.cookie);4175 4176 ar = ab->pdevs[mac_id].ar;4177 rx_ring = &ar->dp.rx_refill_buf_ring;4178 4179 spin_lock_bh(&rx_ring->idr_lock);4180 msdu = idr_find(&rx_ring->bufs_idr, buf_id);4181 if (!msdu) {4182 ath11k_warn(ab, "frame rx with invalid buf_id %d pdev %d\n",4183 buf_id, mac_id);4184 spin_unlock_bh(&rx_ring->idr_lock);4185 continue;4186 }4187 4188 idr_remove(&rx_ring->bufs_idr, buf_id);4189 spin_unlock_bh(&rx_ring->idr_lock);4190 4191 rxcb = ATH11K_SKB_RXCB(msdu);4192 dma_unmap_single(ab->dev, rxcb->paddr,4193 msdu->len + skb_tailroom(msdu),4194 DMA_FROM_DEVICE);4195 4196 num_buffs_reaped[mac_id]++;4197 total_num_buffs_reaped++;4198 budget--;4199 4200 if (err_info.push_reason !=4201 HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) {4202 dev_kfree_skb_any(msdu);4203 continue;4204 }4205 4206 rxcb->err_rel_src = err_info.err_rel_src;4207 rxcb->err_code = err_info.err_code;4208 rxcb->rx_desc = (struct hal_rx_desc *)msdu->data;4209 __skb_queue_tail(&msdu_list[mac_id], msdu);4210 }4211 4212 ath11k_hal_srng_access_end(ab, srng);4213 4214 spin_unlock_bh(&srng->lock);4215 4216 if (!total_num_buffs_reaped)4217 goto done;4218 4219 for (i = 0; i < ab->num_radios; i++) {4220 if (!num_buffs_reaped[i])4221 continue;4222 4223 ar = ab->pdevs[i].ar;4224 rx_ring = &ar->dp.rx_refill_buf_ring;4225 4226 ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i],4227 ab->hw_params.hal_params->rx_buf_rbm);4228 }4229 4230 rcu_read_lock();4231 for (i = 0; i < ab->num_radios; i++) {4232 if (!rcu_dereference(ab->pdevs_active[i])) {4233 __skb_queue_purge(&msdu_list[i]);4234 continue;4235 }4236 4237 ar = ab->pdevs[i].ar;4238 4239 if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) {4240 __skb_queue_purge(&msdu_list[i]);4241 continue;4242 }4243 4244 while ((msdu = __skb_dequeue(&msdu_list[i])) != NULL)4245 ath11k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list[i]);4246 }4247 rcu_read_unlock();4248done:4249 return total_num_buffs_reaped;4250}4251 4252int ath11k_dp_process_rxdma_err(struct ath11k_base *ab, int mac_id, int budget)4253{4254 struct ath11k *ar;4255 struct dp_srng *err_ring;4256 struct dp_rxdma_ring *rx_ring;4257 struct dp_link_desc_bank *link_desc_banks = ab->dp.link_desc_banks;4258 struct hal_srng *srng;4259 u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC];4260 enum hal_rx_buf_return_buf_manager rbm;4261 enum hal_reo_entr_rxdma_ecode rxdma_err_code;4262 struct ath11k_skb_rxcb *rxcb;4263 struct sk_buff *skb;4264 struct hal_reo_entrance_ring *entr_ring;4265 void *desc;4266 int num_buf_freed = 0;4267 int quota = budget;4268 dma_addr_t paddr;4269 u32 desc_bank;4270 void *link_desc_va;4271 int num_msdus;4272 int i;4273 int buf_id;4274 4275 ar = ab->pdevs[ath11k_hw_mac_id_to_pdev_id(&ab->hw_params, mac_id)].ar;4276 err_ring = &ar->dp.rxdma_err_dst_ring[ath11k_hw_mac_id_to_srng_id(&ab->hw_params,4277 mac_id)];4278 rx_ring = &ar->dp.rx_refill_buf_ring;4279 4280 srng = &ab->hal.srng_list[err_ring->ring_id];4281 4282 spin_lock_bh(&srng->lock);4283 4284 ath11k_hal_srng_access_begin(ab, srng);4285 4286 while (quota-- &&4287 (desc = ath11k_hal_srng_dst_get_next_entry(ab, srng))) {4288 ath11k_hal_rx_reo_ent_paddr_get(ab, desc, &paddr, &desc_bank);4289 4290 entr_ring = (struct hal_reo_entrance_ring *)desc;4291 rxdma_err_code =4292 FIELD_GET(HAL_REO_ENTR_RING_INFO1_RXDMA_ERROR_CODE,4293 entr_ring->info1);4294 ab->soc_stats.rxdma_error[rxdma_err_code]++;4295 4296 link_desc_va = link_desc_banks[desc_bank].vaddr +4297 (paddr - link_desc_banks[desc_bank].paddr);4298 ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus,4299 msdu_cookies, &rbm);4300 4301 for (i = 0; i < num_msdus; i++) {4302 buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,4303 msdu_cookies[i]);4304 4305 spin_lock_bh(&rx_ring->idr_lock);4306 skb = idr_find(&rx_ring->bufs_idr, buf_id);4307 if (!skb) {4308 ath11k_warn(ab, "rxdma error with invalid buf_id %d\n",4309 buf_id);4310 spin_unlock_bh(&rx_ring->idr_lock);4311 continue;4312 }4313 4314 idr_remove(&rx_ring->bufs_idr, buf_id);4315 spin_unlock_bh(&rx_ring->idr_lock);4316 4317 rxcb = ATH11K_SKB_RXCB(skb);4318 dma_unmap_single(ab->dev, rxcb->paddr,4319 skb->len + skb_tailroom(skb),4320 DMA_FROM_DEVICE);4321 dev_kfree_skb_any(skb);4322 4323 num_buf_freed++;4324 }4325 4326 ath11k_dp_rx_link_desc_return(ab, desc,4327 HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);4328 }4329 4330 ath11k_hal_srng_access_end(ab, srng);4331 4332 spin_unlock_bh(&srng->lock);4333 4334 if (num_buf_freed)4335 ath11k_dp_rxbufs_replenish(ab, mac_id, rx_ring, num_buf_freed,4336 ab->hw_params.hal_params->rx_buf_rbm);4337 4338 return budget - quota;4339}4340 4341void ath11k_dp_process_reo_status(struct ath11k_base *ab)4342{4343 struct ath11k_dp *dp = &ab->dp;4344 struct hal_srng *srng;4345 struct dp_reo_cmd *cmd, *tmp;4346 bool found = false;4347 u32 *reo_desc;4348 u16 tag;4349 struct hal_reo_status reo_status;4350 4351 srng = &ab->hal.srng_list[dp->reo_status_ring.ring_id];4352 4353 memset(&reo_status, 0, sizeof(reo_status));4354 4355 spin_lock_bh(&srng->lock);4356 4357 ath11k_hal_srng_access_begin(ab, srng);4358 4359 while ((reo_desc = ath11k_hal_srng_dst_get_next_entry(ab, srng))) {4360 tag = FIELD_GET(HAL_SRNG_TLV_HDR_TAG, *reo_desc);4361 4362 switch (tag) {4363 case HAL_REO_GET_QUEUE_STATS_STATUS:4364 ath11k_hal_reo_status_queue_stats(ab, reo_desc,4365 &reo_status);4366 break;4367 case HAL_REO_FLUSH_QUEUE_STATUS:4368 ath11k_hal_reo_flush_queue_status(ab, reo_desc,4369 &reo_status);4370 break;4371 case HAL_REO_FLUSH_CACHE_STATUS:4372 ath11k_hal_reo_flush_cache_status(ab, reo_desc,4373 &reo_status);4374 break;4375 case HAL_REO_UNBLOCK_CACHE_STATUS:4376 ath11k_hal_reo_unblk_cache_status(ab, reo_desc,4377 &reo_status);4378 break;4379 case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS:4380 ath11k_hal_reo_flush_timeout_list_status(ab, reo_desc,4381 &reo_status);4382 break;4383 case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS:4384 ath11k_hal_reo_desc_thresh_reached_status(ab, reo_desc,4385 &reo_status);4386 break;4387 case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS:4388 ath11k_hal_reo_update_rx_reo_queue_status(ab, reo_desc,4389 &reo_status);4390 break;4391 default:4392 ath11k_warn(ab, "Unknown reo status type %d\n", tag);4393 continue;4394 }4395 4396 spin_lock_bh(&dp->reo_cmd_lock);4397 list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) {4398 if (reo_status.uniform_hdr.cmd_num == cmd->cmd_num) {4399 found = true;4400 list_del(&cmd->list);4401 break;4402 }4403 }4404 spin_unlock_bh(&dp->reo_cmd_lock);4405 4406 if (found) {4407 cmd->handler(dp, (void *)&cmd->data,4408 reo_status.uniform_hdr.cmd_status);4409 kfree(cmd);4410 }4411 4412 found = false;4413 }4414 4415 ath11k_hal_srng_access_end(ab, srng);4416 4417 spin_unlock_bh(&srng->lock);4418}4419 4420void ath11k_dp_rx_pdev_free(struct ath11k_base *ab, int mac_id)4421{4422 struct ath11k *ar = ab->pdevs[mac_id].ar;4423 4424 ath11k_dp_rx_pdev_srng_free(ar);4425 ath11k_dp_rxdma_pdev_buf_free(ar);4426}4427 4428int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int mac_id)4429{4430 struct ath11k *ar = ab->pdevs[mac_id].ar;4431 struct ath11k_pdev_dp *dp = &ar->dp;4432 u32 ring_id;4433 int i;4434 int ret;4435 4436 ret = ath11k_dp_rx_pdev_srng_alloc(ar);4437 if (ret) {4438 ath11k_warn(ab, "failed to setup rx srngs\n");4439 return ret;4440 }4441 4442 ret = ath11k_dp_rxdma_pdev_buf_setup(ar);4443 if (ret) {4444 ath11k_warn(ab, "failed to setup rxdma ring\n");4445 return ret;4446 }4447 4448 ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id;4449 ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id, mac_id, HAL_RXDMA_BUF);4450 if (ret) {4451 ath11k_warn(ab, "failed to configure rx_refill_buf_ring %d\n",4452 ret);4453 return ret;4454 }4455 4456 if (ab->hw_params.rx_mac_buf_ring) {4457 for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {4458 ring_id = dp->rx_mac_buf_ring[i].ring_id;4459 ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id,4460 mac_id + i, HAL_RXDMA_BUF);4461 if (ret) {4462 ath11k_warn(ab, "failed to configure rx_mac_buf_ring%d %d\n",4463 i, ret);4464 return ret;4465 }4466 }4467 }4468 4469 for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {4470 ring_id = dp->rxdma_err_dst_ring[i].ring_id;4471 ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id,4472 mac_id + i, HAL_RXDMA_DST);4473 if (ret) {4474 ath11k_warn(ab, "failed to configure rxdma_err_dest_ring%d %d\n",4475 i, ret);4476 return ret;4477 }4478 }4479 4480 if (!ab->hw_params.rxdma1_enable)4481 goto config_refill_ring;4482 4483 ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id;4484 ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id,4485 mac_id, HAL_RXDMA_MONITOR_BUF);4486 if (ret) {4487 ath11k_warn(ab, "failed to configure rxdma_mon_buf_ring %d\n",4488 ret);4489 return ret;4490 }4491 ret = ath11k_dp_tx_htt_srng_setup(ab,4492 dp->rxdma_mon_dst_ring.ring_id,4493 mac_id, HAL_RXDMA_MONITOR_DST);4494 if (ret) {4495 ath11k_warn(ab, "failed to configure rxdma_mon_dst_ring %d\n",4496 ret);4497 return ret;4498 }4499 ret = ath11k_dp_tx_htt_srng_setup(ab,4500 dp->rxdma_mon_desc_ring.ring_id,4501 mac_id, HAL_RXDMA_MONITOR_DESC);4502 if (ret) {4503 ath11k_warn(ab, "failed to configure rxdma_mon_dst_ring %d\n",4504 ret);4505 return ret;4506 }4507 4508config_refill_ring:4509 for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {4510 ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;4511 ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id, mac_id + i,4512 HAL_RXDMA_MONITOR_STATUS);4513 if (ret) {4514 ath11k_warn(ab,4515 "failed to configure mon_status_refill_ring%d %d\n",4516 i, ret);4517 return ret;4518 }4519 }4520 4521 return 0;4522}4523 4524static void ath11k_dp_mon_set_frag_len(u32 *total_len, u32 *frag_len)4525{4526 if (*total_len >= (DP_RX_BUFFER_SIZE - sizeof(struct hal_rx_desc))) {4527 *frag_len = DP_RX_BUFFER_SIZE - sizeof(struct hal_rx_desc);4528 *total_len -= *frag_len;4529 } else {4530 *frag_len = *total_len;4531 *total_len = 0;4532 }4533}4534 4535static4536int ath11k_dp_rx_monitor_link_desc_return(struct ath11k *ar,4537 void *p_last_buf_addr_info,4538 u8 mac_id)4539{4540 struct ath11k_pdev_dp *dp = &ar->dp;4541 struct dp_srng *dp_srng;4542 void *hal_srng;4543 void *src_srng_desc;4544 int ret = 0;4545 4546 if (ar->ab->hw_params.rxdma1_enable) {4547 dp_srng = &dp->rxdma_mon_desc_ring;4548 hal_srng = &ar->ab->hal.srng_list[dp_srng->ring_id];4549 } else {4550 dp_srng = &ar->ab->dp.wbm_desc_rel_ring;4551 hal_srng = &ar->ab->hal.srng_list[dp_srng->ring_id];4552 }4553 4554 ath11k_hal_srng_access_begin(ar->ab, hal_srng);4555 4556 src_srng_desc = ath11k_hal_srng_src_get_next_entry(ar->ab, hal_srng);4557 4558 if (src_srng_desc) {4559 struct ath11k_buffer_addr *src_desc = src_srng_desc;4560 4561 *src_desc = *((struct ath11k_buffer_addr *)p_last_buf_addr_info);4562 } else {4563 ath11k_dbg(ar->ab, ATH11K_DBG_DATA,4564 "Monitor Link Desc Ring %d Full", mac_id);4565 ret = -ENOMEM;4566 }4567 4568 ath11k_hal_srng_access_end(ar->ab, hal_srng);4569 return ret;4570}4571 4572static4573void ath11k_dp_rx_mon_next_link_desc_get(void *rx_msdu_link_desc,4574 dma_addr_t *paddr, u32 *sw_cookie,4575 u8 *rbm,4576 void **pp_buf_addr_info)4577{4578 struct hal_rx_msdu_link *msdu_link = rx_msdu_link_desc;4579 struct ath11k_buffer_addr *buf_addr_info;4580 4581 buf_addr_info = (struct ath11k_buffer_addr *)&msdu_link->buf_addr_info;4582 4583 ath11k_hal_rx_buf_addr_info_get(buf_addr_info, paddr, sw_cookie, rbm);4584 4585 *pp_buf_addr_info = (void *)buf_addr_info;4586}4587 4588static int ath11k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len)4589{4590 if (skb->len > len) {4591 skb_trim(skb, len);4592 } else {4593 if (skb_tailroom(skb) < len - skb->len) {4594 if ((pskb_expand_head(skb, 0,4595 len - skb->len - skb_tailroom(skb),4596 GFP_ATOMIC))) {4597 dev_kfree_skb_any(skb);4598 return -ENOMEM;4599 }4600 }4601 skb_put(skb, (len - skb->len));4602 }4603 return 0;4604}4605 4606static void ath11k_hal_rx_msdu_list_get(struct ath11k *ar,4607 void *msdu_link_desc,4608 struct hal_rx_msdu_list *msdu_list,4609 u16 *num_msdus)4610{4611 struct hal_rx_msdu_details *msdu_details = NULL;4612 struct rx_msdu_desc *msdu_desc_info = NULL;4613 struct hal_rx_msdu_link *msdu_link = NULL;4614 int i;4615 u32 last = FIELD_PREP(RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU, 1);4616 u32 first = FIELD_PREP(RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU, 1);4617 u8 tmp = 0;4618 4619 msdu_link = msdu_link_desc;4620 msdu_details = &msdu_link->msdu_link[0];4621 4622 for (i = 0; i < HAL_RX_NUM_MSDU_DESC; i++) {4623 if (FIELD_GET(BUFFER_ADDR_INFO0_ADDR,4624 msdu_details[i].buf_addr_info.info0) == 0) {4625 msdu_desc_info = &msdu_details[i - 1].rx_msdu_info;4626 msdu_desc_info->info0 |= last;4627 ;4628 break;4629 }4630 msdu_desc_info = &msdu_details[i].rx_msdu_info;4631 4632 if (!i)4633 msdu_desc_info->info0 |= first;4634 else if (i == (HAL_RX_NUM_MSDU_DESC - 1))4635 msdu_desc_info->info0 |= last;4636 msdu_list->msdu_info[i].msdu_flags = msdu_desc_info->info0;4637 msdu_list->msdu_info[i].msdu_len =4638 HAL_RX_MSDU_PKT_LENGTH_GET(msdu_desc_info->info0);4639 msdu_list->sw_cookie[i] =4640 FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,4641 msdu_details[i].buf_addr_info.info1);4642 tmp = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,4643 msdu_details[i].buf_addr_info.info1);4644 msdu_list->rbm[i] = tmp;4645 }4646 *num_msdus = i;4647}4648 4649static u32 ath11k_dp_rx_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id,4650 u32 *rx_bufs_used)4651{4652 u32 ret = 0;4653 4654 if ((*ppdu_id < msdu_ppdu_id) &&4655 ((msdu_ppdu_id - *ppdu_id) < DP_NOT_PPDU_ID_WRAP_AROUND)) {4656 *ppdu_id = msdu_ppdu_id;4657 ret = msdu_ppdu_id;4658 } else if ((*ppdu_id > msdu_ppdu_id) &&4659 ((*ppdu_id - msdu_ppdu_id) > DP_NOT_PPDU_ID_WRAP_AROUND)) {4660 /* mon_dst is behind than mon_status4661 * skip dst_ring and free it4662 */4663 *rx_bufs_used += 1;4664 *ppdu_id = msdu_ppdu_id;4665 ret = msdu_ppdu_id;4666 }4667 return ret;4668}4669 4670static void ath11k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info,4671 bool *is_frag, u32 *total_len,4672 u32 *frag_len, u32 *msdu_cnt)4673{4674 if (info->msdu_flags & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) {4675 if (!*is_frag) {4676 *total_len = info->msdu_len;4677 *is_frag = true;4678 }4679 ath11k_dp_mon_set_frag_len(total_len,4680 frag_len);4681 } else {4682 if (*is_frag) {4683 ath11k_dp_mon_set_frag_len(total_len,4684 frag_len);4685 } else {4686 *frag_len = info->msdu_len;4687 }4688 *is_frag = false;4689 *msdu_cnt -= 1;4690 }4691}4692 4693static u324694ath11k_dp_rx_mon_mpdu_pop(struct ath11k *ar, int mac_id,4695 void *ring_entry, struct sk_buff **head_msdu,4696 struct sk_buff **tail_msdu, u32 *npackets,4697 u32 *ppdu_id)4698{4699 struct ath11k_pdev_dp *dp = &ar->dp;4700 struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data;4701 struct dp_rxdma_ring *rx_ring = &dp->rxdma_mon_buf_ring;4702 struct sk_buff *msdu = NULL, *last = NULL;4703 struct hal_rx_msdu_list msdu_list;4704 void *p_buf_addr_info, *p_last_buf_addr_info;4705 struct hal_rx_desc *rx_desc;4706 void *rx_msdu_link_desc;4707 dma_addr_t paddr;4708 u16 num_msdus = 0;4709 u32 rx_buf_size, rx_pkt_offset, sw_cookie;4710 u32 rx_bufs_used = 0, i = 0;4711 u32 msdu_ppdu_id = 0, msdu_cnt = 0;4712 u32 total_len = 0, frag_len = 0;4713 bool is_frag, is_first_msdu;4714 bool drop_mpdu = false;4715 struct ath11k_skb_rxcb *rxcb;4716 struct hal_reo_entrance_ring *ent_desc = ring_entry;4717 int buf_id;4718 u32 rx_link_buf_info[2];4719 u8 rbm;4720 4721 if (!ar->ab->hw_params.rxdma1_enable)4722 rx_ring = &dp->rx_refill_buf_ring;4723 4724 ath11k_hal_rx_reo_ent_buf_paddr_get(ring_entry, &paddr,4725 &sw_cookie,4726 &p_last_buf_addr_info, &rbm,4727 &msdu_cnt);4728 4729 if (FIELD_GET(HAL_REO_ENTR_RING_INFO1_RXDMA_PUSH_REASON,4730 ent_desc->info1) ==4731 HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) {4732 u8 rxdma_err =4733 FIELD_GET(HAL_REO_ENTR_RING_INFO1_RXDMA_ERROR_CODE,4734 ent_desc->info1);4735 if (rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR ||4736 rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR ||4737 rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR) {4738 drop_mpdu = true;4739 pmon->rx_mon_stats.dest_mpdu_drop++;4740 }4741 }4742 4743 is_frag = false;4744 is_first_msdu = true;4745 4746 do {4747 if (pmon->mon_last_linkdesc_paddr == paddr) {4748 pmon->rx_mon_stats.dup_mon_linkdesc_cnt++;4749 return rx_bufs_used;4750 }4751 4752 if (ar->ab->hw_params.rxdma1_enable)4753 rx_msdu_link_desc =4754 (void *)pmon->link_desc_banks[sw_cookie].vaddr +4755 (paddr - pmon->link_desc_banks[sw_cookie].paddr);4756 else4757 rx_msdu_link_desc =4758 (void *)ar->ab->dp.link_desc_banks[sw_cookie].vaddr +4759 (paddr - ar->ab->dp.link_desc_banks[sw_cookie].paddr);4760 4761 ath11k_hal_rx_msdu_list_get(ar, rx_msdu_link_desc, &msdu_list,4762 &num_msdus);4763 4764 for (i = 0; i < num_msdus; i++) {4765 u32 l2_hdr_offset;4766 4767 if (pmon->mon_last_buf_cookie == msdu_list.sw_cookie[i]) {4768 ath11k_dbg(ar->ab, ATH11K_DBG_DATA,4769 "i %d last_cookie %d is same\n",4770 i, pmon->mon_last_buf_cookie);4771 drop_mpdu = true;4772 pmon->rx_mon_stats.dup_mon_buf_cnt++;4773 continue;4774 }4775 buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,4776 msdu_list.sw_cookie[i]);4777 4778 spin_lock_bh(&rx_ring->idr_lock);4779 msdu = idr_find(&rx_ring->bufs_idr, buf_id);4780 spin_unlock_bh(&rx_ring->idr_lock);4781 if (!msdu) {4782 ath11k_dbg(ar->ab, ATH11K_DBG_DATA,4783 "msdu_pop: invalid buf_id %d\n", buf_id);4784 break;4785 }4786 rxcb = ATH11K_SKB_RXCB(msdu);4787 if (!rxcb->unmapped) {4788 dma_unmap_single(ar->ab->dev, rxcb->paddr,4789 msdu->len +4790 skb_tailroom(msdu),4791 DMA_FROM_DEVICE);4792 rxcb->unmapped = 1;4793 }4794 if (drop_mpdu) {4795 ath11k_dbg(ar->ab, ATH11K_DBG_DATA,4796 "i %d drop msdu %p *ppdu_id %x\n",4797 i, msdu, *ppdu_id);4798 dev_kfree_skb_any(msdu);4799 msdu = NULL;4800 goto next_msdu;4801 }4802 4803 rx_desc = (struct hal_rx_desc *)msdu->data;4804 4805 rx_pkt_offset = sizeof(struct hal_rx_desc);4806 l2_hdr_offset = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, rx_desc);4807 4808 if (is_first_msdu) {4809 if (!ath11k_dp_rxdesc_mpdu_valid(ar->ab, rx_desc)) {4810 drop_mpdu = true;4811 dev_kfree_skb_any(msdu);4812 msdu = NULL;4813 pmon->mon_last_linkdesc_paddr = paddr;4814 goto next_msdu;4815 }4816 4817 msdu_ppdu_id =4818 ath11k_dp_rxdesc_get_ppduid(ar->ab, rx_desc);4819 4820 if (ath11k_dp_rx_mon_comp_ppduid(msdu_ppdu_id,4821 ppdu_id,4822 &rx_bufs_used)) {4823 if (rx_bufs_used) {4824 drop_mpdu = true;4825 dev_kfree_skb_any(msdu);4826 msdu = NULL;4827 goto next_msdu;4828 }4829 return rx_bufs_used;4830 }4831 pmon->mon_last_linkdesc_paddr = paddr;4832 is_first_msdu = false;4833 }4834 ath11k_dp_mon_get_buf_len(&msdu_list.msdu_info[i],4835 &is_frag, &total_len,4836 &frag_len, &msdu_cnt);4837 rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len;4838 4839 ath11k_dp_pkt_set_pktlen(msdu, rx_buf_size);4840 4841 if (!(*head_msdu))4842 *head_msdu = msdu;4843 else if (last)4844 last->next = msdu;4845 4846 last = msdu;4847next_msdu:4848 pmon->mon_last_buf_cookie = msdu_list.sw_cookie[i];4849 rx_bufs_used++;4850 spin_lock_bh(&rx_ring->idr_lock);4851 idr_remove(&rx_ring->bufs_idr, buf_id);4852 spin_unlock_bh(&rx_ring->idr_lock);4853 }4854 4855 ath11k_hal_rx_buf_addr_info_set(rx_link_buf_info, paddr, sw_cookie, rbm);4856 4857 ath11k_dp_rx_mon_next_link_desc_get(rx_msdu_link_desc, &paddr,4858 &sw_cookie, &rbm,4859 &p_buf_addr_info);4860 4861 if (ar->ab->hw_params.rxdma1_enable) {4862 if (ath11k_dp_rx_monitor_link_desc_return(ar,4863 p_last_buf_addr_info,4864 dp->mac_id))4865 ath11k_dbg(ar->ab, ATH11K_DBG_DATA,4866 "dp_rx_monitor_link_desc_return failed");4867 } else {4868 ath11k_dp_rx_link_desc_return(ar->ab, rx_link_buf_info,4869 HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);4870 }4871 4872 p_last_buf_addr_info = p_buf_addr_info;4873 4874 } while (paddr && msdu_cnt);4875 4876 if (last)4877 last->next = NULL;4878 4879 *tail_msdu = msdu;4880 4881 if (msdu_cnt == 0)4882 *npackets = 1;4883 4884 return rx_bufs_used;4885}4886 4887static void ath11k_dp_rx_msdus_set_payload(struct ath11k *ar, struct sk_buff *msdu)4888{4889 u32 rx_pkt_offset, l2_hdr_offset;4890 4891 rx_pkt_offset = ar->ab->hw_params.hal_desc_sz;4892 l2_hdr_offset = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab,4893 (struct hal_rx_desc *)msdu->data);4894 skb_pull(msdu, rx_pkt_offset + l2_hdr_offset);4895}4896 4897static struct sk_buff *4898ath11k_dp_rx_mon_merg_msdus(struct ath11k *ar,4899 u32 mac_id, struct sk_buff *head_msdu,4900 struct sk_buff *last_msdu,4901 struct ieee80211_rx_status *rxs, bool *fcs_err)4902{4903 struct ath11k_base *ab = ar->ab;4904 struct sk_buff *msdu, *prev_buf;4905 struct hal_rx_desc *rx_desc;4906 char *hdr_desc;4907 u8 *dest, decap_format;4908 struct ieee80211_hdr_3addr *wh;4909 struct rx_attention *rx_attention;4910 u32 err_bitmap;4911 4912 if (!head_msdu)4913 goto err_merge_fail;4914 4915 rx_desc = (struct hal_rx_desc *)head_msdu->data;4916 rx_attention = ath11k_dp_rx_get_attention(ab, rx_desc);4917 err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention);4918 4919 if (err_bitmap & DP_RX_MPDU_ERR_FCS)4920 *fcs_err = true;4921 4922 if (ath11k_dp_rxdesc_get_mpdulen_err(rx_attention))4923 return NULL;4924 4925 decap_format = ath11k_dp_rx_h_msdu_start_decap_type(ab, rx_desc);4926 4927 ath11k_dp_rx_h_ppdu(ar, rx_desc, rxs);4928 4929 if (decap_format == DP_RX_DECAP_TYPE_RAW) {4930 ath11k_dp_rx_msdus_set_payload(ar, head_msdu);4931 4932 prev_buf = head_msdu;4933 msdu = head_msdu->next;4934 4935 while (msdu) {4936 ath11k_dp_rx_msdus_set_payload(ar, msdu);4937 4938 prev_buf = msdu;4939 msdu = msdu->next;4940 }4941 4942 prev_buf->next = NULL;4943 4944 skb_trim(prev_buf, prev_buf->len - HAL_RX_FCS_LEN);4945 } else if (decap_format == DP_RX_DECAP_TYPE_NATIVE_WIFI) {4946 u8 qos_pkt = 0;4947 4948 rx_desc = (struct hal_rx_desc *)head_msdu->data;4949 hdr_desc = ath11k_dp_rxdesc_get_80211hdr(ab, rx_desc);4950 4951 /* Base size */4952 wh = (struct ieee80211_hdr_3addr *)hdr_desc;4953 4954 if (ieee80211_is_data_qos(wh->frame_control))4955 qos_pkt = 1;4956 4957 msdu = head_msdu;4958 4959 while (msdu) {4960 ath11k_dp_rx_msdus_set_payload(ar, msdu);4961 if (qos_pkt) {4962 dest = skb_push(msdu, sizeof(__le16));4963 if (!dest)4964 goto err_merge_fail;4965 memcpy(dest, hdr_desc, sizeof(struct ieee80211_qos_hdr));4966 }4967 prev_buf = msdu;4968 msdu = msdu->next;4969 }4970 dest = skb_put(prev_buf, HAL_RX_FCS_LEN);4971 if (!dest)4972 goto err_merge_fail;4973 4974 ath11k_dbg(ab, ATH11K_DBG_DATA,4975 "mpdu_buf %p mpdu_buf->len %u",4976 prev_buf, prev_buf->len);4977 } else {4978 ath11k_dbg(ab, ATH11K_DBG_DATA,4979 "decap format %d is not supported!\n",4980 decap_format);4981 goto err_merge_fail;4982 }4983 4984 return head_msdu;4985 4986err_merge_fail:4987 return NULL;4988}4989 4990static void4991ath11k_dp_rx_update_radiotap_he(struct hal_rx_mon_ppdu_info *rx_status,4992 u8 *rtap_buf)4993{4994 u32 rtap_len = 0;4995 4996 put_unaligned_le16(rx_status->he_data1, &rtap_buf[rtap_len]);4997 rtap_len += 2;4998 4999 put_unaligned_le16(rx_status->he_data2, &rtap_buf[rtap_len]);5000 rtap_len += 2;5001 5002 put_unaligned_le16(rx_status->he_data3, &rtap_buf[rtap_len]);5003 rtap_len += 2;5004 5005 put_unaligned_le16(rx_status->he_data4, &rtap_buf[rtap_len]);5006 rtap_len += 2;5007 5008 put_unaligned_le16(rx_status->he_data5, &rtap_buf[rtap_len]);5009 rtap_len += 2;5010 5011 put_unaligned_le16(rx_status->he_data6, &rtap_buf[rtap_len]);5012}5013 5014static void5015ath11k_dp_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info *rx_status,5016 u8 *rtap_buf)5017{5018 u32 rtap_len = 0;5019 5020 put_unaligned_le16(rx_status->he_flags1, &rtap_buf[rtap_len]);5021 rtap_len += 2;5022 5023 put_unaligned_le16(rx_status->he_flags2, &rtap_buf[rtap_len]);5024 rtap_len += 2;5025 5026 rtap_buf[rtap_len] = rx_status->he_RU[0];5027 rtap_len += 1;5028 5029 rtap_buf[rtap_len] = rx_status->he_RU[1];5030 rtap_len += 1;5031 5032 rtap_buf[rtap_len] = rx_status->he_RU[2];5033 rtap_len += 1;5034 5035 rtap_buf[rtap_len] = rx_status->he_RU[3];5036}5037 5038static void ath11k_update_radiotap(struct ath11k *ar,5039 struct hal_rx_mon_ppdu_info *ppduinfo,5040 struct sk_buff *mon_skb,5041 struct ieee80211_rx_status *rxs)5042{5043 struct ieee80211_supported_band *sband;5044 u8 *ptr = NULL;5045 5046 rxs->flag |= RX_FLAG_MACTIME_START;5047 rxs->signal = ppduinfo->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR;5048 5049 if (ppduinfo->nss)5050 rxs->nss = ppduinfo->nss;5051 5052 if (ppduinfo->he_mu_flags) {5053 rxs->flag |= RX_FLAG_RADIOTAP_HE_MU;5054 rxs->encoding = RX_ENC_HE;5055 ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he_mu));5056 ath11k_dp_rx_update_radiotap_he_mu(ppduinfo, ptr);5057 } else if (ppduinfo->he_flags) {5058 rxs->flag |= RX_FLAG_RADIOTAP_HE;5059 rxs->encoding = RX_ENC_HE;5060 ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he));5061 ath11k_dp_rx_update_radiotap_he(ppduinfo, ptr);5062 rxs->rate_idx = ppduinfo->rate;5063 } else if (ppduinfo->vht_flags) {5064 rxs->encoding = RX_ENC_VHT;5065 rxs->rate_idx = ppduinfo->rate;5066 } else if (ppduinfo->ht_flags) {5067 rxs->encoding = RX_ENC_HT;5068 rxs->rate_idx = ppduinfo->rate;5069 } else {5070 rxs->encoding = RX_ENC_LEGACY;5071 sband = &ar->mac.sbands[rxs->band];5072 rxs->rate_idx = ath11k_mac_hw_rate_to_idx(sband, ppduinfo->rate,5073 ppduinfo->cck_flag);5074 }5075 5076 rxs->mactime = ppduinfo->tsft;5077}5078 5079static int ath11k_dp_rx_mon_deliver(struct ath11k *ar, u32 mac_id,5080 struct sk_buff *head_msdu,5081 struct hal_rx_mon_ppdu_info *ppduinfo,5082 struct sk_buff *tail_msdu,5083 struct napi_struct *napi)5084{5085 struct ath11k_pdev_dp *dp = &ar->dp;5086 struct sk_buff *mon_skb, *skb_next, *header;5087 struct ieee80211_rx_status *rxs = &dp->rx_status;5088 bool fcs_err = false;5089 5090 mon_skb = ath11k_dp_rx_mon_merg_msdus(ar, mac_id, head_msdu,5091 tail_msdu, rxs, &fcs_err);5092 5093 if (!mon_skb)5094 goto mon_deliver_fail;5095 5096 header = mon_skb;5097 5098 rxs->flag = 0;5099 5100 if (fcs_err)5101 rxs->flag = RX_FLAG_FAILED_FCS_CRC;5102 5103 do {5104 skb_next = mon_skb->next;5105 if (!skb_next)5106 rxs->flag &= ~RX_FLAG_AMSDU_MORE;5107 else5108 rxs->flag |= RX_FLAG_AMSDU_MORE;5109 5110 if (mon_skb == header) {5111 header = NULL;5112 rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN;5113 } else {5114 rxs->flag |= RX_FLAG_ALLOW_SAME_PN;5115 }5116 rxs->flag |= RX_FLAG_ONLY_MONITOR;5117 ath11k_update_radiotap(ar, ppduinfo, mon_skb, rxs);5118 5119 ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb, rxs);5120 mon_skb = skb_next;5121 } while (mon_skb);5122 rxs->flag = 0;5123 5124 return 0;5125 5126mon_deliver_fail:5127 mon_skb = head_msdu;5128 while (mon_skb) {5129 skb_next = mon_skb->next;5130 dev_kfree_skb_any(mon_skb);5131 mon_skb = skb_next;5132 }5133 return -EINVAL;5134}5135 5136/* The destination ring processing is stuck if the destination is not5137 * moving while status ring moves 16 PPDU. The destination ring processing5138 * skips this destination ring PPDU as a workaround.5139 */5140#define MON_DEST_RING_STUCK_MAX_CNT 165141 5142static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,5143 u32 quota, struct napi_struct *napi)5144{5145 struct ath11k_pdev_dp *dp = &ar->dp;5146 struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data;5147 const struct ath11k_hw_hal_params *hal_params;5148 void *ring_entry;5149 void *mon_dst_srng;5150 u32 ppdu_id;5151 u32 rx_bufs_used;5152 u32 ring_id;5153 struct ath11k_pdev_mon_stats *rx_mon_stats;5154 u32 npackets = 0;5155 u32 mpdu_rx_bufs_used;5156 5157 if (ar->ab->hw_params.rxdma1_enable)5158 ring_id = dp->rxdma_mon_dst_ring.ring_id;5159 else5160 ring_id = dp->rxdma_err_dst_ring[mac_id].ring_id;5161 5162 mon_dst_srng = &ar->ab->hal.srng_list[ring_id];5163 5164 spin_lock_bh(&pmon->mon_lock);5165 5166 ath11k_hal_srng_access_begin(ar->ab, mon_dst_srng);5167 5168 ppdu_id = pmon->mon_ppdu_info.ppdu_id;5169 rx_bufs_used = 0;5170 rx_mon_stats = &pmon->rx_mon_stats;5171 5172 while ((ring_entry = ath11k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) {5173 struct sk_buff *head_msdu, *tail_msdu;5174 5175 head_msdu = NULL;5176 tail_msdu = NULL;5177 5178 mpdu_rx_bufs_used = ath11k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry,5179 &head_msdu,5180 &tail_msdu,5181 &npackets, &ppdu_id);5182 5183 rx_bufs_used += mpdu_rx_bufs_used;5184 5185 if (mpdu_rx_bufs_used) {5186 dp->mon_dest_ring_stuck_cnt = 0;5187 } else {5188 dp->mon_dest_ring_stuck_cnt++;5189 rx_mon_stats->dest_mon_not_reaped++;5190 }5191 5192 if (dp->mon_dest_ring_stuck_cnt > MON_DEST_RING_STUCK_MAX_CNT) {5193 rx_mon_stats->dest_mon_stuck++;5194 ath11k_dbg(ar->ab, ATH11K_DBG_DATA,5195 "status ring ppdu_id=%d dest ring ppdu_id=%d mon_dest_ring_stuck_cnt=%d dest_mon_not_reaped=%u dest_mon_stuck=%u\n",5196 pmon->mon_ppdu_info.ppdu_id, ppdu_id,5197 dp->mon_dest_ring_stuck_cnt,5198 rx_mon_stats->dest_mon_not_reaped,5199 rx_mon_stats->dest_mon_stuck);5200 pmon->mon_ppdu_info.ppdu_id = ppdu_id;5201 continue;5202 }5203 5204 if (ppdu_id != pmon->mon_ppdu_info.ppdu_id) {5205 pmon->mon_ppdu_status = DP_PPDU_STATUS_START;5206 ath11k_dbg(ar->ab, ATH11K_DBG_DATA,5207 "dest_rx: new ppdu_id %x != status ppdu_id %x dest_mon_not_reaped = %u dest_mon_stuck = %u\n",5208 ppdu_id, pmon->mon_ppdu_info.ppdu_id,5209 rx_mon_stats->dest_mon_not_reaped,5210 rx_mon_stats->dest_mon_stuck);5211 break;5212 }5213 if (head_msdu && tail_msdu) {5214 ath11k_dp_rx_mon_deliver(ar, dp->mac_id, head_msdu,5215 &pmon->mon_ppdu_info,5216 tail_msdu, napi);5217 rx_mon_stats->dest_mpdu_done++;5218 }5219 5220 ring_entry = ath11k_hal_srng_dst_get_next_entry(ar->ab,5221 mon_dst_srng);5222 }5223 ath11k_hal_srng_access_end(ar->ab, mon_dst_srng);5224 5225 spin_unlock_bh(&pmon->mon_lock);5226 5227 if (rx_bufs_used) {5228 rx_mon_stats->dest_ppdu_done++;5229 hal_params = ar->ab->hw_params.hal_params;5230 5231 if (ar->ab->hw_params.rxdma1_enable)5232 ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id,5233 &dp->rxdma_mon_buf_ring,5234 rx_bufs_used,5235 hal_params->rx_buf_rbm);5236 else5237 ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id,5238 &dp->rx_refill_buf_ring,5239 rx_bufs_used,5240 hal_params->rx_buf_rbm);5241 }5242}5243 5244int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,5245 struct napi_struct *napi, int budget)5246{5247 struct ath11k *ar = ath11k_ab_to_ar(ab, mac_id);5248 enum hal_rx_mon_status hal_status;5249 struct sk_buff *skb;5250 struct sk_buff_head skb_list;5251 struct ath11k_peer *peer;5252 struct ath11k_sta *arsta;5253 int num_buffs_reaped = 0;5254 u32 rx_buf_sz;5255 u16 log_type;5256 struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&ar->dp.mon_data;5257 struct ath11k_pdev_mon_stats *rx_mon_stats = &pmon->rx_mon_stats;5258 struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;5259 5260 __skb_queue_head_init(&skb_list);5261 5262 num_buffs_reaped = ath11k_dp_rx_reap_mon_status_ring(ab, mac_id, &budget,5263 &skb_list);5264 if (!num_buffs_reaped)5265 goto exit;5266 5267 memset(ppdu_info, 0, sizeof(*ppdu_info));5268 ppdu_info->peer_id = HAL_INVALID_PEERID;5269 5270 while ((skb = __skb_dequeue(&skb_list))) {5271 if (ath11k_debugfs_is_pktlog_lite_mode_enabled(ar)) {5272 log_type = ATH11K_PKTLOG_TYPE_LITE_RX;5273 rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;5274 } else if (ath11k_debugfs_is_pktlog_rx_stats_enabled(ar)) {5275 log_type = ATH11K_PKTLOG_TYPE_RX_STATBUF;5276 rx_buf_sz = DP_RX_BUFFER_SIZE;5277 } else {5278 log_type = ATH11K_PKTLOG_TYPE_INVALID;5279 rx_buf_sz = 0;5280 }5281 5282 if (log_type != ATH11K_PKTLOG_TYPE_INVALID)5283 trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz);5284 5285 memset(ppdu_info, 0, sizeof(*ppdu_info));5286 ppdu_info->peer_id = HAL_INVALID_PEERID;5287 hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb);5288 5289 if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags) &&5290 pmon->mon_ppdu_status == DP_PPDU_STATUS_START &&5291 hal_status == HAL_TLV_STATUS_PPDU_DONE) {5292 rx_mon_stats->status_ppdu_done++;5293 pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE;5294 if (!ab->hw_params.full_monitor_mode) {5295 ath11k_dp_rx_mon_dest_process(ar, mac_id,5296 budget, napi);5297 pmon->mon_ppdu_status = DP_PPDU_STATUS_START;5298 }5299 }5300 5301 if (ppdu_info->peer_id == HAL_INVALID_PEERID ||5302 hal_status != HAL_RX_MON_STATUS_PPDU_DONE) {5303 dev_kfree_skb_any(skb);5304 continue;5305 }5306 5307 rcu_read_lock();5308 spin_lock_bh(&ab->base_lock);5309 peer = ath11k_peer_find_by_id(ab, ppdu_info->peer_id);5310 5311 if (!peer || !peer->sta) {5312 ath11k_dbg(ab, ATH11K_DBG_DATA,5313 "failed to find the peer with peer_id %d\n",5314 ppdu_info->peer_id);5315 goto next_skb;5316 }5317 5318 arsta = ath11k_sta_to_arsta(peer->sta);5319 ath11k_dp_rx_update_peer_stats(arsta, ppdu_info);5320 5321 if (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr))5322 trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz);5323 5324next_skb:5325 spin_unlock_bh(&ab->base_lock);5326 rcu_read_unlock();5327 5328 dev_kfree_skb_any(skb);5329 memset(ppdu_info, 0, sizeof(*ppdu_info));5330 ppdu_info->peer_id = HAL_INVALID_PEERID;5331 }5332exit:5333 return num_buffs_reaped;5334}5335 5336static u325337ath11k_dp_rx_full_mon_mpdu_pop(struct ath11k *ar,5338 void *ring_entry, struct sk_buff **head_msdu,5339 struct sk_buff **tail_msdu,5340 struct hal_sw_mon_ring_entries *sw_mon_entries)5341{5342 struct ath11k_pdev_dp *dp = &ar->dp;5343 struct ath11k_mon_data *pmon = &dp->mon_data;5344 struct dp_rxdma_ring *rx_ring = &dp->rxdma_mon_buf_ring;5345 struct sk_buff *msdu = NULL, *last = NULL;5346 struct hal_sw_monitor_ring *sw_desc = ring_entry;5347 struct hal_rx_msdu_list msdu_list;5348 struct hal_rx_desc *rx_desc;5349 struct ath11k_skb_rxcb *rxcb;5350 void *rx_msdu_link_desc;5351 void *p_buf_addr_info, *p_last_buf_addr_info;5352 int buf_id, i = 0;5353 u32 rx_buf_size, rx_pkt_offset, l2_hdr_offset;5354 u32 rx_bufs_used = 0, msdu_cnt = 0;5355 u32 total_len = 0, frag_len = 0, sw_cookie;5356 u16 num_msdus = 0;5357 u8 rxdma_err, rbm;5358 bool is_frag, is_first_msdu;5359 bool drop_mpdu = false;5360 5361 ath11k_hal_rx_sw_mon_ring_buf_paddr_get(ring_entry, sw_mon_entries);5362 5363 sw_cookie = sw_mon_entries->mon_dst_sw_cookie;5364 sw_mon_entries->end_of_ppdu = false;5365 sw_mon_entries->drop_ppdu = false;5366 p_last_buf_addr_info = sw_mon_entries->dst_buf_addr_info;5367 msdu_cnt = sw_mon_entries->msdu_cnt;5368 5369 sw_mon_entries->end_of_ppdu =5370 FIELD_GET(HAL_SW_MON_RING_INFO0_END_OF_PPDU, sw_desc->info0);5371 if (sw_mon_entries->end_of_ppdu)5372 return rx_bufs_used;5373 5374 if (FIELD_GET(HAL_SW_MON_RING_INFO0_RXDMA_PUSH_REASON,5375 sw_desc->info0) ==5376 HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) {5377 rxdma_err =5378 FIELD_GET(HAL_SW_MON_RING_INFO0_RXDMA_ERROR_CODE,5379 sw_desc->info0);5380 if (rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR ||5381 rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR ||5382 rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR) {5383 pmon->rx_mon_stats.dest_mpdu_drop++;5384 drop_mpdu = true;5385 }5386 }5387 5388 is_frag = false;5389 is_first_msdu = true;5390 5391 do {5392 rx_msdu_link_desc =5393 (u8 *)pmon->link_desc_banks[sw_cookie].vaddr +5394 (sw_mon_entries->mon_dst_paddr -5395 pmon->link_desc_banks[sw_cookie].paddr);5396 5397 ath11k_hal_rx_msdu_list_get(ar, rx_msdu_link_desc, &msdu_list,5398 &num_msdus);5399 5400 for (i = 0; i < num_msdus; i++) {5401 buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,5402 msdu_list.sw_cookie[i]);5403 5404 spin_lock_bh(&rx_ring->idr_lock);5405 msdu = idr_find(&rx_ring->bufs_idr, buf_id);5406 if (!msdu) {5407 ath11k_dbg(ar->ab, ATH11K_DBG_DATA,5408 "full mon msdu_pop: invalid buf_id %d\n",5409 buf_id);5410 spin_unlock_bh(&rx_ring->idr_lock);5411 break;5412 }5413 idr_remove(&rx_ring->bufs_idr, buf_id);5414 spin_unlock_bh(&rx_ring->idr_lock);5415 5416 rxcb = ATH11K_SKB_RXCB(msdu);5417 if (!rxcb->unmapped) {5418 dma_unmap_single(ar->ab->dev, rxcb->paddr,5419 msdu->len +5420 skb_tailroom(msdu),5421 DMA_FROM_DEVICE);5422 rxcb->unmapped = 1;5423 }5424 if (drop_mpdu) {5425 ath11k_dbg(ar->ab, ATH11K_DBG_DATA,5426 "full mon: i %d drop msdu %p *ppdu_id %x\n",5427 i, msdu, sw_mon_entries->ppdu_id);5428 dev_kfree_skb_any(msdu);5429 msdu_cnt--;5430 goto next_msdu;5431 }5432 5433 rx_desc = (struct hal_rx_desc *)msdu->data;5434 5435 rx_pkt_offset = sizeof(struct hal_rx_desc);5436 l2_hdr_offset = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, rx_desc);5437 5438 if (is_first_msdu) {5439 if (!ath11k_dp_rxdesc_mpdu_valid(ar->ab, rx_desc)) {5440 drop_mpdu = true;5441 dev_kfree_skb_any(msdu);5442 msdu = NULL;5443 goto next_msdu;5444 }5445 is_first_msdu = false;5446 }5447 5448 ath11k_dp_mon_get_buf_len(&msdu_list.msdu_info[i],5449 &is_frag, &total_len,5450 &frag_len, &msdu_cnt);5451 5452 rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len;5453 5454 ath11k_dp_pkt_set_pktlen(msdu, rx_buf_size);5455 5456 if (!(*head_msdu))5457 *head_msdu = msdu;5458 else if (last)5459 last->next = msdu;5460 5461 last = msdu;5462next_msdu:5463 rx_bufs_used++;5464 }5465 5466 ath11k_dp_rx_mon_next_link_desc_get(rx_msdu_link_desc,5467 &sw_mon_entries->mon_dst_paddr,5468 &sw_mon_entries->mon_dst_sw_cookie,5469 &rbm,5470 &p_buf_addr_info);5471 5472 if (ath11k_dp_rx_monitor_link_desc_return(ar,5473 p_last_buf_addr_info,5474 dp->mac_id))5475 ath11k_dbg(ar->ab, ATH11K_DBG_DATA,5476 "full mon: dp_rx_monitor_link_desc_return failed\n");5477 5478 p_last_buf_addr_info = p_buf_addr_info;5479 5480 } while (sw_mon_entries->mon_dst_paddr && msdu_cnt);5481 5482 if (last)5483 last->next = NULL;5484 5485 *tail_msdu = msdu;5486 5487 return rx_bufs_used;5488}5489 5490static int ath11k_dp_rx_full_mon_prepare_mpdu(struct ath11k_dp *dp,5491 struct dp_full_mon_mpdu *mon_mpdu,5492 struct sk_buff *head,5493 struct sk_buff *tail)5494{5495 mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC);5496 if (!mon_mpdu)5497 return -ENOMEM;5498 5499 list_add_tail(&mon_mpdu->list, &dp->dp_full_mon_mpdu_list);5500 mon_mpdu->head = head;5501 mon_mpdu->tail = tail;5502 5503 return 0;5504}5505 5506static void ath11k_dp_rx_full_mon_drop_ppdu(struct ath11k_dp *dp,5507 struct dp_full_mon_mpdu *mon_mpdu)5508{5509 struct dp_full_mon_mpdu *tmp;5510 struct sk_buff *tmp_msdu, *skb_next;5511 5512 if (list_empty(&dp->dp_full_mon_mpdu_list))5513 return;5514 5515 list_for_each_entry_safe(mon_mpdu, tmp, &dp->dp_full_mon_mpdu_list, list) {5516 list_del(&mon_mpdu->list);5517 5518 tmp_msdu = mon_mpdu->head;5519 while (tmp_msdu) {5520 skb_next = tmp_msdu->next;5521 dev_kfree_skb_any(tmp_msdu);5522 tmp_msdu = skb_next;5523 }5524 5525 kfree(mon_mpdu);5526 }5527}5528 5529static int ath11k_dp_rx_full_mon_deliver_ppdu(struct ath11k *ar,5530 int mac_id,5531 struct ath11k_mon_data *pmon,5532 struct napi_struct *napi)5533{5534 struct ath11k_pdev_mon_stats *rx_mon_stats;5535 struct dp_full_mon_mpdu *tmp;5536 struct dp_full_mon_mpdu *mon_mpdu = pmon->mon_mpdu;5537 struct sk_buff *head_msdu, *tail_msdu;5538 struct ath11k_base *ab = ar->ab;5539 struct ath11k_dp *dp = &ab->dp;5540 int ret;5541 5542 rx_mon_stats = &pmon->rx_mon_stats;5543 5544 list_for_each_entry_safe(mon_mpdu, tmp, &dp->dp_full_mon_mpdu_list, list) {5545 list_del(&mon_mpdu->list);5546 head_msdu = mon_mpdu->head;5547 tail_msdu = mon_mpdu->tail;5548 if (head_msdu && tail_msdu) {5549 ret = ath11k_dp_rx_mon_deliver(ar, mac_id, head_msdu,5550 &pmon->mon_ppdu_info,5551 tail_msdu, napi);5552 rx_mon_stats->dest_mpdu_done++;5553 ath11k_dbg(ar->ab, ATH11K_DBG_DATA, "full mon: deliver ppdu\n");5554 }5555 kfree(mon_mpdu);5556 }5557 5558 return ret;5559}5560 5561static int5562ath11k_dp_rx_process_full_mon_status_ring(struct ath11k_base *ab, int mac_id,5563 struct napi_struct *napi, int budget)5564{5565 struct ath11k *ar = ab->pdevs[mac_id].ar;5566 struct ath11k_pdev_dp *dp = &ar->dp;5567 struct ath11k_mon_data *pmon = &dp->mon_data;5568 struct hal_sw_mon_ring_entries *sw_mon_entries;5569 int quota = 0, work = 0, count;5570 5571 sw_mon_entries = &pmon->sw_mon_entries;5572 5573 while (pmon->hold_mon_dst_ring) {5574 quota = ath11k_dp_rx_process_mon_status(ab, mac_id,5575 napi, 1);5576 if (pmon->buf_state == DP_MON_STATUS_MATCH) {5577 count = sw_mon_entries->status_buf_count;5578 if (count > 1) {5579 quota += ath11k_dp_rx_process_mon_status(ab, mac_id,5580 napi, count);5581 }5582 5583 ath11k_dp_rx_full_mon_deliver_ppdu(ar, dp->mac_id,5584 pmon, napi);5585 pmon->hold_mon_dst_ring = false;5586 } else if (!pmon->mon_status_paddr ||5587 pmon->buf_state == DP_MON_STATUS_LEAD) {5588 sw_mon_entries->drop_ppdu = true;5589 pmon->hold_mon_dst_ring = false;5590 }5591 5592 if (!quota)5593 break;5594 5595 work += quota;5596 }5597 5598 if (sw_mon_entries->drop_ppdu)5599 ath11k_dp_rx_full_mon_drop_ppdu(&ab->dp, pmon->mon_mpdu);5600 5601 return work;5602}5603 5604static int ath11k_dp_full_mon_process_rx(struct ath11k_base *ab, int mac_id,5605 struct napi_struct *napi, int budget)5606{5607 struct ath11k *ar = ab->pdevs[mac_id].ar;5608 struct ath11k_pdev_dp *dp = &ar->dp;5609 struct ath11k_mon_data *pmon = &dp->mon_data;5610 struct hal_sw_mon_ring_entries *sw_mon_entries;5611 struct ath11k_pdev_mon_stats *rx_mon_stats;5612 struct sk_buff *head_msdu, *tail_msdu;5613 void *mon_dst_srng = &ar->ab->hal.srng_list[dp->rxdma_mon_dst_ring.ring_id];5614 void *ring_entry;5615 u32 rx_bufs_used = 0, mpdu_rx_bufs_used;5616 int quota = 0, ret;5617 bool break_dst_ring = false;5618 5619 spin_lock_bh(&pmon->mon_lock);5620 5621 sw_mon_entries = &pmon->sw_mon_entries;5622 rx_mon_stats = &pmon->rx_mon_stats;5623 5624 if (pmon->hold_mon_dst_ring) {5625 spin_unlock_bh(&pmon->mon_lock);5626 goto reap_status_ring;5627 }5628 5629 ath11k_hal_srng_access_begin(ar->ab, mon_dst_srng);5630 while ((ring_entry = ath11k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) {5631 head_msdu = NULL;5632 tail_msdu = NULL;5633 5634 mpdu_rx_bufs_used = ath11k_dp_rx_full_mon_mpdu_pop(ar, ring_entry,5635 &head_msdu,5636 &tail_msdu,5637 sw_mon_entries);5638 rx_bufs_used += mpdu_rx_bufs_used;5639 5640 if (!sw_mon_entries->end_of_ppdu) {5641 if (head_msdu) {5642 ret = ath11k_dp_rx_full_mon_prepare_mpdu(&ab->dp,5643 pmon->mon_mpdu,5644 head_msdu,5645 tail_msdu);5646 if (ret)5647 break_dst_ring = true;5648 }5649 5650 goto next_entry;5651 } else {5652 if (!sw_mon_entries->ppdu_id &&5653 !sw_mon_entries->mon_status_paddr) {5654 break_dst_ring = true;5655 goto next_entry;5656 }5657 }5658 5659 rx_mon_stats->dest_ppdu_done++;5660 pmon->mon_ppdu_status = DP_PPDU_STATUS_START;5661 pmon->buf_state = DP_MON_STATUS_LAG;5662 pmon->mon_status_paddr = sw_mon_entries->mon_status_paddr;5663 pmon->hold_mon_dst_ring = true;5664next_entry:5665 ring_entry = ath11k_hal_srng_dst_get_next_entry(ar->ab,5666 mon_dst_srng);5667 if (break_dst_ring)5668 break;5669 }5670 5671 ath11k_hal_srng_access_end(ar->ab, mon_dst_srng);5672 spin_unlock_bh(&pmon->mon_lock);5673 5674 if (rx_bufs_used) {5675 ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id,5676 &dp->rxdma_mon_buf_ring,5677 rx_bufs_used,5678 HAL_RX_BUF_RBM_SW3_BM);5679 }5680 5681reap_status_ring:5682 quota = ath11k_dp_rx_process_full_mon_status_ring(ab, mac_id,5683 napi, budget);5684 5685 return quota;5686}5687 5688int ath11k_dp_rx_process_mon_rings(struct ath11k_base *ab, int mac_id,5689 struct napi_struct *napi, int budget)5690{5691 struct ath11k *ar = ath11k_ab_to_ar(ab, mac_id);5692 int ret = 0;5693 5694 if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags) &&5695 ab->hw_params.full_monitor_mode)5696 ret = ath11k_dp_full_mon_process_rx(ab, mac_id, napi, budget);5697 else5698 ret = ath11k_dp_rx_process_mon_status(ab, mac_id, napi, budget);5699 5700 return ret;5701}5702 5703static int ath11k_dp_rx_pdev_mon_status_attach(struct ath11k *ar)5704{5705 struct ath11k_pdev_dp *dp = &ar->dp;5706 struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data;5707 5708 skb_queue_head_init(&pmon->rx_status_q);5709 5710 pmon->mon_ppdu_status = DP_PPDU_STATUS_START;5711 5712 memset(&pmon->rx_mon_stats, 0,5713 sizeof(pmon->rx_mon_stats));5714 return 0;5715}5716 5717int ath11k_dp_rx_pdev_mon_attach(struct ath11k *ar)5718{5719 struct ath11k_pdev_dp *dp = &ar->dp;5720 struct ath11k_mon_data *pmon = &dp->mon_data;5721 struct hal_srng *mon_desc_srng = NULL;5722 struct dp_srng *dp_srng;5723 int ret = 0;5724 u32 n_link_desc = 0;5725 5726 ret = ath11k_dp_rx_pdev_mon_status_attach(ar);5727 if (ret) {5728 ath11k_warn(ar->ab, "pdev_mon_status_attach() failed");5729 return ret;5730 }5731 5732 /* if rxdma1_enable is false, no need to setup5733 * rxdma_mon_desc_ring.5734 */5735 if (!ar->ab->hw_params.rxdma1_enable)5736 return 0;5737 5738 dp_srng = &dp->rxdma_mon_desc_ring;5739 n_link_desc = dp_srng->size /5740 ath11k_hal_srng_get_entrysize(ar->ab, HAL_RXDMA_MONITOR_DESC);5741 mon_desc_srng =5742 &ar->ab->hal.srng_list[dp->rxdma_mon_desc_ring.ring_id];5743 5744 ret = ath11k_dp_link_desc_setup(ar->ab, pmon->link_desc_banks,5745 HAL_RXDMA_MONITOR_DESC, mon_desc_srng,5746 n_link_desc);5747 if (ret) {5748 ath11k_warn(ar->ab, "mon_link_desc_pool_setup() failed");5749 return ret;5750 }5751 pmon->mon_last_linkdesc_paddr = 0;5752 pmon->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1;5753 spin_lock_init(&pmon->mon_lock);5754 5755 return 0;5756}5757 5758static int ath11k_dp_mon_link_free(struct ath11k *ar)5759{5760 struct ath11k_pdev_dp *dp = &ar->dp;5761 struct ath11k_mon_data *pmon = &dp->mon_data;5762 5763 ath11k_dp_link_desc_cleanup(ar->ab, pmon->link_desc_banks,5764 HAL_RXDMA_MONITOR_DESC,5765 &dp->rxdma_mon_desc_ring);5766 return 0;5767}5768 5769int ath11k_dp_rx_pdev_mon_detach(struct ath11k *ar)5770{5771 ath11k_dp_mon_link_free(ar);5772 return 0;5773}5774 5775int ath11k_dp_rx_pktlog_start(struct ath11k_base *ab)5776{5777 /* start reap timer */5778 mod_timer(&ab->mon_reap_timer,5779 jiffies + msecs_to_jiffies(ATH11K_MON_TIMER_INTERVAL));5780 5781 return 0;5782}5783 5784int ath11k_dp_rx_pktlog_stop(struct ath11k_base *ab, bool stop_timer)5785{5786 int ret;5787 5788 if (stop_timer)5789 del_timer_sync(&ab->mon_reap_timer);5790 5791 /* reap all the monitor related rings */5792 ret = ath11k_dp_purge_mon_ring(ab);5793 if (ret) {5794 ath11k_warn(ab, "failed to purge dp mon ring: %d\n", ret);5795 return ret;5796 }5797 5798 return 0;5799}5800