]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: ath12k: Handle monitor drop TLVs scenario
authorP Praneesh <quic_ppranees@quicinc.com>
Mon, 23 Dec 2024 06:01:31 +0000 (11:31 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Sun, 26 Jan 2025 18:41:30 +0000 (10:41 -0800)
During monitor destination ring back-pressure, hardware failed to send
HAL_RX_PPDU_END_STATUS_DONE TLV. But driver uses this TLV as a delimiter
to complete one PPDU worth of data parsing. This causes driver to overwrite
the existing PPDU information with the new PPDU information.

Fix it by recording the end reason which is provided under each buffer's
descriptor in skb->cb and uses it while parsing TLV tags to mark the PPDU
end delimiter.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
Link: https://patch.msgid.link/20241223060132.3506372-14-quic_ppranees@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/core.h
drivers/net/wireless/ath/ath12k/dp_mon.c

index 3d20a6b3b473a15beed1ef1fde1f80bfadde6513..28db100cfac06e5b33c78f09e9ef1b6447150fec 100644 (file)
@@ -142,6 +142,7 @@ struct ath12k_skb_rxcb {
        u8 is_frag;
        u8 tid;
        u16 peer_id;
+       bool is_end_of_ppdu;
 };
 
 enum ath12k_hw_rev {
index 23b1a41c6fd2b5446285fbf19f773f9115c2ba7f..4e9a60181c06704d36e17088f005d61dab1a0ea8 100644 (file)
@@ -1139,6 +1139,7 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon,
                            struct sk_buff *skb)
 {
        struct hal_tlv_64_hdr *tlv;
+       struct ath12k_skb_rxcb *rxcb;
        enum hal_rx_mon_status hal_status;
        u16 tlv_tag, tlv_len;
        u8 *ptr = skb->data;
@@ -1170,6 +1171,10 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon,
                 (hal_status == HAL_RX_MON_STATUS_MPDU_END) ||
                 (hal_status == HAL_RX_MON_STATUS_MSDU_END));
 
+       rxcb = ATH12K_SKB_RXCB(skb);
+       if (rxcb->is_end_of_ppdu)
+               hal_status = HAL_RX_MON_STATUS_PPDU_DONE;
+
        return hal_status;
 }
 
@@ -2345,8 +2350,10 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget,
                 * HAL_MON_END_OF_PPDU to ensure that one PPDU worth of data is always
                 * reaped. This helps to efficiently utilize the NAPI budget.
                 */
-               if (end_reason == HAL_MON_END_OF_PPDU)
+               if (end_reason == HAL_MON_END_OF_PPDU) {
                        *budget -= 1;
+                       rxcb->is_end_of_ppdu = true;
+               }
 
                end_offset = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_OFFSET);
                if (likely(end_offset <= DP_RX_BUFFER_SIZE)) {