]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: Move RX status TLV parsing to Wi-Fi 7 module
authorAlok Singh <quic_aloksing@quicinc.com>
Mon, 10 Nov 2025 10:37:05 +0000 (16:07 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Tue, 11 Nov 2025 15:21:33 +0000 (07:21 -0800)
Split Wi-Fi 7-specific monitor code out of ath12k common code
to improve modularity.

Move following RX status TLV parsing functions to the new file
wifi7/dp_mon.c and rename the helpers with the ath12k_wifi7_ prefix:
- ath12k_dp_mon_rx_parse_status_tlv()
- ath12k_dp_mon_parse_rx_dest_tlv()

Export helper functions required by the Wi-Fi 7 module.

Temporarily include wifi7/hal_rx.h from dp_mon.h to provide
HAL structure definitions; remove this dependency in a later patch.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1

Signed-off-by: Alok Singh <quic_aloksing@quicinc.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20251110103713.3484779-5-quic_aloksing@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/dp_mon.c
drivers/net/wireless/ath/ath12k/dp_mon.h
drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c

index 16361dd77a6ae4b927e6b100d097d535cb00fc72..dc4827771a64c3b5d5837b4b599af0dfb50212bb 100644 (file)
@@ -17,7 +17,7 @@
 #define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \
                u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits)
 
-static void
+void
 ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user,
                                   struct hal_rx_user_status *rx_user_status)
 {
@@ -26,6 +26,7 @@ ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu
        rx_user_status->ul_ofdma_user_v0_word1 =
                __le32_to_cpu(ppdu_end_user->usr_resp_ref_ext);
 }
+EXPORT_SYMBOL(ath12k_dp_mon_rx_handle_ofdma_info);
 
 static void
 ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats,
@@ -40,7 +41,7 @@ ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *st
                              HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_ERR_BYTE_COUNT);
 }
 
-static void
+void
 ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv,
                                       struct hal_rx_mon_ppdu_info *ppdu_info,
                                       struct hal_rx_user_status *rx_user_status)
@@ -78,9 +79,10 @@ ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *
 
        ath12k_dp_mon_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status);
 }
+EXPORT_SYMBOL(ath12k_dp_mon_rx_populate_mu_user_info);
 
-static void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig,
-                                         struct hal_rx_mon_ppdu_info *ppdu_info)
+void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig,
+                                  struct hal_rx_mon_ppdu_info *ppdu_info)
 {
        u32 nsts, info0, info1;
        u8 gi_setting;
@@ -118,9 +120,10 @@ static void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vh
        ppdu_info->vht_flag_values4 =
                u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING);
 }
+EXPORT_SYMBOL(ath12k_dp_mon_parse_vht_sig_a);
 
-static void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig,
-                                      struct hal_rx_mon_ppdu_info *ppdu_info)
+void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig,
+                               struct hal_rx_mon_ppdu_info *ppdu_info)
 {
        u32 info0 = __le32_to_cpu(ht_sig->info0);
        u32 info1 = __le32_to_cpu(ht_sig->info1);
@@ -132,9 +135,10 @@ static void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig,
        ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI);
        ppdu_info->nss = (ppdu_info->mcs >> 3);
 }
+EXPORT_SYMBOL(ath12k_dp_mon_parse_ht_sig);
 
-static void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb,
-                                       struct hal_rx_mon_ppdu_info *ppdu_info)
+void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb,
+                                struct hal_rx_mon_ppdu_info *ppdu_info)
 {
        u32 info0 = __le32_to_cpu(lsigb->info0);
        u8 rate;
@@ -163,9 +167,10 @@ static void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb,
        ppdu_info->rate = rate;
        ppdu_info->cck_flag = 1;
 }
+EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_b);
 
-static void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga,
-                                       struct hal_rx_mon_ppdu_info *ppdu_info)
+void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga,
+                                struct hal_rx_mon_ppdu_info *ppdu_info)
 {
        u32 info0 = __le32_to_cpu(lsiga->info0);
        u8 rate;
@@ -202,8 +207,9 @@ static void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga,
 
        ppdu_info->rate = rate;
 }
+EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_a);
 
-static void
+void
 ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma,
                                    struct hal_rx_mon_ppdu_info *ppdu_info)
 {
@@ -238,8 +244,9 @@ ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *of
        ppdu_info->beamformed = u32_get_bits(info0,
                                             HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF);
 }
+EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b2_ofdma);
 
-static void
+void
 ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu,
                                 struct hal_rx_mon_ppdu_info *ppdu_info)
 {
@@ -264,8 +271,9 @@ ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b
 
        ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS);
 }
+EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b2_mu);
 
-static void
+void
 ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu,
                                 struct hal_rx_mon_ppdu_info *ppdu_info)
 {
@@ -277,8 +285,9 @@ ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b
        ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones);
        ppdu_info->he_RU[0] = ru_tones;
 }
+EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b1_mu);
 
-static void
+void
 ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl,
                              struct hal_rx_mon_ppdu_info *ppdu_info)
 {
@@ -410,9 +419,10 @@ ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_
        ppdu_info->is_stbc = info1 &
                             HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC;
 }
+EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_mu);
 
-static void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a,
-                                         struct hal_rx_mon_ppdu_info *ppdu_info)
+void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a,
+                                  struct hal_rx_mon_ppdu_info *ppdu_info)
 {
        u32 info0, info1, value;
        u32 dcm;
@@ -557,6 +567,7 @@ static void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *
        ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS);
        ppdu_info->dcm = dcm;
 }
+EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_su);
 
 static void
 ath12k_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn,
@@ -731,7 +742,7 @@ ath12k_dp_mon_hal_rx_parse_u_sig_mu(const struct hal_mon_usig_mu *usig_mu,
        usig->mask = cpu_to_le32(mask);
 }
 
-static void
+void
 ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig,
                                     struct hal_rx_mon_ppdu_info *ppdu_info)
 {
@@ -749,8 +760,9 @@ ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig,
        else
                ath12k_dp_mon_hal_rx_parse_u_sig_mu(&usig->non_cmn.mu, ppdu_info);
 }
+EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_u_sig_hdr);
 
-static void
+void
 ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info,
                           u16 tlv_len, const void *tlv_data)
 {
@@ -760,6 +772,7 @@ ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info,
                ppdu_info->tlv_aggr.cur_len += tlv_len;
        }
 }
+EXPORT_SYMBOL(ath12k_dp_mon_hal_aggr_tlv);
 
 static inline bool
 ath12k_dp_mon_hal_rx_is_frame_type_ndp(const struct hal_rx_u_sig_info *usig_info)
@@ -1117,7 +1130,7 @@ ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(const void *tlv,
                                                       ppdu_info);
 }
 
-static void
+void
 ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info,
                                const void *tlv_data)
 {
@@ -1130,6 +1143,7 @@ ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info,
        else if (ath12k_dp_mon_hal_rx_is_ofdma(&ppdu_info->u_sig_info))
                ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info);
 }
+EXPORT_SYMBOL(ath12k_dp_mon_parse_eht_sig_hdr);
 
 static inline enum ath12k_eht_ru_size
 hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size)
@@ -1215,7 +1229,7 @@ hal_rx_ul_ofdma_ru_size_to_width(enum ath12k_eht_ru_size ru_size)
        }
 }
 
-static void
+void
 ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info,
                                     u16 user_id,
                                     struct hal_rx_mon_ppdu_info *ppdu_info)
@@ -1416,6 +1430,7 @@ ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_
                mon_rx_user_status->ofdma_info_valid = 1;
        }
 }
+EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_user_info);
 
 static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap)
 {
@@ -1441,7 +1456,7 @@ static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap)
                *errmap |= HAL_RX_MPDU_ERR_MPDU_LEN;
 }
 
-static void
+void
 ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon,
                                    const struct hal_rx_msdu_end *msdu_end)
 {
@@ -1450,280 +1465,7 @@ ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon,
        pmon->decap_format = le32_get_bits(msdu_end->info1,
                                           RX_MSDU_END_INFO11_DECAP_FORMAT);
 }
-
-enum hal_rx_mon_status
-ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev,
-                                 struct ath12k_mon_data *pmon,
-                                 const struct hal_tlv_64_hdr *tlv)
-{
-       struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
-       const void *tlv_data = tlv->value;
-       u32 info[7], userid;
-       u16 tlv_tag, tlv_len;
-
-       tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG);
-       tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN);
-       userid = le64_get_bits(tlv->tl, HAL_TLV_64_USR_ID);
-
-       if (ppdu_info->tlv_aggr.in_progress && ppdu_info->tlv_aggr.tlv_tag != tlv_tag) {
-               ath12k_dp_mon_parse_eht_sig_hdr(ppdu_info, ppdu_info->tlv_aggr.buf);
-
-               ppdu_info->tlv_aggr.in_progress = false;
-               ppdu_info->tlv_aggr.cur_len = 0;
-       }
-
-       switch (tlv_tag) {
-       case HAL_RX_PPDU_START: {
-               const struct hal_rx_ppdu_start *ppdu_start = tlv_data;
-
-               u64 ppdu_ts = ath12k_le32hilo_to_u64(ppdu_start->ppdu_start_ts_63_32,
-                                                    ppdu_start->ppdu_start_ts_31_0);
-
-               info[0] = __le32_to_cpu(ppdu_start->info0);
-
-               ppdu_info->ppdu_id = u32_get_bits(info[0],
-                                                 HAL_RX_PPDU_START_INFO0_PPDU_ID);
-
-               info[1] = __le32_to_cpu(ppdu_start->info1);
-               ppdu_info->chan_num = u32_get_bits(info[1],
-                                                  HAL_RX_PPDU_START_INFO1_CHAN_NUM);
-               ppdu_info->freq = u32_get_bits(info[1],
-                                              HAL_RX_PPDU_START_INFO1_CHAN_FREQ);
-               ppdu_info->ppdu_ts = ppdu_ts;
-
-               if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) {
-                       ppdu_info->last_ppdu_id = ppdu_info->ppdu_id;
-                       ppdu_info->num_users = 0;
-                       memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0,
-                              HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *
-                              sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0]));
-               }
-               break;
-       }
-       case HAL_RX_PPDU_END_USER_STATS: {
-               const struct hal_rx_ppdu_end_user_stats *eu_stats = tlv_data;
-               u32 tid_bitmap;
-
-               info[0] = __le32_to_cpu(eu_stats->info0);
-               info[1] = __le32_to_cpu(eu_stats->info1);
-               info[2] = __le32_to_cpu(eu_stats->info2);
-               info[4] = __le32_to_cpu(eu_stats->info4);
-               info[5] = __le32_to_cpu(eu_stats->info5);
-               info[6] = __le32_to_cpu(eu_stats->info6);
-
-               ppdu_info->ast_index =
-                       u32_get_bits(info[2], HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX);
-               ppdu_info->fc_valid =
-                       u32_get_bits(info[1], HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID);
-               tid_bitmap = u32_get_bits(info[6],
-                                         HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP);
-               ppdu_info->tid = ffs(tid_bitmap) - 1;
-               ppdu_info->tcp_msdu_count =
-                       u32_get_bits(info[4],
-                                    HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT);
-               ppdu_info->udp_msdu_count =
-                       u32_get_bits(info[4],
-                                    HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT);
-               ppdu_info->other_msdu_count =
-                       u32_get_bits(info[5],
-                                    HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT);
-               ppdu_info->tcp_ack_msdu_count =
-                       u32_get_bits(info[5],
-                                    HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT);
-               ppdu_info->preamble_type =
-                       u32_get_bits(info[1],
-                                    HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE);
-               ppdu_info->num_mpdu_fcs_ok =
-                       u32_get_bits(info[1],
-                                    HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK);
-               ppdu_info->num_mpdu_fcs_err =
-                       u32_get_bits(info[0],
-                                    HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR);
-               ppdu_info->peer_id =
-                       u32_get_bits(info[0], HAL_RX_PPDU_END_USER_STATS_INFO0_PEER_ID);
-
-               switch (ppdu_info->preamble_type) {
-               case HAL_RX_PREAMBLE_11N:
-                       ppdu_info->ht_flags = 1;
-                       break;
-               case HAL_RX_PREAMBLE_11AC:
-                       ppdu_info->vht_flags = 1;
-                       break;
-               case HAL_RX_PREAMBLE_11AX:
-                       ppdu_info->he_flags = 1;
-                       break;
-               case HAL_RX_PREAMBLE_11BE:
-                       ppdu_info->is_eht = true;
-                       break;
-               default:
-                       break;
-               }
-
-               if (userid < HAL_MAX_UL_MU_USERS) {
-                       struct hal_rx_user_status *rxuser_stats =
-                               &ppdu_info->userstats[userid];
-
-                       if (ppdu_info->num_mpdu_fcs_ok > 1 ||
-                           ppdu_info->num_mpdu_fcs_err > 1)
-                               ppdu_info->userstats[userid].ampdu_present = true;
-
-                       ppdu_info->num_users += 1;
-
-                       ath12k_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats);
-                       ath12k_dp_mon_rx_populate_mu_user_info(eu_stats, ppdu_info,
-                                                              rxuser_stats);
-               }
-               ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]);
-               ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]);
-               break;
-       }
-       case HAL_RX_PPDU_END_USER_STATS_EXT: {
-               const struct hal_rx_ppdu_end_user_stats_ext *eu_stats = tlv_data;
-
-               ppdu_info->mpdu_fcs_ok_bitmap[2] = __le32_to_cpu(eu_stats->info1);
-               ppdu_info->mpdu_fcs_ok_bitmap[3] = __le32_to_cpu(eu_stats->info2);
-               ppdu_info->mpdu_fcs_ok_bitmap[4] = __le32_to_cpu(eu_stats->info3);
-               ppdu_info->mpdu_fcs_ok_bitmap[5] = __le32_to_cpu(eu_stats->info4);
-               ppdu_info->mpdu_fcs_ok_bitmap[6] = __le32_to_cpu(eu_stats->info5);
-               ppdu_info->mpdu_fcs_ok_bitmap[7] = __le32_to_cpu(eu_stats->info6);
-               break;
-       }
-       case HAL_PHYRX_HT_SIG:
-               ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info);
-               break;
-
-       case HAL_PHYRX_L_SIG_B:
-               ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info);
-               break;
-
-       case HAL_PHYRX_L_SIG_A:
-               ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info);
-               break;
-
-       case HAL_PHYRX_VHT_SIG_A:
-               ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info);
-               break;
-
-       case HAL_PHYRX_HE_SIG_A_SU:
-               ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info);
-               break;
-
-       case HAL_PHYRX_HE_SIG_A_MU_DL:
-               ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info);
-               break;
-
-       case HAL_PHYRX_HE_SIG_B1_MU:
-               ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info);
-               break;
-
-       case HAL_PHYRX_HE_SIG_B2_MU:
-               ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info);
-               break;
-
-       case HAL_PHYRX_HE_SIG_B2_OFDMA:
-               ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info);
-               break;
-
-       case HAL_PHYRX_RSSI_LEGACY: {
-               const struct hal_rx_phyrx_rssi_legacy_info *rssi = tlv_data;
-
-               info[0] = __le32_to_cpu(rssi->info0);
-               info[1] = __le32_to_cpu(rssi->info1);
-
-               /* TODO: Please note that the combined rssi will not be accurate
-                * in MU case. Rssi in MU needs to be retrieved from
-                * PHYRX_OTHER_RECEIVE_INFO TLV.
-                */
-               ppdu_info->rssi_comb =
-                       u32_get_bits(info[1],
-                                    HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB);
-
-               ppdu_info->bw = u32_get_bits(info[0],
-                                            HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RX_BW);
-               break;
-       }
-       case HAL_PHYRX_OTHER_RECEIVE_INFO: {
-               const struct hal_phyrx_common_user_info *cmn_usr_info = tlv_data;
-
-               ppdu_info->gi = le32_get_bits(cmn_usr_info->info0,
-                                             HAL_RX_PHY_CMN_USER_INFO0_GI);
-               break;
-       }
-       case HAL_RX_PPDU_START_USER_INFO:
-               ath12k_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info);
-               break;
-
-       case HAL_RXPCU_PPDU_END_INFO: {
-               const struct hal_rx_ppdu_end_duration *ppdu_rx_duration = tlv_data;
-
-               info[0] = __le32_to_cpu(ppdu_rx_duration->info0);
-               ppdu_info->rx_duration =
-                       u32_get_bits(info[0], HAL_RX_PPDU_END_DURATION);
-               ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]);
-               ppdu_info->tsft = (ppdu_info->tsft << 32) |
-                                  __le32_to_cpu(ppdu_rx_duration->rsvd0[0]);
-               break;
-       }
-       case HAL_RX_MPDU_START: {
-               const struct hal_rx_mpdu_start *mpdu_start = tlv_data;
-               u16 peer_id;
-
-               info[1] = __le32_to_cpu(mpdu_start->info1);
-               peer_id = u32_get_bits(info[1], HAL_RX_MPDU_START_INFO1_PEERID);
-               if (peer_id)
-                       ppdu_info->peer_id = peer_id;
-
-               ppdu_info->mpdu_len += u32_get_bits(info[1],
-                                                   HAL_RX_MPDU_START_INFO2_MPDU_LEN);
-               if (userid < HAL_MAX_UL_MU_USERS) {
-                       info[0] = __le32_to_cpu(mpdu_start->info0);
-                       ppdu_info->userid = userid;
-                       ppdu_info->userstats[userid].ampdu_id =
-                               u32_get_bits(info[0], HAL_RX_MPDU_START_INFO0_PPDU_ID);
-               }
-
-               return HAL_RX_MON_STATUS_MPDU_START;
-       }
-       case HAL_RX_MSDU_START:
-               /* TODO: add msdu start parsing logic */
-               break;
-       case HAL_MON_BUF_ADDR:
-               return HAL_RX_MON_STATUS_BUF_ADDR;
-       case HAL_RX_MSDU_END:
-               ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data);
-               return HAL_RX_MON_STATUS_MSDU_END;
-       case HAL_RX_MPDU_END:
-               return HAL_RX_MON_STATUS_MPDU_END;
-       case HAL_PHYRX_GENERIC_U_SIG:
-               ath12k_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info);
-               break;
-       case HAL_PHYRX_GENERIC_EHT_SIG:
-               /* Handle the case where aggregation is in progress
-                * or the current TLV is one of the TLVs which should be
-                * aggregated
-                */
-               if (!ppdu_info->tlv_aggr.in_progress) {
-                       ppdu_info->tlv_aggr.in_progress = true;
-                       ppdu_info->tlv_aggr.tlv_tag = tlv_tag;
-                       ppdu_info->tlv_aggr.cur_len = 0;
-               }
-
-               ppdu_info->is_eht = true;
-
-               ath12k_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data);
-               break;
-       case HAL_DUMMY:
-               return HAL_RX_MON_STATUS_BUF_DONE;
-       case HAL_RX_PPDU_END_STATUS_DONE:
-       case 0:
-               return HAL_RX_MON_STATUS_PPDU_DONE;
-       default:
-               break;
-       }
-
-       return HAL_RX_MON_STATUS_PPDU_NOT_DONE;
-}
-EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_status_tlv);
+EXPORT_SYMBOL(ath12k_dp_mon_parse_status_msdu_end);
 
 static void
 ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info,
@@ -2413,7 +2155,7 @@ ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info,
 }
 EXPORT_SYMBOL(ath12k_dp_mon_get_buf_len);
 
-static int
+int
 ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev,
                               struct ath12k_mon_data *pmon,
                               const struct dp_mon_packet_info *packet_info)
@@ -2458,45 +2200,7 @@ dest_replenish:
 
        return 0;
 }
-
-int
-ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev,
-                               struct ath12k_mon_data *pmon,
-                               enum hal_rx_mon_status hal_status,
-                               const void *tlv_data)
-{
-       switch (hal_status) {
-       case HAL_RX_MON_STATUS_MPDU_START:
-               if (WARN_ON_ONCE(pmon->mon_mpdu))
-                       break;
-
-               pmon->mon_mpdu = kzalloc(sizeof(*pmon->mon_mpdu), GFP_ATOMIC);
-               if (!pmon->mon_mpdu)
-                       return -ENOMEM;
-               break;
-       case HAL_RX_MON_STATUS_BUF_ADDR:
-               return ath12k_dp_mon_parse_status_buf(dp_pdev, pmon, tlv_data);
-       case HAL_RX_MON_STATUS_MPDU_END:
-               /* If no MSDU then free empty MPDU */
-               if (pmon->mon_mpdu->tail) {
-                       pmon->mon_mpdu->tail->next = NULL;
-                       list_add_tail(&pmon->mon_mpdu->list, &pmon->dp_rx_mon_mpdu_list);
-               } else {
-                       kfree(pmon->mon_mpdu);
-               }
-               pmon->mon_mpdu = NULL;
-               break;
-       case HAL_RX_MON_STATUS_MSDU_END:
-               pmon->mon_mpdu->decap_format = pmon->decap_format;
-               pmon->mon_mpdu->err_bitmap = pmon->err_bitmap;
-               break;
-       default:
-               break;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(ath12k_dp_mon_parse_rx_dest_tlv);
+EXPORT_SYMBOL(ath12k_dp_mon_parse_status_buf);
 
 int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab,
                                struct dp_rxdma_mon_ring *buf_ring,
index 425bec6f0f3ca375680817cde50b7a0a73643d6c..bfea7d4041cb9dcbf8a31469ee0550ab1768da3c 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "core.h"
 #include "wifi7/hal_desc.h"
+#include "wifi7/hal_rx.h"
 
 #define ATH12K_MON_RX_DOT11_OFFSET     5
 #define ATH12K_MON_RX_PKT_OFFSET       8
@@ -106,15 +107,6 @@ int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev,
                             struct dp_mon_mpdu *mon_mpdu,
                             struct hal_rx_mon_ppdu_info *ppduinfo,
                             struct napi_struct *napi);
-int
-ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev,
-                               struct ath12k_mon_data *pmon,
-                               enum hal_rx_mon_status hal_status,
-                               const void *tlv_data);
-enum hal_rx_mon_status
-ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev,
-                                 struct ath12k_mon_data *pmon,
-                                 const struct hal_tlv_64_hdr *tlv);
 struct sk_buff
 *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab,
                                   struct dp_rxdma_mon_ring *rx_ring,
@@ -128,4 +120,53 @@ void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab,
                                      dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm,
                                      struct ath12k_buffer_addr **pp_buf_addr_info);
 u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id);
+int
+ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev,
+                              struct ath12k_mon_data *pmon,
+                              const struct dp_mon_packet_info *packet_info);
+void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig,
+                               struct hal_rx_mon_ppdu_info *ppdu_info);
+void
+ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info,
+                               const void *tlv_data);
+void
+ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user,
+                                  struct hal_rx_user_status *rx_user_status);
+void
+ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv,
+                                      struct hal_rx_mon_ppdu_info *ppdu_info,
+                                      struct hal_rx_user_status *rx_user_status);
+void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb,
+                                struct hal_rx_mon_ppdu_info *ppdu_info);
+void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga,
+                                struct hal_rx_mon_ppdu_info *ppdu_info);
+void
+ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma,
+                                   struct hal_rx_mon_ppdu_info *ppdu_info);
+void
+ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu,
+                                struct hal_rx_mon_ppdu_info *ppdu_info);
+void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig,
+                                  struct hal_rx_mon_ppdu_info *ppdu_info);
+void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a,
+                                  struct hal_rx_mon_ppdu_info *ppdu_info);
+void
+ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu,
+                                struct hal_rx_mon_ppdu_info *ppdu_info);
+void
+ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl,
+                             struct hal_rx_mon_ppdu_info *ppdu_info);
+void
+ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info,
+                                    u16 user_id,
+                                    struct hal_rx_mon_ppdu_info *ppdu_info);
+void
+ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon,
+                                   const struct hal_rx_msdu_end *msdu_end);
+void
+ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig,
+                                    struct hal_rx_mon_ppdu_info *ppdu_info);
+void
+ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info,
+                          u16 tlv_len, const void *tlv_data);
 #endif
index dae3f262cc5071d8b55860e70960d184ab3cc902..076fb75a101f199a964baf5961d7fa4e6fdb3ddb 100644 (file)
@@ -10,6 +10,7 @@
 #include "../debug.h"
 #include "hal_qcn9274.h"
 #include "dp_rx.h"
+#include "../dp_tx.h"
 #include "../peer.h"
 
 static void
@@ -19,6 +20,317 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info)
        ppdu_info->peer_id = HAL_INVALID_PEERID;
 }
 
+static enum hal_rx_mon_status
+ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev,
+                                       struct ath12k_mon_data *pmon,
+                                       const struct hal_tlv_64_hdr *tlv)
+{
+       struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
+       const void *tlv_data = tlv->value;
+       u32 info[7], userid;
+       u16 tlv_tag, tlv_len;
+
+       tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG);
+       tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN);
+       userid = le64_get_bits(tlv->tl, HAL_TLV_64_USR_ID);
+
+       if (ppdu_info->tlv_aggr.in_progress && ppdu_info->tlv_aggr.tlv_tag != tlv_tag) {
+               ath12k_dp_mon_parse_eht_sig_hdr(ppdu_info, ppdu_info->tlv_aggr.buf);
+
+               ppdu_info->tlv_aggr.in_progress = false;
+               ppdu_info->tlv_aggr.cur_len = 0;
+       }
+
+       switch (tlv_tag) {
+       case HAL_RX_PPDU_START: {
+               const struct hal_rx_ppdu_start *ppdu_start = tlv_data;
+
+               u64 ppdu_ts = ath12k_le32hilo_to_u64(ppdu_start->ppdu_start_ts_63_32,
+                                                    ppdu_start->ppdu_start_ts_31_0);
+
+               info[0] = __le32_to_cpu(ppdu_start->info0);
+
+               ppdu_info->ppdu_id = u32_get_bits(info[0],
+                                                 HAL_RX_PPDU_START_INFO0_PPDU_ID);
+
+               info[1] = __le32_to_cpu(ppdu_start->info1);
+               ppdu_info->chan_num = u32_get_bits(info[1],
+                                                  HAL_RX_PPDU_START_INFO1_CHAN_NUM);
+               ppdu_info->freq = u32_get_bits(info[1],
+                                              HAL_RX_PPDU_START_INFO1_CHAN_FREQ);
+               ppdu_info->ppdu_ts = ppdu_ts;
+
+               if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) {
+                       ppdu_info->last_ppdu_id = ppdu_info->ppdu_id;
+                       ppdu_info->num_users = 0;
+                       memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0,
+                              HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *
+                              sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0]));
+               }
+               break;
+       }
+       case HAL_RX_PPDU_END_USER_STATS: {
+               const struct hal_rx_ppdu_end_user_stats *eu_stats = tlv_data;
+               u32 tid_bitmap;
+
+               info[0] = __le32_to_cpu(eu_stats->info0);
+               info[1] = __le32_to_cpu(eu_stats->info1);
+               info[2] = __le32_to_cpu(eu_stats->info2);
+               info[4] = __le32_to_cpu(eu_stats->info4);
+               info[5] = __le32_to_cpu(eu_stats->info5);
+               info[6] = __le32_to_cpu(eu_stats->info6);
+
+               ppdu_info->ast_index =
+                       u32_get_bits(info[2], HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX);
+               ppdu_info->fc_valid =
+                       u32_get_bits(info[1], HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID);
+               tid_bitmap = u32_get_bits(info[6],
+                                         HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP);
+               ppdu_info->tid = ffs(tid_bitmap) - 1;
+               ppdu_info->tcp_msdu_count =
+                       u32_get_bits(info[4],
+                                    HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT);
+               ppdu_info->udp_msdu_count =
+                       u32_get_bits(info[4],
+                                    HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT);
+               ppdu_info->other_msdu_count =
+                       u32_get_bits(info[5],
+                                    HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT);
+               ppdu_info->tcp_ack_msdu_count =
+                       u32_get_bits(info[5],
+                                    HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT);
+               ppdu_info->preamble_type =
+                       u32_get_bits(info[1],
+                                    HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE);
+               ppdu_info->num_mpdu_fcs_ok =
+                       u32_get_bits(info[1],
+                                    HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK);
+               ppdu_info->num_mpdu_fcs_err =
+                       u32_get_bits(info[0],
+                                    HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR);
+               ppdu_info->peer_id =
+                       u32_get_bits(info[0], HAL_RX_PPDU_END_USER_STATS_INFO0_PEER_ID);
+
+               switch (ppdu_info->preamble_type) {
+               case HAL_RX_PREAMBLE_11N:
+                       ppdu_info->ht_flags = 1;
+                       break;
+               case HAL_RX_PREAMBLE_11AC:
+                       ppdu_info->vht_flags = 1;
+                       break;
+               case HAL_RX_PREAMBLE_11AX:
+                       ppdu_info->he_flags = 1;
+                       break;
+               case HAL_RX_PREAMBLE_11BE:
+                       ppdu_info->is_eht = true;
+                       break;
+               default:
+                       break;
+               }
+
+               if (userid < HAL_MAX_UL_MU_USERS) {
+                       struct hal_rx_user_status *rxuser_stats =
+                               &ppdu_info->userstats[userid];
+
+                       if (ppdu_info->num_mpdu_fcs_ok > 1 ||
+                           ppdu_info->num_mpdu_fcs_err > 1)
+                               ppdu_info->userstats[userid].ampdu_present = true;
+
+                       ppdu_info->num_users += 1;
+
+                       ath12k_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats);
+                       ath12k_dp_mon_rx_populate_mu_user_info(eu_stats, ppdu_info,
+                                                              rxuser_stats);
+               }
+               ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]);
+               ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]);
+               break;
+       }
+       case HAL_RX_PPDU_END_USER_STATS_EXT: {
+               const struct hal_rx_ppdu_end_user_stats_ext *eu_stats = tlv_data;
+
+               ppdu_info->mpdu_fcs_ok_bitmap[2] = __le32_to_cpu(eu_stats->info1);
+               ppdu_info->mpdu_fcs_ok_bitmap[3] = __le32_to_cpu(eu_stats->info2);
+               ppdu_info->mpdu_fcs_ok_bitmap[4] = __le32_to_cpu(eu_stats->info3);
+               ppdu_info->mpdu_fcs_ok_bitmap[5] = __le32_to_cpu(eu_stats->info4);
+               ppdu_info->mpdu_fcs_ok_bitmap[6] = __le32_to_cpu(eu_stats->info5);
+               ppdu_info->mpdu_fcs_ok_bitmap[7] = __le32_to_cpu(eu_stats->info6);
+               break;
+       }
+       case HAL_PHYRX_HT_SIG:
+               ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info);
+               break;
+
+       case HAL_PHYRX_L_SIG_B:
+               ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info);
+               break;
+
+       case HAL_PHYRX_L_SIG_A:
+               ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info);
+               break;
+
+       case HAL_PHYRX_VHT_SIG_A:
+               ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info);
+               break;
+
+       case HAL_PHYRX_HE_SIG_A_SU:
+               ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info);
+               break;
+
+       case HAL_PHYRX_HE_SIG_A_MU_DL:
+               ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info);
+               break;
+
+       case HAL_PHYRX_HE_SIG_B1_MU:
+               ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info);
+               break;
+
+       case HAL_PHYRX_HE_SIG_B2_MU:
+               ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info);
+               break;
+
+       case HAL_PHYRX_HE_SIG_B2_OFDMA:
+               ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info);
+               break;
+
+       case HAL_PHYRX_RSSI_LEGACY: {
+               const struct hal_rx_phyrx_rssi_legacy_info *rssi = tlv_data;
+
+               info[0] = __le32_to_cpu(rssi->info0);
+               info[1] = __le32_to_cpu(rssi->info1);
+
+               /* TODO: Please note that the combined rssi will not be accurate
+                * in MU case. Rssi in MU needs to be retrieved from
+                * PHYRX_OTHER_RECEIVE_INFO TLV.
+                */
+               ppdu_info->rssi_comb =
+                       u32_get_bits(info[1],
+                                    HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB);
+
+               ppdu_info->bw = u32_get_bits(info[0],
+                                            HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RX_BW);
+               break;
+       }
+       case HAL_PHYRX_OTHER_RECEIVE_INFO: {
+               const struct hal_phyrx_common_user_info *cmn_usr_info = tlv_data;
+
+               ppdu_info->gi = le32_get_bits(cmn_usr_info->info0,
+                                             HAL_RX_PHY_CMN_USER_INFO0_GI);
+               break;
+       }
+       case HAL_RX_PPDU_START_USER_INFO:
+               ath12k_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info);
+               break;
+
+       case HAL_RXPCU_PPDU_END_INFO: {
+               const struct hal_rx_ppdu_end_duration *ppdu_rx_duration = tlv_data;
+
+               info[0] = __le32_to_cpu(ppdu_rx_duration->info0);
+               ppdu_info->rx_duration =
+                       u32_get_bits(info[0], HAL_RX_PPDU_END_DURATION);
+               ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]);
+               ppdu_info->tsft = (ppdu_info->tsft << 32) |
+                                  __le32_to_cpu(ppdu_rx_duration->rsvd0[0]);
+               break;
+       }
+       case HAL_RX_MPDU_START: {
+               const struct hal_rx_mpdu_start *mpdu_start = tlv_data;
+               u16 peer_id;
+
+               info[1] = __le32_to_cpu(mpdu_start->info1);
+               peer_id = u32_get_bits(info[1], HAL_RX_MPDU_START_INFO1_PEERID);
+               if (peer_id)
+                       ppdu_info->peer_id = peer_id;
+
+               ppdu_info->mpdu_len += u32_get_bits(info[1],
+                                                   HAL_RX_MPDU_START_INFO2_MPDU_LEN);
+               if (userid < HAL_MAX_UL_MU_USERS) {
+                       info[0] = __le32_to_cpu(mpdu_start->info0);
+                       ppdu_info->userid = userid;
+                       ppdu_info->userstats[userid].ampdu_id =
+                               u32_get_bits(info[0], HAL_RX_MPDU_START_INFO0_PPDU_ID);
+               }
+
+               return HAL_RX_MON_STATUS_MPDU_START;
+       }
+       case HAL_RX_MSDU_START:
+               /* TODO: add msdu start parsing logic */
+               break;
+       case HAL_MON_BUF_ADDR:
+               return HAL_RX_MON_STATUS_BUF_ADDR;
+       case HAL_RX_MSDU_END:
+               ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data);
+               return HAL_RX_MON_STATUS_MSDU_END;
+       case HAL_RX_MPDU_END:
+               return HAL_RX_MON_STATUS_MPDU_END;
+       case HAL_PHYRX_GENERIC_U_SIG:
+               ath12k_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info);
+               break;
+       case HAL_PHYRX_GENERIC_EHT_SIG:
+               /* Handle the case where aggregation is in progress
+                * or the current TLV is one of the TLVs which should be
+                * aggregated
+                */
+               if (!ppdu_info->tlv_aggr.in_progress) {
+                       ppdu_info->tlv_aggr.in_progress = true;
+                       ppdu_info->tlv_aggr.tlv_tag = tlv_tag;
+                       ppdu_info->tlv_aggr.cur_len = 0;
+               }
+
+               ppdu_info->is_eht = true;
+
+               ath12k_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data);
+               break;
+       case HAL_DUMMY:
+               return HAL_RX_MON_STATUS_BUF_DONE;
+       case HAL_RX_PPDU_END_STATUS_DONE:
+       case 0:
+               return HAL_RX_MON_STATUS_PPDU_DONE;
+       default:
+               break;
+       }
+
+       return HAL_RX_MON_STATUS_PPDU_NOT_DONE;
+}
+
+static int
+ath12k_wifi7_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev,
+                                     struct ath12k_mon_data *pmon,
+                                     enum hal_rx_mon_status hal_status,
+                                     const void *tlv_data)
+{
+       switch (hal_status) {
+       case HAL_RX_MON_STATUS_MPDU_START:
+               if (WARN_ON_ONCE(pmon->mon_mpdu))
+                       break;
+
+               pmon->mon_mpdu = kzalloc(sizeof(*pmon->mon_mpdu), GFP_ATOMIC);
+               if (!pmon->mon_mpdu)
+                       return -ENOMEM;
+               break;
+       case HAL_RX_MON_STATUS_BUF_ADDR:
+               return ath12k_dp_mon_parse_status_buf(dp_pdev, pmon, tlv_data);
+       case HAL_RX_MON_STATUS_MPDU_END:
+               /* If no MSDU then free empty MPDU */
+               if (pmon->mon_mpdu->tail) {
+                       pmon->mon_mpdu->tail->next = NULL;
+                       list_add_tail(&pmon->mon_mpdu->list, &pmon->dp_rx_mon_mpdu_list);
+               } else {
+                       kfree(pmon->mon_mpdu);
+               }
+               pmon->mon_mpdu = NULL;
+               break;
+       case HAL_RX_MON_STATUS_MSDU_END:
+               pmon->mon_mpdu->decap_format = pmon->decap_format;
+               pmon->mon_mpdu->err_bitmap = pmon->err_bitmap;
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
 static u32
 ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id,
                                void *ring_entry, struct sk_buff **head_msdu,
@@ -389,11 +701,12 @@ ath12k_wifi7_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev,
                else
                        tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN);
 
-               hal_status = ath12k_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, tlv);
+               hal_status = ath12k_wifi7_dp_mon_rx_parse_status_tlv(dp_pdev, pmon,
+                                                                    tlv);
 
                if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable &&
-                   ath12k_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status,
-                                                   tlv->value))
+                   ath12k_wifi7_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status,
+                                                         tlv->value))
                        return HAL_RX_MON_STATUS_PPDU_DONE;
 
                ptr += sizeof(*tlv) + tlv_len;