xref: /freebsd/sys/contrib/dev/athk/ath12k/dp_mon.c (revision 5c1def83)
15c1def83SBjoern A. Zeeb // SPDX-License-Identifier: BSD-3-Clause-Clear
25c1def83SBjoern A. Zeeb /*
35c1def83SBjoern A. Zeeb  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
45c1def83SBjoern A. Zeeb  * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
55c1def83SBjoern A. Zeeb  */
65c1def83SBjoern A. Zeeb 
75c1def83SBjoern A. Zeeb #include "dp_mon.h"
85c1def83SBjoern A. Zeeb #include "debug.h"
95c1def83SBjoern A. Zeeb #include "dp_rx.h"
105c1def83SBjoern A. Zeeb #include "dp_tx.h"
115c1def83SBjoern A. Zeeb #include "peer.h"
125c1def83SBjoern A. Zeeb 
ath12k_dp_mon_rx_handle_ofdma_info(void * rx_tlv,struct hal_rx_user_status * rx_user_status)135c1def83SBjoern A. Zeeb static void ath12k_dp_mon_rx_handle_ofdma_info(void *rx_tlv,
145c1def83SBjoern A. Zeeb 					       struct hal_rx_user_status *rx_user_status)
155c1def83SBjoern A. Zeeb {
165c1def83SBjoern A. Zeeb 	struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
175c1def83SBjoern A. Zeeb 				(struct hal_rx_ppdu_end_user_stats *)rx_tlv;
185c1def83SBjoern A. Zeeb 
195c1def83SBjoern A. Zeeb 	rx_user_status->ul_ofdma_user_v0_word0 =
205c1def83SBjoern A. Zeeb 		__le32_to_cpu(ppdu_end_user->usr_resp_ref);
215c1def83SBjoern A. Zeeb 	rx_user_status->ul_ofdma_user_v0_word1 =
225c1def83SBjoern A. Zeeb 		__le32_to_cpu(ppdu_end_user->usr_resp_ref_ext);
235c1def83SBjoern A. Zeeb }
245c1def83SBjoern A. Zeeb 
255c1def83SBjoern A. Zeeb static void
ath12k_dp_mon_rx_populate_byte_count(void * rx_tlv,void * ppduinfo,struct hal_rx_user_status * rx_user_status)265c1def83SBjoern A. Zeeb ath12k_dp_mon_rx_populate_byte_count(void *rx_tlv, void *ppduinfo,
275c1def83SBjoern A. Zeeb 				     struct hal_rx_user_status *rx_user_status)
285c1def83SBjoern A. Zeeb {
295c1def83SBjoern A. Zeeb 	struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
305c1def83SBjoern A. Zeeb 		(struct hal_rx_ppdu_end_user_stats *)rx_tlv;
315c1def83SBjoern A. Zeeb 	u32 mpdu_ok_byte_count = __le32_to_cpu(ppdu_end_user->mpdu_ok_cnt);
325c1def83SBjoern A. Zeeb 	u32 mpdu_err_byte_count = __le32_to_cpu(ppdu_end_user->mpdu_err_cnt);
335c1def83SBjoern A. Zeeb 
345c1def83SBjoern A. Zeeb 	rx_user_status->mpdu_ok_byte_count =
355c1def83SBjoern A. Zeeb 		u32_get_bits(mpdu_ok_byte_count,
365c1def83SBjoern A. Zeeb 			     HAL_RX_PPDU_END_USER_STATS_MPDU_DELIM_OK_BYTE_COUNT);
375c1def83SBjoern A. Zeeb 	rx_user_status->mpdu_err_byte_count =
385c1def83SBjoern A. Zeeb 		u32_get_bits(mpdu_err_byte_count,
395c1def83SBjoern A. Zeeb 			     HAL_RX_PPDU_END_USER_STATS_MPDU_DELIM_ERR_BYTE_COUNT);
405c1def83SBjoern A. Zeeb }
415c1def83SBjoern A. Zeeb 
425c1def83SBjoern A. Zeeb static void
ath12k_dp_mon_rx_populate_mu_user_info(void * rx_tlv,struct hal_rx_mon_ppdu_info * ppdu_info,struct hal_rx_user_status * rx_user_status)435c1def83SBjoern A. Zeeb ath12k_dp_mon_rx_populate_mu_user_info(void *rx_tlv,
445c1def83SBjoern A. Zeeb 				       struct hal_rx_mon_ppdu_info *ppdu_info,
455c1def83SBjoern A. Zeeb 				       struct hal_rx_user_status *rx_user_status)
465c1def83SBjoern A. Zeeb {
475c1def83SBjoern A. Zeeb 	rx_user_status->ast_index = ppdu_info->ast_index;
485c1def83SBjoern A. Zeeb 	rx_user_status->tid = ppdu_info->tid;
495c1def83SBjoern A. Zeeb 	rx_user_status->tcp_ack_msdu_count =
505c1def83SBjoern A. Zeeb 		ppdu_info->tcp_ack_msdu_count;
515c1def83SBjoern A. Zeeb 	rx_user_status->tcp_msdu_count =
525c1def83SBjoern A. Zeeb 		ppdu_info->tcp_msdu_count;
535c1def83SBjoern A. Zeeb 	rx_user_status->udp_msdu_count =
545c1def83SBjoern A. Zeeb 		ppdu_info->udp_msdu_count;
555c1def83SBjoern A. Zeeb 	rx_user_status->other_msdu_count =
565c1def83SBjoern A. Zeeb 		ppdu_info->other_msdu_count;
575c1def83SBjoern A. Zeeb 	rx_user_status->frame_control = ppdu_info->frame_control;
585c1def83SBjoern A. Zeeb 	rx_user_status->frame_control_info_valid =
595c1def83SBjoern A. Zeeb 		ppdu_info->frame_control_info_valid;
605c1def83SBjoern A. Zeeb 	rx_user_status->data_sequence_control_info_valid =
615c1def83SBjoern A. Zeeb 		ppdu_info->data_sequence_control_info_valid;
625c1def83SBjoern A. Zeeb 	rx_user_status->first_data_seq_ctrl =
635c1def83SBjoern A. Zeeb 		ppdu_info->first_data_seq_ctrl;
645c1def83SBjoern A. Zeeb 	rx_user_status->preamble_type = ppdu_info->preamble_type;
655c1def83SBjoern A. Zeeb 	rx_user_status->ht_flags = ppdu_info->ht_flags;
665c1def83SBjoern A. Zeeb 	rx_user_status->vht_flags = ppdu_info->vht_flags;
675c1def83SBjoern A. Zeeb 	rx_user_status->he_flags = ppdu_info->he_flags;
685c1def83SBjoern A. Zeeb 	rx_user_status->rs_flags = ppdu_info->rs_flags;
695c1def83SBjoern A. Zeeb 
705c1def83SBjoern A. Zeeb 	rx_user_status->mpdu_cnt_fcs_ok =
715c1def83SBjoern A. Zeeb 		ppdu_info->num_mpdu_fcs_ok;
725c1def83SBjoern A. Zeeb 	rx_user_status->mpdu_cnt_fcs_err =
735c1def83SBjoern A. Zeeb 		ppdu_info->num_mpdu_fcs_err;
745c1def83SBjoern A. Zeeb 	memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0],
755c1def83SBjoern A. Zeeb 	       HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *
765c1def83SBjoern A. Zeeb 	       sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0]));
775c1def83SBjoern A. Zeeb 
785c1def83SBjoern A. Zeeb 	ath12k_dp_mon_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status);
795c1def83SBjoern A. Zeeb }
805c1def83SBjoern A. Zeeb 
ath12k_dp_mon_parse_vht_sig_a(u8 * tlv_data,struct hal_rx_mon_ppdu_info * ppdu_info)815c1def83SBjoern A. Zeeb static void ath12k_dp_mon_parse_vht_sig_a(u8 *tlv_data,
825c1def83SBjoern A. Zeeb 					  struct hal_rx_mon_ppdu_info *ppdu_info)
835c1def83SBjoern A. Zeeb {
845c1def83SBjoern A. Zeeb 	struct hal_rx_vht_sig_a_info *vht_sig =
855c1def83SBjoern A. Zeeb 			(struct hal_rx_vht_sig_a_info *)tlv_data;
865c1def83SBjoern A. Zeeb 	u32 nsts, group_id, info0, info1;
875c1def83SBjoern A. Zeeb 	u8 gi_setting;
885c1def83SBjoern A. Zeeb 
895c1def83SBjoern A. Zeeb 	info0 = __le32_to_cpu(vht_sig->info0);
905c1def83SBjoern A. Zeeb 	info1 = __le32_to_cpu(vht_sig->info1);
915c1def83SBjoern A. Zeeb 
925c1def83SBjoern A. Zeeb 	ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING);
935c1def83SBjoern A. Zeeb 	ppdu_info->mcs = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_MCS);
945c1def83SBjoern A. Zeeb 	gi_setting = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING);
955c1def83SBjoern A. Zeeb 	switch (gi_setting) {
965c1def83SBjoern A. Zeeb 	case HAL_RX_VHT_SIG_A_NORMAL_GI:
975c1def83SBjoern A. Zeeb 		ppdu_info->gi = HAL_RX_GI_0_8_US;
985c1def83SBjoern A. Zeeb 		break;
995c1def83SBjoern A. Zeeb 	case HAL_RX_VHT_SIG_A_SHORT_GI:
1005c1def83SBjoern A. Zeeb 	case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY:
1015c1def83SBjoern A. Zeeb 		ppdu_info->gi = HAL_RX_GI_0_4_US;
1025c1def83SBjoern A. Zeeb 		break;
1035c1def83SBjoern A. Zeeb 	}
1045c1def83SBjoern A. Zeeb 
1055c1def83SBjoern A. Zeeb 	ppdu_info->is_stbc = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_STBC);
1065c1def83SBjoern A. Zeeb 	nsts = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS);
1075c1def83SBjoern A. Zeeb 	if (ppdu_info->is_stbc && nsts > 0)
1085c1def83SBjoern A. Zeeb 		nsts = ((nsts + 1) >> 1) - 1;
1095c1def83SBjoern A. Zeeb 
1105c1def83SBjoern A. Zeeb 	ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK);
1115c1def83SBjoern A. Zeeb 	ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW);
1125c1def83SBjoern A. Zeeb 	ppdu_info->beamformed = u32_get_bits(info1,
1135c1def83SBjoern A. Zeeb 					     HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED);
1145c1def83SBjoern A. Zeeb 	group_id = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID);
1155c1def83SBjoern A. Zeeb 	if (group_id == 0 || group_id == 63)
1165c1def83SBjoern A. Zeeb 		ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
1175c1def83SBjoern A. Zeeb 	else
1185c1def83SBjoern A. Zeeb 		ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;
1195c1def83SBjoern A. Zeeb 	ppdu_info->vht_flag_values5 = group_id;
1205c1def83SBjoern A. Zeeb 	ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) |
1215c1def83SBjoern A. Zeeb 					    ppdu_info->nss);
1225c1def83SBjoern A. Zeeb 	ppdu_info->vht_flag_values2 = ppdu_info->bw;
1235c1def83SBjoern A. Zeeb 	ppdu_info->vht_flag_values4 =
1245c1def83SBjoern A. Zeeb 		u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING);
1255c1def83SBjoern A. Zeeb }
1265c1def83SBjoern A. Zeeb 
ath12k_dp_mon_parse_ht_sig(u8 * tlv_data,struct hal_rx_mon_ppdu_info * ppdu_info)1275c1def83SBjoern A. Zeeb static void ath12k_dp_mon_parse_ht_sig(u8 *tlv_data,
1285c1def83SBjoern A. Zeeb 				       struct hal_rx_mon_ppdu_info *ppdu_info)
1295c1def83SBjoern A. Zeeb {
1305c1def83SBjoern A. Zeeb 	struct hal_rx_ht_sig_info *ht_sig =
1315c1def83SBjoern A. Zeeb 			(struct hal_rx_ht_sig_info *)tlv_data;
1325c1def83SBjoern A. Zeeb 	u32 info0 = __le32_to_cpu(ht_sig->info0);
1335c1def83SBjoern A. Zeeb 	u32 info1 = __le32_to_cpu(ht_sig->info1);
1345c1def83SBjoern A. Zeeb 
1355c1def83SBjoern A. Zeeb 	ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_MCS);
1365c1def83SBjoern A. Zeeb 	ppdu_info->bw = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_BW);
1375c1def83SBjoern A. Zeeb 	ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC);
1385c1def83SBjoern A. Zeeb 	ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING);
1395c1def83SBjoern A. Zeeb 	ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI);
1405c1def83SBjoern A. Zeeb 	ppdu_info->nss = (ppdu_info->mcs >> 3);
1415c1def83SBjoern A. Zeeb 	ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
1425c1def83SBjoern A. Zeeb }
1435c1def83SBjoern A. Zeeb 
ath12k_dp_mon_parse_l_sig_b(u8 * tlv_data,struct hal_rx_mon_ppdu_info * ppdu_info)1445c1def83SBjoern A. Zeeb static void ath12k_dp_mon_parse_l_sig_b(u8 *tlv_data,
1455c1def83SBjoern A. Zeeb 					struct hal_rx_mon_ppdu_info *ppdu_info)
1465c1def83SBjoern A. Zeeb {
1475c1def83SBjoern A. Zeeb 	struct hal_rx_lsig_b_info *lsigb =
1485c1def83SBjoern A. Zeeb 			(struct hal_rx_lsig_b_info *)tlv_data;
1495c1def83SBjoern A. Zeeb 	u32 info0 = __le32_to_cpu(lsigb->info0);
1505c1def83SBjoern A. Zeeb 	u8 rate;
1515c1def83SBjoern A. Zeeb 
1525c1def83SBjoern A. Zeeb 	rate = u32_get_bits(info0, HAL_RX_LSIG_B_INFO_INFO0_RATE);
1535c1def83SBjoern A. Zeeb 	switch (rate) {
1545c1def83SBjoern A. Zeeb 	case 1:
1555c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_1_MBPS;
1565c1def83SBjoern A. Zeeb 		break;
1575c1def83SBjoern A. Zeeb 	case 2:
1585c1def83SBjoern A. Zeeb 	case 5:
1595c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_2_MBPS;
1605c1def83SBjoern A. Zeeb 		break;
1615c1def83SBjoern A. Zeeb 	case 3:
1625c1def83SBjoern A. Zeeb 	case 6:
1635c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_5_5_MBPS;
1645c1def83SBjoern A. Zeeb 		break;
1655c1def83SBjoern A. Zeeb 	case 4:
1665c1def83SBjoern A. Zeeb 	case 7:
1675c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_11_MBPS;
1685c1def83SBjoern A. Zeeb 		break;
1695c1def83SBjoern A. Zeeb 	default:
1705c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_INVALID;
1715c1def83SBjoern A. Zeeb 	}
1725c1def83SBjoern A. Zeeb 
1735c1def83SBjoern A. Zeeb 	ppdu_info->rate = rate;
1745c1def83SBjoern A. Zeeb 	ppdu_info->cck_flag = 1;
1755c1def83SBjoern A. Zeeb 	ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
1765c1def83SBjoern A. Zeeb }
1775c1def83SBjoern A. Zeeb 
ath12k_dp_mon_parse_l_sig_a(u8 * tlv_data,struct hal_rx_mon_ppdu_info * ppdu_info)1785c1def83SBjoern A. Zeeb static void ath12k_dp_mon_parse_l_sig_a(u8 *tlv_data,
1795c1def83SBjoern A. Zeeb 					struct hal_rx_mon_ppdu_info *ppdu_info)
1805c1def83SBjoern A. Zeeb {
1815c1def83SBjoern A. Zeeb 	struct hal_rx_lsig_a_info *lsiga =
1825c1def83SBjoern A. Zeeb 			(struct hal_rx_lsig_a_info *)tlv_data;
1835c1def83SBjoern A. Zeeb 	u32 info0 = __le32_to_cpu(lsiga->info0);
1845c1def83SBjoern A. Zeeb 	u8 rate;
1855c1def83SBjoern A. Zeeb 
1865c1def83SBjoern A. Zeeb 	rate = u32_get_bits(info0, HAL_RX_LSIG_A_INFO_INFO0_RATE);
1875c1def83SBjoern A. Zeeb 	switch (rate) {
1885c1def83SBjoern A. Zeeb 	case 8:
1895c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_48_MBPS;
1905c1def83SBjoern A. Zeeb 		break;
1915c1def83SBjoern A. Zeeb 	case 9:
1925c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_24_MBPS;
1935c1def83SBjoern A. Zeeb 		break;
1945c1def83SBjoern A. Zeeb 	case 10:
1955c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_12_MBPS;
1965c1def83SBjoern A. Zeeb 		break;
1975c1def83SBjoern A. Zeeb 	case 11:
1985c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_6_MBPS;
1995c1def83SBjoern A. Zeeb 		break;
2005c1def83SBjoern A. Zeeb 	case 12:
2015c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_54_MBPS;
2025c1def83SBjoern A. Zeeb 		break;
2035c1def83SBjoern A. Zeeb 	case 13:
2045c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_36_MBPS;
2055c1def83SBjoern A. Zeeb 		break;
2065c1def83SBjoern A. Zeeb 	case 14:
2075c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_18_MBPS;
2085c1def83SBjoern A. Zeeb 		break;
2095c1def83SBjoern A. Zeeb 	case 15:
2105c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_9_MBPS;
2115c1def83SBjoern A. Zeeb 		break;
2125c1def83SBjoern A. Zeeb 	default:
2135c1def83SBjoern A. Zeeb 		rate = HAL_RX_LEGACY_RATE_INVALID;
2145c1def83SBjoern A. Zeeb 	}
2155c1def83SBjoern A. Zeeb 
2165c1def83SBjoern A. Zeeb 	ppdu_info->rate = rate;
2175c1def83SBjoern A. Zeeb 	ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
2185c1def83SBjoern A. Zeeb }
2195c1def83SBjoern A. Zeeb 
ath12k_dp_mon_parse_he_sig_b2_ofdma(u8 * tlv_data,struct hal_rx_mon_ppdu_info * ppdu_info)2205c1def83SBjoern A. Zeeb static void ath12k_dp_mon_parse_he_sig_b2_ofdma(u8 *tlv_data,
2215c1def83SBjoern A. Zeeb 						struct hal_rx_mon_ppdu_info *ppdu_info)
2225c1def83SBjoern A. Zeeb {
2235c1def83SBjoern A. Zeeb 	struct hal_rx_he_sig_b2_ofdma_info *he_sig_b2_ofdma =
2245c1def83SBjoern A. Zeeb 			(struct hal_rx_he_sig_b2_ofdma_info *)tlv_data;
2255c1def83SBjoern A. Zeeb 	u32 info0, value;
2265c1def83SBjoern A. Zeeb 
2275c1def83SBjoern A. Zeeb 	info0 = __le32_to_cpu(he_sig_b2_ofdma->info0);
2285c1def83SBjoern A. Zeeb 
2295c1def83SBjoern A. Zeeb 	ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_DCM_KNOWN | HE_CODING_KNOWN;
2305c1def83SBjoern A. Zeeb 
2315c1def83SBjoern A. Zeeb 	/* HE-data2 */
2325c1def83SBjoern A. Zeeb 	ppdu_info->he_data2 |= HE_TXBF_KNOWN;
2335c1def83SBjoern A. Zeeb 
2345c1def83SBjoern A. Zeeb 	ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS);
2355c1def83SBjoern A. Zeeb 	value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT;
2365c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
2375c1def83SBjoern A. Zeeb 
2385c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM);
2395c1def83SBjoern A. Zeeb 	value = value << HE_DCM_SHIFT;
2405c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
2415c1def83SBjoern A. Zeeb 
2425c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING);
2435c1def83SBjoern A. Zeeb 	ppdu_info->ldpc = value;
2445c1def83SBjoern A. Zeeb 	value = value << HE_CODING_SHIFT;
2455c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
2465c1def83SBjoern A. Zeeb 
2475c1def83SBjoern A. Zeeb 	/* HE-data4 */
2485c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID);
2495c1def83SBjoern A. Zeeb 	value = value << HE_STA_ID_SHIFT;
2505c1def83SBjoern A. Zeeb 	ppdu_info->he_data4 |= value;
2515c1def83SBjoern A. Zeeb 
2525c1def83SBjoern A. Zeeb 	ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS);
2535c1def83SBjoern A. Zeeb 	ppdu_info->beamformed = u32_get_bits(info0,
2545c1def83SBjoern A. Zeeb 					     HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF);
2555c1def83SBjoern A. Zeeb 	ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA;
2565c1def83SBjoern A. Zeeb }
2575c1def83SBjoern A. Zeeb 
ath12k_dp_mon_parse_he_sig_b2_mu(u8 * tlv_data,struct hal_rx_mon_ppdu_info * ppdu_info)2585c1def83SBjoern A. Zeeb static void ath12k_dp_mon_parse_he_sig_b2_mu(u8 *tlv_data,
2595c1def83SBjoern A. Zeeb 					     struct hal_rx_mon_ppdu_info *ppdu_info)
2605c1def83SBjoern A. Zeeb {
2615c1def83SBjoern A. Zeeb 	struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu =
2625c1def83SBjoern A. Zeeb 			(struct hal_rx_he_sig_b2_mu_info *)tlv_data;
2635c1def83SBjoern A. Zeeb 	u32 info0, value;
2645c1def83SBjoern A. Zeeb 
2655c1def83SBjoern A. Zeeb 	info0 = __le32_to_cpu(he_sig_b2_mu->info0);
2665c1def83SBjoern A. Zeeb 
2675c1def83SBjoern A. Zeeb 	ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_CODING_KNOWN;
2685c1def83SBjoern A. Zeeb 
2695c1def83SBjoern A. Zeeb 	ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS);
2705c1def83SBjoern A. Zeeb 	value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT;
2715c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
2725c1def83SBjoern A. Zeeb 
2735c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING);
2745c1def83SBjoern A. Zeeb 	ppdu_info->ldpc = value;
2755c1def83SBjoern A. Zeeb 	value = value << HE_CODING_SHIFT;
2765c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
2775c1def83SBjoern A. Zeeb 
2785c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID);
2795c1def83SBjoern A. Zeeb 	value = value << HE_STA_ID_SHIFT;
2805c1def83SBjoern A. Zeeb 	ppdu_info->he_data4 |= value;
2815c1def83SBjoern A. Zeeb 
2825c1def83SBjoern A. Zeeb 	ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS);
2835c1def83SBjoern A. Zeeb }
2845c1def83SBjoern A. Zeeb 
ath12k_dp_mon_parse_he_sig_b1_mu(u8 * tlv_data,struct hal_rx_mon_ppdu_info * ppdu_info)2855c1def83SBjoern A. Zeeb static void ath12k_dp_mon_parse_he_sig_b1_mu(u8 *tlv_data,
2865c1def83SBjoern A. Zeeb 					     struct hal_rx_mon_ppdu_info *ppdu_info)
2875c1def83SBjoern A. Zeeb {
2885c1def83SBjoern A. Zeeb 	struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu =
2895c1def83SBjoern A. Zeeb 			(struct hal_rx_he_sig_b1_mu_info *)tlv_data;
2905c1def83SBjoern A. Zeeb 	u32 info0 = __le32_to_cpu(he_sig_b1_mu->info0);
2915c1def83SBjoern A. Zeeb 	u16 ru_tones;
2925c1def83SBjoern A. Zeeb 
2935c1def83SBjoern A. Zeeb 	ru_tones = u32_get_bits(info0,
2945c1def83SBjoern A. Zeeb 				HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION);
2955c1def83SBjoern A. Zeeb 	ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones);
2965c1def83SBjoern A. Zeeb 	ppdu_info->he_RU[0] = ru_tones;
2975c1def83SBjoern A. Zeeb 	ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;
2985c1def83SBjoern A. Zeeb }
2995c1def83SBjoern A. Zeeb 
ath12k_dp_mon_parse_he_sig_mu(u8 * tlv_data,struct hal_rx_mon_ppdu_info * ppdu_info)3005c1def83SBjoern A. Zeeb static void ath12k_dp_mon_parse_he_sig_mu(u8 *tlv_data,
3015c1def83SBjoern A. Zeeb 					  struct hal_rx_mon_ppdu_info *ppdu_info)
3025c1def83SBjoern A. Zeeb {
3035c1def83SBjoern A. Zeeb 	struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl =
3045c1def83SBjoern A. Zeeb 			(struct hal_rx_he_sig_a_mu_dl_info *)tlv_data;
3055c1def83SBjoern A. Zeeb 	u32 info0, info1, value;
3065c1def83SBjoern A. Zeeb 	u16 he_gi = 0, he_ltf = 0;
3075c1def83SBjoern A. Zeeb 
3085c1def83SBjoern A. Zeeb 	info0 = __le32_to_cpu(he_sig_a_mu_dl->info0);
3095c1def83SBjoern A. Zeeb 	info1 = __le32_to_cpu(he_sig_a_mu_dl->info1);
3105c1def83SBjoern A. Zeeb 
3115c1def83SBjoern A. Zeeb 	ppdu_info->he_mu_flags = 1;
3125c1def83SBjoern A. Zeeb 
3135c1def83SBjoern A. Zeeb 	ppdu_info->he_data1 = HE_MU_FORMAT_TYPE;
3145c1def83SBjoern A. Zeeb 	ppdu_info->he_data1 |=
3155c1def83SBjoern A. Zeeb 			HE_BSS_COLOR_KNOWN |
3165c1def83SBjoern A. Zeeb 			HE_DL_UL_KNOWN |
3175c1def83SBjoern A. Zeeb 			HE_LDPC_EXTRA_SYMBOL_KNOWN |
3185c1def83SBjoern A. Zeeb 			HE_STBC_KNOWN |
3195c1def83SBjoern A. Zeeb 			HE_DATA_BW_RU_KNOWN |
3205c1def83SBjoern A. Zeeb 			HE_DOPPLER_KNOWN;
3215c1def83SBjoern A. Zeeb 
3225c1def83SBjoern A. Zeeb 	ppdu_info->he_data2 =
3235c1def83SBjoern A. Zeeb 			HE_GI_KNOWN |
3245c1def83SBjoern A. Zeeb 			HE_LTF_SYMBOLS_KNOWN |
3255c1def83SBjoern A. Zeeb 			HE_PRE_FEC_PADDING_KNOWN |
3265c1def83SBjoern A. Zeeb 			HE_PE_DISAMBIGUITY_KNOWN |
3275c1def83SBjoern A. Zeeb 			HE_TXOP_KNOWN |
3285c1def83SBjoern A. Zeeb 			HE_MIDABLE_PERIODICITY_KNOWN;
3295c1def83SBjoern A. Zeeb 
3305c1def83SBjoern A. Zeeb 	/* data3 */
3315c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_BSS_COLOR);
3325c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_UL_FLAG);
3335c1def83SBjoern A. Zeeb 	value = value << HE_DL_UL_SHIFT;
3345c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
3355c1def83SBjoern A. Zeeb 
3365c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_LDPC_EXTRA);
3375c1def83SBjoern A. Zeeb 	value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT;
3385c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
3395c1def83SBjoern A. Zeeb 
3405c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC);
3415c1def83SBjoern A. Zeeb 	value = value << HE_STBC_SHIFT;
3425c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
3435c1def83SBjoern A. Zeeb 
3445c1def83SBjoern A. Zeeb 	/* data4 */
3455c1def83SBjoern A. Zeeb 	ppdu_info->he_data4 = u32_get_bits(info0,
3465c1def83SBjoern A. Zeeb 					   HAL_RX_HE_SIG_A_MU_DL_INFO0_SPATIAL_REUSE);
3475c1def83SBjoern A. Zeeb 	ppdu_info->he_data4 = value;
3485c1def83SBjoern A. Zeeb 
3495c1def83SBjoern A. Zeeb 	/* data5 */
3505c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW);
3515c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 = value;
3525c1def83SBjoern A. Zeeb 	ppdu_info->bw = value;
3535c1def83SBjoern A. Zeeb 
3545c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_CP_LTF_SIZE);
3555c1def83SBjoern A. Zeeb 	switch (value) {
3565c1def83SBjoern A. Zeeb 	case 0:
3575c1def83SBjoern A. Zeeb 		he_gi = HE_GI_0_8;
3585c1def83SBjoern A. Zeeb 		he_ltf = HE_LTF_4_X;
3595c1def83SBjoern A. Zeeb 		break;
3605c1def83SBjoern A. Zeeb 	case 1:
3615c1def83SBjoern A. Zeeb 		he_gi = HE_GI_0_8;
3625c1def83SBjoern A. Zeeb 		he_ltf = HE_LTF_2_X;
3635c1def83SBjoern A. Zeeb 		break;
3645c1def83SBjoern A. Zeeb 	case 2:
3655c1def83SBjoern A. Zeeb 		he_gi = HE_GI_1_6;
3665c1def83SBjoern A. Zeeb 		he_ltf = HE_LTF_2_X;
3675c1def83SBjoern A. Zeeb 		break;
3685c1def83SBjoern A. Zeeb 	case 3:
3695c1def83SBjoern A. Zeeb 		he_gi = HE_GI_3_2;
3705c1def83SBjoern A. Zeeb 		he_ltf = HE_LTF_4_X;
3715c1def83SBjoern A. Zeeb 		break;
3725c1def83SBjoern A. Zeeb 	}
3735c1def83SBjoern A. Zeeb 
3745c1def83SBjoern A. Zeeb 	ppdu_info->gi = he_gi;
3755c1def83SBjoern A. Zeeb 	value = he_gi << HE_GI_SHIFT;
3765c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 |= value;
3775c1def83SBjoern A. Zeeb 
3785c1def83SBjoern A. Zeeb 	value = he_ltf << HE_LTF_SIZE_SHIFT;
3795c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 |= value;
3805c1def83SBjoern A. Zeeb 
3815c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_NUM_LTF_SYMB);
3825c1def83SBjoern A. Zeeb 	value = (value << HE_LTF_SYM_SHIFT);
3835c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 |= value;
3845c1def83SBjoern A. Zeeb 
3855c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_FACTOR);
3865c1def83SBjoern A. Zeeb 	value = value << HE_PRE_FEC_PAD_SHIFT;
3875c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 |= value;
3885c1def83SBjoern A. Zeeb 
3895c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_PE_DISAM);
3905c1def83SBjoern A. Zeeb 	value = value << HE_PE_DISAMBIGUITY_SHIFT;
3915c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 |= value;
3925c1def83SBjoern A. Zeeb 
3935c1def83SBjoern A. Zeeb 	/*data6*/
3945c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DOPPLER_INDICATION);
3955c1def83SBjoern A. Zeeb 	value = value << HE_DOPPLER_SHIFT;
3965c1def83SBjoern A. Zeeb 	ppdu_info->he_data6 |= value;
3975c1def83SBjoern A. Zeeb 
3985c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_TXOP_DURATION);
3995c1def83SBjoern A. Zeeb 	value = value << HE_TXOP_SHIFT;
4005c1def83SBjoern A. Zeeb 	ppdu_info->he_data6 |= value;
4015c1def83SBjoern A. Zeeb 
4025c1def83SBjoern A. Zeeb 	/* HE-MU Flags */
4035c1def83SBjoern A. Zeeb 	/* HE-MU-flags1 */
4045c1def83SBjoern A. Zeeb 	ppdu_info->he_flags1 =
4055c1def83SBjoern A. Zeeb 		HE_SIG_B_MCS_KNOWN |
4065c1def83SBjoern A. Zeeb 		HE_SIG_B_DCM_KNOWN |
4075c1def83SBjoern A. Zeeb 		HE_SIG_B_COMPRESSION_FLAG_1_KNOWN |
4085c1def83SBjoern A. Zeeb 		HE_SIG_B_SYM_NUM_KNOWN |
4095c1def83SBjoern A. Zeeb 		HE_RU_0_KNOWN;
4105c1def83SBjoern A. Zeeb 
4115c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_MCS_OF_SIGB);
4125c1def83SBjoern A. Zeeb 	ppdu_info->he_flags1 |= value;
4135c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DCM_OF_SIGB);
4145c1def83SBjoern A. Zeeb 	value = value << HE_DCM_FLAG_1_SHIFT;
4155c1def83SBjoern A. Zeeb 	ppdu_info->he_flags1 |= value;
4165c1def83SBjoern A. Zeeb 
4175c1def83SBjoern A. Zeeb 	/* HE-MU-flags2 */
4185c1def83SBjoern A. Zeeb 	ppdu_info->he_flags2 = HE_BW_KNOWN;
4195c1def83SBjoern A. Zeeb 
4205c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW);
4215c1def83SBjoern A. Zeeb 	ppdu_info->he_flags2 |= value;
4225c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_COMP_MODE_SIGB);
4235c1def83SBjoern A. Zeeb 	value = value << HE_SIG_B_COMPRESSION_FLAG_2_SHIFT;
4245c1def83SBjoern A. Zeeb 	ppdu_info->he_flags2 |= value;
4255c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_NUM_SIGB_SYMB);
4265c1def83SBjoern A. Zeeb 	value = value - 1;
4275c1def83SBjoern A. Zeeb 	value = value << HE_NUM_SIG_B_SYMBOLS_SHIFT;
4285c1def83SBjoern A. Zeeb 	ppdu_info->he_flags2 |= value;
4295c1def83SBjoern A. Zeeb 
4305c1def83SBjoern A. Zeeb 	ppdu_info->is_stbc = info1 &
4315c1def83SBjoern A. Zeeb 			     HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC;
4325c1def83SBjoern A. Zeeb 	ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;
4335c1def83SBjoern A. Zeeb }
4345c1def83SBjoern A. Zeeb 
ath12k_dp_mon_parse_he_sig_su(u8 * tlv_data,struct hal_rx_mon_ppdu_info * ppdu_info)4355c1def83SBjoern A. Zeeb static void ath12k_dp_mon_parse_he_sig_su(u8 *tlv_data,
4365c1def83SBjoern A. Zeeb 					  struct hal_rx_mon_ppdu_info *ppdu_info)
4375c1def83SBjoern A. Zeeb {
4385c1def83SBjoern A. Zeeb 	struct hal_rx_he_sig_a_su_info *he_sig_a =
4395c1def83SBjoern A. Zeeb 			(struct hal_rx_he_sig_a_su_info *)tlv_data;
4405c1def83SBjoern A. Zeeb 	u32 info0, info1, value;
4415c1def83SBjoern A. Zeeb 	u32 dcm;
4425c1def83SBjoern A. Zeeb 	u8 he_dcm = 0, he_stbc = 0;
4435c1def83SBjoern A. Zeeb 	u16 he_gi = 0, he_ltf = 0;
4445c1def83SBjoern A. Zeeb 
4455c1def83SBjoern A. Zeeb 	ppdu_info->he_flags = 1;
4465c1def83SBjoern A. Zeeb 
4475c1def83SBjoern A. Zeeb 	info0 = __le32_to_cpu(he_sig_a->info0);
4485c1def83SBjoern A. Zeeb 	info1 = __le32_to_cpu(he_sig_a->info1);
4495c1def83SBjoern A. Zeeb 
4505c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND);
4515c1def83SBjoern A. Zeeb 	if (value == 0)
4525c1def83SBjoern A. Zeeb 		ppdu_info->he_data1 = HE_TRIG_FORMAT_TYPE;
4535c1def83SBjoern A. Zeeb 	else
4545c1def83SBjoern A. Zeeb 		ppdu_info->he_data1 = HE_SU_FORMAT_TYPE;
4555c1def83SBjoern A. Zeeb 
4565c1def83SBjoern A. Zeeb 	ppdu_info->he_data1 |=
4575c1def83SBjoern A. Zeeb 			HE_BSS_COLOR_KNOWN |
4585c1def83SBjoern A. Zeeb 			HE_BEAM_CHANGE_KNOWN |
4595c1def83SBjoern A. Zeeb 			HE_DL_UL_KNOWN |
4605c1def83SBjoern A. Zeeb 			HE_MCS_KNOWN |
4615c1def83SBjoern A. Zeeb 			HE_DCM_KNOWN |
4625c1def83SBjoern A. Zeeb 			HE_CODING_KNOWN |
4635c1def83SBjoern A. Zeeb 			HE_LDPC_EXTRA_SYMBOL_KNOWN |
4645c1def83SBjoern A. Zeeb 			HE_STBC_KNOWN |
4655c1def83SBjoern A. Zeeb 			HE_DATA_BW_RU_KNOWN |
4665c1def83SBjoern A. Zeeb 			HE_DOPPLER_KNOWN;
4675c1def83SBjoern A. Zeeb 
4685c1def83SBjoern A. Zeeb 	ppdu_info->he_data2 |=
4695c1def83SBjoern A. Zeeb 			HE_GI_KNOWN |
4705c1def83SBjoern A. Zeeb 			HE_TXBF_KNOWN |
4715c1def83SBjoern A. Zeeb 			HE_PE_DISAMBIGUITY_KNOWN |
4725c1def83SBjoern A. Zeeb 			HE_TXOP_KNOWN |
4735c1def83SBjoern A. Zeeb 			HE_LTF_SYMBOLS_KNOWN |
4745c1def83SBjoern A. Zeeb 			HE_PRE_FEC_PADDING_KNOWN |
4755c1def83SBjoern A. Zeeb 			HE_MIDABLE_PERIODICITY_KNOWN;
4765c1def83SBjoern A. Zeeb 
4775c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 = u32_get_bits(info0,
4785c1def83SBjoern A. Zeeb 					   HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR);
4795c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE);
4805c1def83SBjoern A. Zeeb 	value = value << HE_BEAM_CHANGE_SHIFT;
4815c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
4825c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG);
4835c1def83SBjoern A. Zeeb 	value = value << HE_DL_UL_SHIFT;
4845c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
4855c1def83SBjoern A. Zeeb 
4865c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS);
4875c1def83SBjoern A. Zeeb 	ppdu_info->mcs = value;
4885c1def83SBjoern A. Zeeb 	value = value << HE_TRANSMIT_MCS_SHIFT;
4895c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
4905c1def83SBjoern A. Zeeb 
4915c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM);
4925c1def83SBjoern A. Zeeb 	he_dcm = value;
4935c1def83SBjoern A. Zeeb 	value = value << HE_DCM_SHIFT;
4945c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
4955c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING);
4965c1def83SBjoern A. Zeeb 	value = value << HE_CODING_SHIFT;
4975c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
4985c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA);
4995c1def83SBjoern A. Zeeb 	value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT;
5005c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
5015c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC);
5025c1def83SBjoern A. Zeeb 	he_stbc = value;
5035c1def83SBjoern A. Zeeb 	value = value << HE_STBC_SHIFT;
5045c1def83SBjoern A. Zeeb 	ppdu_info->he_data3 |= value;
5055c1def83SBjoern A. Zeeb 
5065c1def83SBjoern A. Zeeb 	/* data4 */
5075c1def83SBjoern A. Zeeb 	ppdu_info->he_data4 = u32_get_bits(info0,
5085c1def83SBjoern A. Zeeb 					   HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE);
5095c1def83SBjoern A. Zeeb 
5105c1def83SBjoern A. Zeeb 	/* data5 */
5115c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0,
5125c1def83SBjoern A. Zeeb 			     HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW);
5135c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 = value;
5145c1def83SBjoern A. Zeeb 	ppdu_info->bw = value;
5155c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE);
5165c1def83SBjoern A. Zeeb 	switch (value) {
5175c1def83SBjoern A. Zeeb 	case 0:
5185c1def83SBjoern A. Zeeb 		he_gi = HE_GI_0_8;
5195c1def83SBjoern A. Zeeb 		he_ltf = HE_LTF_1_X;
5205c1def83SBjoern A. Zeeb 		break;
5215c1def83SBjoern A. Zeeb 	case 1:
5225c1def83SBjoern A. Zeeb 		he_gi = HE_GI_0_8;
5235c1def83SBjoern A. Zeeb 		he_ltf = HE_LTF_2_X;
5245c1def83SBjoern A. Zeeb 		break;
5255c1def83SBjoern A. Zeeb 	case 2:
5265c1def83SBjoern A. Zeeb 		he_gi = HE_GI_1_6;
5275c1def83SBjoern A. Zeeb 		he_ltf = HE_LTF_2_X;
5285c1def83SBjoern A. Zeeb 		break;
5295c1def83SBjoern A. Zeeb 	case 3:
5305c1def83SBjoern A. Zeeb 		if (he_dcm && he_stbc) {
5315c1def83SBjoern A. Zeeb 			he_gi = HE_GI_0_8;
5325c1def83SBjoern A. Zeeb 			he_ltf = HE_LTF_4_X;
5335c1def83SBjoern A. Zeeb 		} else {
5345c1def83SBjoern A. Zeeb 			he_gi = HE_GI_3_2;
5355c1def83SBjoern A. Zeeb 			he_ltf = HE_LTF_4_X;
5365c1def83SBjoern A. Zeeb 		}
5375c1def83SBjoern A. Zeeb 		break;
5385c1def83SBjoern A. Zeeb 	}
5395c1def83SBjoern A. Zeeb 	ppdu_info->gi = he_gi;
5405c1def83SBjoern A. Zeeb 	value = he_gi << HE_GI_SHIFT;
5415c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 |= value;
5425c1def83SBjoern A. Zeeb 	value = he_ltf << HE_LTF_SIZE_SHIFT;
5435c1def83SBjoern A. Zeeb 	ppdu_info->ltf_size = he_ltf;
5445c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 |= value;
5455c1def83SBjoern A. Zeeb 
5465c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS);
5475c1def83SBjoern A. Zeeb 	value = (value << HE_LTF_SYM_SHIFT);
5485c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 |= value;
5495c1def83SBjoern A. Zeeb 
5505c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR);
5515c1def83SBjoern A. Zeeb 	value = value << HE_PRE_FEC_PAD_SHIFT;
5525c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 |= value;
5535c1def83SBjoern A. Zeeb 
5545c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF);
5555c1def83SBjoern A. Zeeb 	value = value << HE_TXBF_SHIFT;
5565c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 |= value;
5575c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM);
5585c1def83SBjoern A. Zeeb 	value = value << HE_PE_DISAMBIGUITY_SHIFT;
5595c1def83SBjoern A. Zeeb 	ppdu_info->he_data5 |= value;
5605c1def83SBjoern A. Zeeb 
5615c1def83SBjoern A. Zeeb 	/* data6 */
5625c1def83SBjoern A. Zeeb 	value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS);
5635c1def83SBjoern A. Zeeb 	value++;
5645c1def83SBjoern A. Zeeb 	ppdu_info->he_data6 = value;
5655c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND);
5665c1def83SBjoern A. Zeeb 	value = value << HE_DOPPLER_SHIFT;
5675c1def83SBjoern A. Zeeb 	ppdu_info->he_data6 |= value;
5685c1def83SBjoern A. Zeeb 	value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION);
5695c1def83SBjoern A. Zeeb 	value = value << HE_TXOP_SHIFT;
5705c1def83SBjoern A. Zeeb 	ppdu_info->he_data6 |= value;
5715c1def83SBjoern A. Zeeb 
5725c1def83SBjoern A. Zeeb 	ppdu_info->mcs =
5735c1def83SBjoern A. Zeeb 		u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS);
5745c1def83SBjoern A. Zeeb 	ppdu_info->bw =
5755c1def83SBjoern A. Zeeb 		u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW);
5765c1def83SBjoern A. Zeeb 	ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING);
5775c1def83SBjoern A. Zeeb 	ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC);
5785c1def83SBjoern A. Zeeb 	ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF);
5795c1def83SBjoern A. Zeeb 	dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM);
5805c1def83SBjoern A. Zeeb 	ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS);
5815c1def83SBjoern A. Zeeb 	ppdu_info->dcm = dcm;
5825c1def83SBjoern A. Zeeb 	ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
5835c1def83SBjoern A. Zeeb }
5845c1def83SBjoern A. Zeeb 
5855c1def83SBjoern A. Zeeb static enum hal_rx_mon_status
ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_base * ab,struct ath12k_mon_data * pmon,u32 tlv_tag,u8 * tlv_data,u32 userid)5865c1def83SBjoern A. Zeeb ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_base *ab,
5875c1def83SBjoern A. Zeeb 				  struct ath12k_mon_data *pmon,
5885c1def83SBjoern A. Zeeb 				  u32 tlv_tag, u8 *tlv_data, u32 userid)
5895c1def83SBjoern A. Zeeb {
5905c1def83SBjoern A. Zeeb 	struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
5915c1def83SBjoern A. Zeeb 	u32 info[7];
5925c1def83SBjoern A. Zeeb 
5935c1def83SBjoern A. Zeeb 	switch (tlv_tag) {
5945c1def83SBjoern A. Zeeb 	case HAL_RX_PPDU_START: {
5955c1def83SBjoern A. Zeeb 		struct hal_rx_ppdu_start *ppdu_start =
5965c1def83SBjoern A. Zeeb 			(struct hal_rx_ppdu_start *)tlv_data;
5975c1def83SBjoern A. Zeeb 
5985c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(ppdu_start->info0);
5995c1def83SBjoern A. Zeeb 
6005c1def83SBjoern A. Zeeb 		ppdu_info->ppdu_id =
6015c1def83SBjoern A. Zeeb 			u32_get_bits(info[0], HAL_RX_PPDU_START_INFO0_PPDU_ID);
6025c1def83SBjoern A. Zeeb 		ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num);
6035c1def83SBjoern A. Zeeb 		ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts);
6045c1def83SBjoern A. Zeeb 
6055c1def83SBjoern A. Zeeb 		if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) {
6065c1def83SBjoern A. Zeeb 			ppdu_info->last_ppdu_id = ppdu_info->ppdu_id;
6075c1def83SBjoern A. Zeeb 			ppdu_info->num_users = 0;
6085c1def83SBjoern A. Zeeb 			memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0,
6095c1def83SBjoern A. Zeeb 			       HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *
6105c1def83SBjoern A. Zeeb 			       sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0]));
6115c1def83SBjoern A. Zeeb 		}
6125c1def83SBjoern A. Zeeb 		break;
6135c1def83SBjoern A. Zeeb 	}
6145c1def83SBjoern A. Zeeb 	case HAL_RX_PPDU_END_USER_STATS: {
6155c1def83SBjoern A. Zeeb 		struct hal_rx_ppdu_end_user_stats *eu_stats =
6165c1def83SBjoern A. Zeeb 			(struct hal_rx_ppdu_end_user_stats *)tlv_data;
6175c1def83SBjoern A. Zeeb 
6185c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(eu_stats->info0);
6195c1def83SBjoern A. Zeeb 		info[1] = __le32_to_cpu(eu_stats->info1);
6205c1def83SBjoern A. Zeeb 		info[2] = __le32_to_cpu(eu_stats->info2);
6215c1def83SBjoern A. Zeeb 		info[4] = __le32_to_cpu(eu_stats->info4);
6225c1def83SBjoern A. Zeeb 		info[5] = __le32_to_cpu(eu_stats->info5);
6235c1def83SBjoern A. Zeeb 		info[6] = __le32_to_cpu(eu_stats->info6);
6245c1def83SBjoern A. Zeeb 
6255c1def83SBjoern A. Zeeb 		ppdu_info->ast_index =
6265c1def83SBjoern A. Zeeb 			u32_get_bits(info[2], HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX);
6275c1def83SBjoern A. Zeeb 		ppdu_info->fc_valid =
6285c1def83SBjoern A. Zeeb 			u32_get_bits(info[1], HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID);
6295c1def83SBjoern A. Zeeb 		ppdu_info->tid =
6305c1def83SBjoern A. Zeeb 			ffs(u32_get_bits(info[6],
6315c1def83SBjoern A. Zeeb 					 HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP)
6325c1def83SBjoern A. Zeeb 					 - 1);
6335c1def83SBjoern A. Zeeb 		ppdu_info->tcp_msdu_count =
6345c1def83SBjoern A. Zeeb 			u32_get_bits(info[4],
6355c1def83SBjoern A. Zeeb 				     HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT);
6365c1def83SBjoern A. Zeeb 		ppdu_info->udp_msdu_count =
6375c1def83SBjoern A. Zeeb 			u32_get_bits(info[4],
6385c1def83SBjoern A. Zeeb 				     HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT);
6395c1def83SBjoern A. Zeeb 		ppdu_info->other_msdu_count =
6405c1def83SBjoern A. Zeeb 			u32_get_bits(info[5],
6415c1def83SBjoern A. Zeeb 				     HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT);
6425c1def83SBjoern A. Zeeb 		ppdu_info->tcp_ack_msdu_count =
6435c1def83SBjoern A. Zeeb 			u32_get_bits(info[5],
6445c1def83SBjoern A. Zeeb 				     HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT);
6455c1def83SBjoern A. Zeeb 		ppdu_info->preamble_type =
6465c1def83SBjoern A. Zeeb 			u32_get_bits(info[1],
6475c1def83SBjoern A. Zeeb 				     HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE);
6485c1def83SBjoern A. Zeeb 		ppdu_info->num_mpdu_fcs_ok =
6495c1def83SBjoern A. Zeeb 			u32_get_bits(info[1],
6505c1def83SBjoern A. Zeeb 				     HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK);
6515c1def83SBjoern A. Zeeb 		ppdu_info->num_mpdu_fcs_err =
6525c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
6535c1def83SBjoern A. Zeeb 				     HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR);
6545c1def83SBjoern A. Zeeb 		switch (ppdu_info->preamble_type) {
6555c1def83SBjoern A. Zeeb 		case HAL_RX_PREAMBLE_11N:
6565c1def83SBjoern A. Zeeb 			ppdu_info->ht_flags = 1;
6575c1def83SBjoern A. Zeeb 			break;
6585c1def83SBjoern A. Zeeb 		case HAL_RX_PREAMBLE_11AC:
6595c1def83SBjoern A. Zeeb 			ppdu_info->vht_flags = 1;
6605c1def83SBjoern A. Zeeb 			break;
6615c1def83SBjoern A. Zeeb 		case HAL_RX_PREAMBLE_11AX:
6625c1def83SBjoern A. Zeeb 			ppdu_info->he_flags = 1;
6635c1def83SBjoern A. Zeeb 			break;
6645c1def83SBjoern A. Zeeb 		default:
6655c1def83SBjoern A. Zeeb 			break;
6665c1def83SBjoern A. Zeeb 		}
6675c1def83SBjoern A. Zeeb 
6685c1def83SBjoern A. Zeeb 		if (userid < HAL_MAX_UL_MU_USERS) {
6695c1def83SBjoern A. Zeeb 			struct hal_rx_user_status *rxuser_stats =
6705c1def83SBjoern A. Zeeb 				&ppdu_info->userstats[userid];
6715c1def83SBjoern A. Zeeb 			ppdu_info->num_users += 1;
6725c1def83SBjoern A. Zeeb 
6735c1def83SBjoern A. Zeeb 			ath12k_dp_mon_rx_handle_ofdma_info(tlv_data, rxuser_stats);
6745c1def83SBjoern A. Zeeb 			ath12k_dp_mon_rx_populate_mu_user_info(tlv_data, ppdu_info,
6755c1def83SBjoern A. Zeeb 							       rxuser_stats);
6765c1def83SBjoern A. Zeeb 		}
6775c1def83SBjoern A. Zeeb 		ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]);
6785c1def83SBjoern A. Zeeb 		ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]);
6795c1def83SBjoern A. Zeeb 		break;
6805c1def83SBjoern A. Zeeb 	}
6815c1def83SBjoern A. Zeeb 	case HAL_RX_PPDU_END_USER_STATS_EXT: {
6825c1def83SBjoern A. Zeeb 		struct hal_rx_ppdu_end_user_stats_ext *eu_stats =
6835c1def83SBjoern A. Zeeb 			(struct hal_rx_ppdu_end_user_stats_ext *)tlv_data;
6845c1def83SBjoern A. Zeeb 		ppdu_info->mpdu_fcs_ok_bitmap[2] = __le32_to_cpu(eu_stats->info1);
6855c1def83SBjoern A. Zeeb 		ppdu_info->mpdu_fcs_ok_bitmap[3] = __le32_to_cpu(eu_stats->info2);
6865c1def83SBjoern A. Zeeb 		ppdu_info->mpdu_fcs_ok_bitmap[4] = __le32_to_cpu(eu_stats->info3);
6875c1def83SBjoern A. Zeeb 		ppdu_info->mpdu_fcs_ok_bitmap[5] = __le32_to_cpu(eu_stats->info4);
6885c1def83SBjoern A. Zeeb 		ppdu_info->mpdu_fcs_ok_bitmap[6] = __le32_to_cpu(eu_stats->info5);
6895c1def83SBjoern A. Zeeb 		ppdu_info->mpdu_fcs_ok_bitmap[7] = __le32_to_cpu(eu_stats->info6);
6905c1def83SBjoern A. Zeeb 		break;
6915c1def83SBjoern A. Zeeb 	}
6925c1def83SBjoern A. Zeeb 	case HAL_PHYRX_HT_SIG:
6935c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info);
6945c1def83SBjoern A. Zeeb 		break;
6955c1def83SBjoern A. Zeeb 
6965c1def83SBjoern A. Zeeb 	case HAL_PHYRX_L_SIG_B:
6975c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info);
6985c1def83SBjoern A. Zeeb 		break;
6995c1def83SBjoern A. Zeeb 
7005c1def83SBjoern A. Zeeb 	case HAL_PHYRX_L_SIG_A:
7015c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info);
7025c1def83SBjoern A. Zeeb 		break;
7035c1def83SBjoern A. Zeeb 
7045c1def83SBjoern A. Zeeb 	case HAL_PHYRX_VHT_SIG_A:
7055c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info);
7065c1def83SBjoern A. Zeeb 		break;
7075c1def83SBjoern A. Zeeb 
7085c1def83SBjoern A. Zeeb 	case HAL_PHYRX_HE_SIG_A_SU:
7095c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info);
7105c1def83SBjoern A. Zeeb 		break;
7115c1def83SBjoern A. Zeeb 
7125c1def83SBjoern A. Zeeb 	case HAL_PHYRX_HE_SIG_A_MU_DL:
7135c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info);
7145c1def83SBjoern A. Zeeb 		break;
7155c1def83SBjoern A. Zeeb 
7165c1def83SBjoern A. Zeeb 	case HAL_PHYRX_HE_SIG_B1_MU:
7175c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info);
7185c1def83SBjoern A. Zeeb 		break;
7195c1def83SBjoern A. Zeeb 
7205c1def83SBjoern A. Zeeb 	case HAL_PHYRX_HE_SIG_B2_MU:
7215c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info);
7225c1def83SBjoern A. Zeeb 		break;
7235c1def83SBjoern A. Zeeb 
7245c1def83SBjoern A. Zeeb 	case HAL_PHYRX_HE_SIG_B2_OFDMA:
7255c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info);
7265c1def83SBjoern A. Zeeb 		break;
7275c1def83SBjoern A. Zeeb 
7285c1def83SBjoern A. Zeeb 	case HAL_PHYRX_RSSI_LEGACY: {
7295c1def83SBjoern A. Zeeb 		struct hal_rx_phyrx_rssi_legacy_info *rssi =
7305c1def83SBjoern A. Zeeb 			(struct hal_rx_phyrx_rssi_legacy_info *)tlv_data;
7315c1def83SBjoern A. Zeeb 		u32 reception_type = 0;
7325c1def83SBjoern A. Zeeb 		u32 rssi_legacy_info = __le32_to_cpu(rssi->rsvd[0]);
7335c1def83SBjoern A. Zeeb 
7345c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(rssi->info0);
7355c1def83SBjoern A. Zeeb 
7365c1def83SBjoern A. Zeeb 		/* TODO: Please note that the combined rssi will not be accurate
7375c1def83SBjoern A. Zeeb 		 * in MU case. Rssi in MU needs to be retrieved from
7385c1def83SBjoern A. Zeeb 		 * PHYRX_OTHER_RECEIVE_INFO TLV.
7395c1def83SBjoern A. Zeeb 		 */
7405c1def83SBjoern A. Zeeb 		ppdu_info->rssi_comb =
7415c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
7425c1def83SBjoern A. Zeeb 				     HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB);
7435c1def83SBjoern A. Zeeb 		reception_type =
7445c1def83SBjoern A. Zeeb 			u32_get_bits(rssi_legacy_info,
7455c1def83SBjoern A. Zeeb 				     HAL_RX_PHYRX_RSSI_LEGACY_INFO_RSVD1_RECEPTION);
7465c1def83SBjoern A. Zeeb 
7475c1def83SBjoern A. Zeeb 		switch (reception_type) {
7485c1def83SBjoern A. Zeeb 		case HAL_RECEPTION_TYPE_ULOFMDA:
7495c1def83SBjoern A. Zeeb 			ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA;
7505c1def83SBjoern A. Zeeb 			break;
7515c1def83SBjoern A. Zeeb 		case HAL_RECEPTION_TYPE_ULMIMO:
7525c1def83SBjoern A. Zeeb 			ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;
7535c1def83SBjoern A. Zeeb 			break;
7545c1def83SBjoern A. Zeeb 		default:
7555c1def83SBjoern A. Zeeb 			ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
7565c1def83SBjoern A. Zeeb 			break;
7575c1def83SBjoern A. Zeeb 		}
7585c1def83SBjoern A. Zeeb 		break;
7595c1def83SBjoern A. Zeeb 	}
7605c1def83SBjoern A. Zeeb 	case HAL_RXPCU_PPDU_END_INFO: {
7615c1def83SBjoern A. Zeeb 		struct hal_rx_ppdu_end_duration *ppdu_rx_duration =
7625c1def83SBjoern A. Zeeb 			(struct hal_rx_ppdu_end_duration *)tlv_data;
7635c1def83SBjoern A. Zeeb 
7645c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(ppdu_rx_duration->info0);
7655c1def83SBjoern A. Zeeb 		ppdu_info->rx_duration =
7665c1def83SBjoern A. Zeeb 			u32_get_bits(info[0], HAL_RX_PPDU_END_DURATION);
7675c1def83SBjoern A. Zeeb 		ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]);
7685c1def83SBjoern A. Zeeb 		ppdu_info->tsft = (ppdu_info->tsft << 32) |
7695c1def83SBjoern A. Zeeb 				   __le32_to_cpu(ppdu_rx_duration->rsvd0[0]);
7705c1def83SBjoern A. Zeeb 		break;
7715c1def83SBjoern A. Zeeb 	}
7725c1def83SBjoern A. Zeeb 	case HAL_RX_MPDU_START: {
7735c1def83SBjoern A. Zeeb 		struct hal_rx_mpdu_start *mpdu_start =
7745c1def83SBjoern A. Zeeb 			(struct hal_rx_mpdu_start *)tlv_data;
7755c1def83SBjoern A. Zeeb 		struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;
7765c1def83SBjoern A. Zeeb 		u16 peer_id;
7775c1def83SBjoern A. Zeeb 
7785c1def83SBjoern A. Zeeb 		info[1] = __le32_to_cpu(mpdu_start->info1);
7795c1def83SBjoern A. Zeeb 		peer_id = u32_get_bits(info[1], HAL_RX_MPDU_START_INFO1_PEERID);
7805c1def83SBjoern A. Zeeb 		if (peer_id)
7815c1def83SBjoern A. Zeeb 			ppdu_info->peer_id = peer_id;
7825c1def83SBjoern A. Zeeb 
7835c1def83SBjoern A. Zeeb 		ppdu_info->mpdu_len += u32_get_bits(info[1],
7845c1def83SBjoern A. Zeeb 						    HAL_RX_MPDU_START_INFO2_MPDU_LEN);
7855c1def83SBjoern A. Zeeb 		if (userid < HAL_MAX_UL_MU_USERS) {
7865c1def83SBjoern A. Zeeb 			info[0] = __le32_to_cpu(mpdu_start->info0);
7875c1def83SBjoern A. Zeeb 			ppdu_info->userid = userid;
7885c1def83SBjoern A. Zeeb 			ppdu_info->ampdu_id[userid] =
7895c1def83SBjoern A. Zeeb 				u32_get_bits(info[0], HAL_RX_MPDU_START_INFO1_PEERID);
7905c1def83SBjoern A. Zeeb 		}
7915c1def83SBjoern A. Zeeb 
7925c1def83SBjoern A. Zeeb 		mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC);
7935c1def83SBjoern A. Zeeb 		if (!mon_mpdu)
7945c1def83SBjoern A. Zeeb 			return HAL_RX_MON_STATUS_PPDU_NOT_DONE;
7955c1def83SBjoern A. Zeeb 
7965c1def83SBjoern A. Zeeb 		break;
7975c1def83SBjoern A. Zeeb 	}
7985c1def83SBjoern A. Zeeb 	case HAL_RX_MSDU_START:
7995c1def83SBjoern A. Zeeb 		/* TODO: add msdu start parsing logic */
8005c1def83SBjoern A. Zeeb 		break;
8015c1def83SBjoern A. Zeeb 	case HAL_MON_BUF_ADDR: {
8025c1def83SBjoern A. Zeeb 		struct dp_rxdma_ring *buf_ring = &ab->dp.rxdma_mon_buf_ring;
8035c1def83SBjoern A. Zeeb 		struct dp_mon_packet_info *packet_info =
8045c1def83SBjoern A. Zeeb 			(struct dp_mon_packet_info *)tlv_data;
8055c1def83SBjoern A. Zeeb 		int buf_id = u32_get_bits(packet_info->cookie,
8065c1def83SBjoern A. Zeeb 					  DP_RXDMA_BUF_COOKIE_BUF_ID);
8075c1def83SBjoern A. Zeeb 		struct sk_buff *msdu;
8085c1def83SBjoern A. Zeeb 		struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;
8095c1def83SBjoern A. Zeeb 		struct ath12k_skb_rxcb *rxcb;
8105c1def83SBjoern A. Zeeb 
8115c1def83SBjoern A. Zeeb 		spin_lock_bh(&buf_ring->idr_lock);
8125c1def83SBjoern A. Zeeb 		msdu = idr_remove(&buf_ring->bufs_idr, buf_id);
8135c1def83SBjoern A. Zeeb 		spin_unlock_bh(&buf_ring->idr_lock);
8145c1def83SBjoern A. Zeeb 
8155c1def83SBjoern A. Zeeb 		if (unlikely(!msdu)) {
8165c1def83SBjoern A. Zeeb 			ath12k_warn(ab, "monitor destination with invalid buf_id %d\n",
8175c1def83SBjoern A. Zeeb 				    buf_id);
8185c1def83SBjoern A. Zeeb 			return HAL_RX_MON_STATUS_PPDU_NOT_DONE;
8195c1def83SBjoern A. Zeeb 		}
8205c1def83SBjoern A. Zeeb 
8215c1def83SBjoern A. Zeeb 		rxcb = ATH12K_SKB_RXCB(msdu);
8225c1def83SBjoern A. Zeeb 		dma_unmap_single(ab->dev, rxcb->paddr,
8235c1def83SBjoern A. Zeeb 				 msdu->len + skb_tailroom(msdu),
8245c1def83SBjoern A. Zeeb 				 DMA_FROM_DEVICE);
8255c1def83SBjoern A. Zeeb 
8265c1def83SBjoern A. Zeeb 		if (mon_mpdu->tail)
8275c1def83SBjoern A. Zeeb 			mon_mpdu->tail->next = msdu;
8285c1def83SBjoern A. Zeeb 		else
8295c1def83SBjoern A. Zeeb 			mon_mpdu->tail = msdu;
8305c1def83SBjoern A. Zeeb 
8315c1def83SBjoern A. Zeeb 		ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);
8325c1def83SBjoern A. Zeeb 
8335c1def83SBjoern A. Zeeb 		break;
8345c1def83SBjoern A. Zeeb 	}
8355c1def83SBjoern A. Zeeb 	case HAL_RX_MSDU_END: {
8365c1def83SBjoern A. Zeeb 		struct rx_msdu_end_qcn9274 *msdu_end =
8375c1def83SBjoern A. Zeeb 			(struct rx_msdu_end_qcn9274 *)tlv_data;
8385c1def83SBjoern A. Zeeb 		bool is_first_msdu_in_mpdu;
8395c1def83SBjoern A. Zeeb 		u16 msdu_end_info;
8405c1def83SBjoern A. Zeeb 
8415c1def83SBjoern A. Zeeb 		msdu_end_info = __le16_to_cpu(msdu_end->info5);
8425c1def83SBjoern A. Zeeb 		is_first_msdu_in_mpdu = u32_get_bits(msdu_end_info,
8435c1def83SBjoern A. Zeeb 						     RX_MSDU_END_INFO5_FIRST_MSDU);
8445c1def83SBjoern A. Zeeb 		if (is_first_msdu_in_mpdu) {
8455c1def83SBjoern A. Zeeb 			pmon->mon_mpdu->head = pmon->mon_mpdu->tail;
8465c1def83SBjoern A. Zeeb 			pmon->mon_mpdu->tail = NULL;
8475c1def83SBjoern A. Zeeb 		}
8485c1def83SBjoern A. Zeeb 		break;
8495c1def83SBjoern A. Zeeb 	}
8505c1def83SBjoern A. Zeeb 	case HAL_RX_MPDU_END:
8515c1def83SBjoern A. Zeeb 		list_add_tail(&pmon->mon_mpdu->list, &pmon->dp_rx_mon_mpdu_list);
8525c1def83SBjoern A. Zeeb 		break;
8535c1def83SBjoern A. Zeeb 	case HAL_DUMMY:
8545c1def83SBjoern A. Zeeb 		return HAL_RX_MON_STATUS_BUF_DONE;
8555c1def83SBjoern A. Zeeb 	case HAL_RX_PPDU_END_STATUS_DONE:
8565c1def83SBjoern A. Zeeb 	case 0:
8575c1def83SBjoern A. Zeeb 		return HAL_RX_MON_STATUS_PPDU_DONE;
8585c1def83SBjoern A. Zeeb 	default:
8595c1def83SBjoern A. Zeeb 		break;
8605c1def83SBjoern A. Zeeb 	}
8615c1def83SBjoern A. Zeeb 
8625c1def83SBjoern A. Zeeb 	return HAL_RX_MON_STATUS_PPDU_NOT_DONE;
8635c1def83SBjoern A. Zeeb }
8645c1def83SBjoern A. Zeeb 
ath12k_dp_mon_rx_msdus_set_payload(struct ath12k * ar,struct sk_buff * msdu)8655c1def83SBjoern A. Zeeb static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar, struct sk_buff *msdu)
8665c1def83SBjoern A. Zeeb {
8675c1def83SBjoern A. Zeeb 	u32 rx_pkt_offset, l2_hdr_offset;
8685c1def83SBjoern A. Zeeb 
8695c1def83SBjoern A. Zeeb 	rx_pkt_offset = ar->ab->hw_params->hal_desc_sz;
8705c1def83SBjoern A. Zeeb 	l2_hdr_offset = ath12k_dp_rx_h_l3pad(ar->ab,
8715c1def83SBjoern A. Zeeb 					     (struct hal_rx_desc *)msdu->data);
8725c1def83SBjoern A. Zeeb 	skb_pull(msdu, rx_pkt_offset + l2_hdr_offset);
8735c1def83SBjoern A. Zeeb }
8745c1def83SBjoern A. Zeeb 
8755c1def83SBjoern A. Zeeb static struct sk_buff *
ath12k_dp_mon_rx_merg_msdus(struct ath12k * ar,u32 mac_id,struct sk_buff * head_msdu,struct ieee80211_rx_status * rxs,bool * fcs_err)8765c1def83SBjoern A. Zeeb ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,
8775c1def83SBjoern A. Zeeb 			    u32 mac_id, struct sk_buff *head_msdu,
8785c1def83SBjoern A. Zeeb 			    struct ieee80211_rx_status *rxs, bool *fcs_err)
8795c1def83SBjoern A. Zeeb {
8805c1def83SBjoern A. Zeeb 	struct ath12k_base *ab = ar->ab;
8815c1def83SBjoern A. Zeeb 	struct sk_buff *msdu, *mpdu_buf, *prev_buf;
8825c1def83SBjoern A. Zeeb 	struct hal_rx_desc *rx_desc;
8835c1def83SBjoern A. Zeeb 	u8 *hdr_desc, *dest, decap_format;
8845c1def83SBjoern A. Zeeb 	struct ieee80211_hdr_3addr *wh;
8855c1def83SBjoern A. Zeeb 	u32 err_bitmap;
8865c1def83SBjoern A. Zeeb 
8875c1def83SBjoern A. Zeeb 	mpdu_buf = NULL;
8885c1def83SBjoern A. Zeeb 
8895c1def83SBjoern A. Zeeb 	if (!head_msdu)
8905c1def83SBjoern A. Zeeb 		goto err_merge_fail;
8915c1def83SBjoern A. Zeeb 
8925c1def83SBjoern A. Zeeb 	rx_desc = (struct hal_rx_desc *)head_msdu->data;
8935c1def83SBjoern A. Zeeb 	err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc);
8945c1def83SBjoern A. Zeeb 
8955c1def83SBjoern A. Zeeb 	if (err_bitmap & HAL_RX_MPDU_ERR_FCS)
8965c1def83SBjoern A. Zeeb 		*fcs_err = true;
8975c1def83SBjoern A. Zeeb 
8985c1def83SBjoern A. Zeeb 	decap_format = ath12k_dp_rx_h_decap_type(ab, rx_desc);
8995c1def83SBjoern A. Zeeb 
9005c1def83SBjoern A. Zeeb 	ath12k_dp_rx_h_ppdu(ar, rx_desc, rxs);
9015c1def83SBjoern A. Zeeb 
9025c1def83SBjoern A. Zeeb 	if (decap_format == DP_RX_DECAP_TYPE_RAW) {
9035c1def83SBjoern A. Zeeb 		ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu);
9045c1def83SBjoern A. Zeeb 
9055c1def83SBjoern A. Zeeb 		prev_buf = head_msdu;
9065c1def83SBjoern A. Zeeb 		msdu = head_msdu->next;
9075c1def83SBjoern A. Zeeb 
9085c1def83SBjoern A. Zeeb 		while (msdu) {
9095c1def83SBjoern A. Zeeb 			ath12k_dp_mon_rx_msdus_set_payload(ar, msdu);
9105c1def83SBjoern A. Zeeb 
9115c1def83SBjoern A. Zeeb 			prev_buf = msdu;
9125c1def83SBjoern A. Zeeb 			msdu = msdu->next;
9135c1def83SBjoern A. Zeeb 		}
9145c1def83SBjoern A. Zeeb 
9155c1def83SBjoern A. Zeeb 		prev_buf->next = NULL;
9165c1def83SBjoern A. Zeeb 
9175c1def83SBjoern A. Zeeb 		skb_trim(prev_buf, prev_buf->len - HAL_RX_FCS_LEN);
9185c1def83SBjoern A. Zeeb 	} else if (decap_format == DP_RX_DECAP_TYPE_NATIVE_WIFI) {
9195c1def83SBjoern A. Zeeb 		u8 qos_pkt = 0;
9205c1def83SBjoern A. Zeeb 
9215c1def83SBjoern A. Zeeb 		rx_desc = (struct hal_rx_desc *)head_msdu->data;
9225c1def83SBjoern A. Zeeb 		hdr_desc = ab->hw_params->hal_ops->rx_desc_get_msdu_payload(rx_desc);
9235c1def83SBjoern A. Zeeb 
9245c1def83SBjoern A. Zeeb 		/* Base size */
9255c1def83SBjoern A. Zeeb 		wh = (struct ieee80211_hdr_3addr *)hdr_desc;
9265c1def83SBjoern A. Zeeb 
9275c1def83SBjoern A. Zeeb 		if (ieee80211_is_data_qos(wh->frame_control))
9285c1def83SBjoern A. Zeeb 			qos_pkt = 1;
9295c1def83SBjoern A. Zeeb 
9305c1def83SBjoern A. Zeeb 		msdu = head_msdu;
9315c1def83SBjoern A. Zeeb 
9325c1def83SBjoern A. Zeeb 		while (msdu) {
9335c1def83SBjoern A. Zeeb 			ath12k_dp_mon_rx_msdus_set_payload(ar, msdu);
9345c1def83SBjoern A. Zeeb 			if (qos_pkt) {
9355c1def83SBjoern A. Zeeb 				dest = skb_push(msdu, sizeof(__le16));
9365c1def83SBjoern A. Zeeb 				if (!dest)
9375c1def83SBjoern A. Zeeb 					goto err_merge_fail;
9385c1def83SBjoern A. Zeeb 				memcpy(dest, hdr_desc, sizeof(struct ieee80211_qos_hdr));
9395c1def83SBjoern A. Zeeb 			}
9405c1def83SBjoern A. Zeeb 			prev_buf = msdu;
9415c1def83SBjoern A. Zeeb 			msdu = msdu->next;
9425c1def83SBjoern A. Zeeb 		}
9435c1def83SBjoern A. Zeeb 		dest = skb_put(prev_buf, HAL_RX_FCS_LEN);
9445c1def83SBjoern A. Zeeb 		if (!dest)
9455c1def83SBjoern A. Zeeb 			goto err_merge_fail;
9465c1def83SBjoern A. Zeeb 
9475c1def83SBjoern A. Zeeb 		ath12k_dbg(ab, ATH12K_DBG_DATA,
9485c1def83SBjoern A. Zeeb 			   "mpdu_buf %pK mpdu_buf->len %u",
9495c1def83SBjoern A. Zeeb 			   prev_buf, prev_buf->len);
9505c1def83SBjoern A. Zeeb 	} else {
9515c1def83SBjoern A. Zeeb 		ath12k_dbg(ab, ATH12K_DBG_DATA,
9525c1def83SBjoern A. Zeeb 			   "decap format %d is not supported!\n",
9535c1def83SBjoern A. Zeeb 			   decap_format);
9545c1def83SBjoern A. Zeeb 		goto err_merge_fail;
9555c1def83SBjoern A. Zeeb 	}
9565c1def83SBjoern A. Zeeb 
9575c1def83SBjoern A. Zeeb 	return head_msdu;
9585c1def83SBjoern A. Zeeb 
9595c1def83SBjoern A. Zeeb err_merge_fail:
9605c1def83SBjoern A. Zeeb 	if (mpdu_buf && decap_format != DP_RX_DECAP_TYPE_RAW) {
9615c1def83SBjoern A. Zeeb 		ath12k_dbg(ab, ATH12K_DBG_DATA,
9625c1def83SBjoern A. Zeeb 			   "err_merge_fail mpdu_buf %pK", mpdu_buf);
9635c1def83SBjoern A. Zeeb 		/* Free the head buffer */
9645c1def83SBjoern A. Zeeb 		dev_kfree_skb_any(mpdu_buf);
9655c1def83SBjoern A. Zeeb 	}
9665c1def83SBjoern A. Zeeb 	return NULL;
9675c1def83SBjoern A. Zeeb }
9685c1def83SBjoern A. Zeeb 
9695c1def83SBjoern A. Zeeb static void
ath12k_dp_mon_rx_update_radiotap_he(struct hal_rx_mon_ppdu_info * rx_status,u8 * rtap_buf)9705c1def83SBjoern A. Zeeb ath12k_dp_mon_rx_update_radiotap_he(struct hal_rx_mon_ppdu_info *rx_status,
9715c1def83SBjoern A. Zeeb 				    u8 *rtap_buf)
9725c1def83SBjoern A. Zeeb {
9735c1def83SBjoern A. Zeeb 	u32 rtap_len = 0;
9745c1def83SBjoern A. Zeeb 
9755c1def83SBjoern A. Zeeb 	put_unaligned_le16(rx_status->he_data1, &rtap_buf[rtap_len]);
9765c1def83SBjoern A. Zeeb 	rtap_len += 2;
9775c1def83SBjoern A. Zeeb 
9785c1def83SBjoern A. Zeeb 	put_unaligned_le16(rx_status->he_data2, &rtap_buf[rtap_len]);
9795c1def83SBjoern A. Zeeb 	rtap_len += 2;
9805c1def83SBjoern A. Zeeb 
9815c1def83SBjoern A. Zeeb 	put_unaligned_le16(rx_status->he_data3, &rtap_buf[rtap_len]);
9825c1def83SBjoern A. Zeeb 	rtap_len += 2;
9835c1def83SBjoern A. Zeeb 
9845c1def83SBjoern A. Zeeb 	put_unaligned_le16(rx_status->he_data4, &rtap_buf[rtap_len]);
9855c1def83SBjoern A. Zeeb 	rtap_len += 2;
9865c1def83SBjoern A. Zeeb 
9875c1def83SBjoern A. Zeeb 	put_unaligned_le16(rx_status->he_data5, &rtap_buf[rtap_len]);
9885c1def83SBjoern A. Zeeb 	rtap_len += 2;
9895c1def83SBjoern A. Zeeb 
9905c1def83SBjoern A. Zeeb 	put_unaligned_le16(rx_status->he_data6, &rtap_buf[rtap_len]);
9915c1def83SBjoern A. Zeeb }
9925c1def83SBjoern A. Zeeb 
9935c1def83SBjoern A. Zeeb static void
ath12k_dp_mon_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info * rx_status,u8 * rtap_buf)9945c1def83SBjoern A. Zeeb ath12k_dp_mon_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info *rx_status,
9955c1def83SBjoern A. Zeeb 				       u8 *rtap_buf)
9965c1def83SBjoern A. Zeeb {
9975c1def83SBjoern A. Zeeb 	u32 rtap_len = 0;
9985c1def83SBjoern A. Zeeb 
9995c1def83SBjoern A. Zeeb 	put_unaligned_le16(rx_status->he_flags1, &rtap_buf[rtap_len]);
10005c1def83SBjoern A. Zeeb 	rtap_len += 2;
10015c1def83SBjoern A. Zeeb 
10025c1def83SBjoern A. Zeeb 	put_unaligned_le16(rx_status->he_flags2, &rtap_buf[rtap_len]);
10035c1def83SBjoern A. Zeeb 	rtap_len += 2;
10045c1def83SBjoern A. Zeeb 
10055c1def83SBjoern A. Zeeb 	rtap_buf[rtap_len] = rx_status->he_RU[0];
10065c1def83SBjoern A. Zeeb 	rtap_len += 1;
10075c1def83SBjoern A. Zeeb 
10085c1def83SBjoern A. Zeeb 	rtap_buf[rtap_len] = rx_status->he_RU[1];
10095c1def83SBjoern A. Zeeb 	rtap_len += 1;
10105c1def83SBjoern A. Zeeb 
10115c1def83SBjoern A. Zeeb 	rtap_buf[rtap_len] = rx_status->he_RU[2];
10125c1def83SBjoern A. Zeeb 	rtap_len += 1;
10135c1def83SBjoern A. Zeeb 
10145c1def83SBjoern A. Zeeb 	rtap_buf[rtap_len] = rx_status->he_RU[3];
10155c1def83SBjoern A. Zeeb }
10165c1def83SBjoern A. Zeeb 
ath12k_dp_mon_update_radiotap(struct ath12k * ar,struct hal_rx_mon_ppdu_info * ppduinfo,struct sk_buff * mon_skb,struct ieee80211_rx_status * rxs)10175c1def83SBjoern A. Zeeb static void ath12k_dp_mon_update_radiotap(struct ath12k *ar,
10185c1def83SBjoern A. Zeeb 					  struct hal_rx_mon_ppdu_info *ppduinfo,
10195c1def83SBjoern A. Zeeb 					  struct sk_buff *mon_skb,
10205c1def83SBjoern A. Zeeb 					  struct ieee80211_rx_status *rxs)
10215c1def83SBjoern A. Zeeb {
10225c1def83SBjoern A. Zeeb 	struct ieee80211_supported_band *sband;
10235c1def83SBjoern A. Zeeb 	u8 *ptr = NULL;
10245c1def83SBjoern A. Zeeb 	u16 ampdu_id = ppduinfo->ampdu_id[ppduinfo->userid];
10255c1def83SBjoern A. Zeeb 
10265c1def83SBjoern A. Zeeb 	rxs->flag |= RX_FLAG_MACTIME_START;
10275c1def83SBjoern A. Zeeb 	rxs->signal = ppduinfo->rssi_comb + ATH12K_DEFAULT_NOISE_FLOOR;
10285c1def83SBjoern A. Zeeb 	rxs->nss = ppduinfo->nss + 1;
10295c1def83SBjoern A. Zeeb 
10305c1def83SBjoern A. Zeeb 	if (ampdu_id) {
10315c1def83SBjoern A. Zeeb 		rxs->flag |= RX_FLAG_AMPDU_DETAILS;
10325c1def83SBjoern A. Zeeb 		rxs->ampdu_reference = ampdu_id;
10335c1def83SBjoern A. Zeeb 	}
10345c1def83SBjoern A. Zeeb 
10355c1def83SBjoern A. Zeeb 	if (ppduinfo->he_mu_flags) {
10365c1def83SBjoern A. Zeeb 		rxs->flag |= RX_FLAG_RADIOTAP_HE_MU;
10375c1def83SBjoern A. Zeeb 		rxs->encoding = RX_ENC_HE;
10385c1def83SBjoern A. Zeeb 		ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he_mu));
10395c1def83SBjoern A. Zeeb 		ath12k_dp_mon_rx_update_radiotap_he_mu(ppduinfo, ptr);
10405c1def83SBjoern A. Zeeb 	} else if (ppduinfo->he_flags) {
10415c1def83SBjoern A. Zeeb 		rxs->flag |= RX_FLAG_RADIOTAP_HE;
10425c1def83SBjoern A. Zeeb 		rxs->encoding = RX_ENC_HE;
10435c1def83SBjoern A. Zeeb 		ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he));
10445c1def83SBjoern A. Zeeb 		ath12k_dp_mon_rx_update_radiotap_he(ppduinfo, ptr);
10455c1def83SBjoern A. Zeeb 		rxs->rate_idx = ppduinfo->rate;
10465c1def83SBjoern A. Zeeb 	} else if (ppduinfo->vht_flags) {
10475c1def83SBjoern A. Zeeb 		rxs->encoding = RX_ENC_VHT;
10485c1def83SBjoern A. Zeeb 		rxs->rate_idx = ppduinfo->rate;
10495c1def83SBjoern A. Zeeb 	} else if (ppduinfo->ht_flags) {
10505c1def83SBjoern A. Zeeb 		rxs->encoding = RX_ENC_HT;
10515c1def83SBjoern A. Zeeb 		rxs->rate_idx = ppduinfo->rate;
10525c1def83SBjoern A. Zeeb 	} else {
10535c1def83SBjoern A. Zeeb 		rxs->encoding = RX_ENC_LEGACY;
10545c1def83SBjoern A. Zeeb 		sband = &ar->mac.sbands[rxs->band];
10555c1def83SBjoern A. Zeeb 		rxs->rate_idx = ath12k_mac_hw_rate_to_idx(sband, ppduinfo->rate,
10565c1def83SBjoern A. Zeeb 							  ppduinfo->cck_flag);
10575c1def83SBjoern A. Zeeb 	}
10585c1def83SBjoern A. Zeeb 
10595c1def83SBjoern A. Zeeb 	rxs->mactime = ppduinfo->tsft;
10605c1def83SBjoern A. Zeeb }
10615c1def83SBjoern A. Zeeb 
ath12k_dp_mon_rx_deliver_msdu(struct ath12k * ar,struct napi_struct * napi,struct sk_buff * msdu,struct ieee80211_rx_status * status)10625c1def83SBjoern A. Zeeb static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi,
10635c1def83SBjoern A. Zeeb 					  struct sk_buff *msdu,
10645c1def83SBjoern A. Zeeb 					  struct ieee80211_rx_status *status)
10655c1def83SBjoern A. Zeeb {
10665c1def83SBjoern A. Zeeb 	static const struct ieee80211_radiotap_he known = {
10675c1def83SBjoern A. Zeeb 		.data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
10685c1def83SBjoern A. Zeeb 				     IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN),
10695c1def83SBjoern A. Zeeb 		.data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN),
10705c1def83SBjoern A. Zeeb 	};
10715c1def83SBjoern A. Zeeb 	struct ieee80211_rx_status *rx_status;
10725c1def83SBjoern A. Zeeb 	struct ieee80211_radiotap_he *he = NULL;
10735c1def83SBjoern A. Zeeb 	struct ieee80211_sta *pubsta = NULL;
10745c1def83SBjoern A. Zeeb 	struct ath12k_peer *peer;
10755c1def83SBjoern A. Zeeb 	struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
10765c1def83SBjoern A. Zeeb 	u8 decap = DP_RX_DECAP_TYPE_RAW;
10775c1def83SBjoern A. Zeeb 	bool is_mcbc = rxcb->is_mcbc;
10785c1def83SBjoern A. Zeeb 	bool is_eapol_tkip = rxcb->is_eapol;
10795c1def83SBjoern A. Zeeb 
10805c1def83SBjoern A. Zeeb 	if ((status->encoding == RX_ENC_HE) && !(status->flag & RX_FLAG_RADIOTAP_HE) &&
10815c1def83SBjoern A. Zeeb 	    !(status->flag & RX_FLAG_SKIP_MONITOR)) {
10825c1def83SBjoern A. Zeeb 		he = skb_push(msdu, sizeof(known));
10835c1def83SBjoern A. Zeeb 		memcpy(he, &known, sizeof(known));
10845c1def83SBjoern A. Zeeb 		status->flag |= RX_FLAG_RADIOTAP_HE;
10855c1def83SBjoern A. Zeeb 	}
10865c1def83SBjoern A. Zeeb 
10875c1def83SBjoern A. Zeeb 	if (!(status->flag & RX_FLAG_ONLY_MONITOR))
10885c1def83SBjoern A. Zeeb 		decap = ath12k_dp_rx_h_decap_type(ar->ab, rxcb->rx_desc);
10895c1def83SBjoern A. Zeeb 	spin_lock_bh(&ar->ab->base_lock);
10905c1def83SBjoern A. Zeeb 	peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu);
10915c1def83SBjoern A. Zeeb 	if (peer && peer->sta)
10925c1def83SBjoern A. Zeeb 		pubsta = peer->sta;
10935c1def83SBjoern A. Zeeb 	spin_unlock_bh(&ar->ab->base_lock);
10945c1def83SBjoern A. Zeeb 
10955c1def83SBjoern A. Zeeb 	ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
10965c1def83SBjoern A. Zeeb 		   "rx skb %pK len %u peer %pM %u %s %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",
10975c1def83SBjoern A. Zeeb 		   msdu,
10985c1def83SBjoern A. Zeeb 		   msdu->len,
10995c1def83SBjoern A. Zeeb 		   peer ? peer->addr : NULL,
11005c1def83SBjoern A. Zeeb 		   rxcb->tid,
11015c1def83SBjoern A. Zeeb 		   (is_mcbc) ? "mcast" : "ucast",
11025c1def83SBjoern A. Zeeb 		   (status->encoding == RX_ENC_LEGACY) ? "legacy" : "",
11035c1def83SBjoern A. Zeeb 		   (status->encoding == RX_ENC_HT) ? "ht" : "",
11045c1def83SBjoern A. Zeeb 		   (status->encoding == RX_ENC_VHT) ? "vht" : "",
11055c1def83SBjoern A. Zeeb 		   (status->encoding == RX_ENC_HE) ? "he" : "",
11065c1def83SBjoern A. Zeeb 		   (status->bw == RATE_INFO_BW_40) ? "40" : "",
11075c1def83SBjoern A. Zeeb 		   (status->bw == RATE_INFO_BW_80) ? "80" : "",
11085c1def83SBjoern A. Zeeb 		   (status->bw == RATE_INFO_BW_160) ? "160" : "",
11095c1def83SBjoern A. Zeeb 		   status->enc_flags & RX_ENC_FLAG_SHORT_GI ? "sgi " : "",
11105c1def83SBjoern A. Zeeb 		   status->rate_idx,
11115c1def83SBjoern A. Zeeb 		   status->nss,
11125c1def83SBjoern A. Zeeb 		   status->freq,
11135c1def83SBjoern A. Zeeb 		   status->band, status->flag,
11145c1def83SBjoern A. Zeeb 		   !!(status->flag & RX_FLAG_FAILED_FCS_CRC),
11155c1def83SBjoern A. Zeeb 		   !!(status->flag & RX_FLAG_MMIC_ERROR),
11165c1def83SBjoern A. Zeeb 		   !!(status->flag & RX_FLAG_AMSDU_MORE));
11175c1def83SBjoern A. Zeeb 
11185c1def83SBjoern A. Zeeb 	ath12k_dbg_dump(ar->ab, ATH12K_DBG_DP_RX, NULL, "dp rx msdu: ",
11195c1def83SBjoern A. Zeeb 			msdu->data, msdu->len);
11205c1def83SBjoern A. Zeeb 	rx_status = IEEE80211_SKB_RXCB(msdu);
11215c1def83SBjoern A. Zeeb 	*rx_status = *status;
11225c1def83SBjoern A. Zeeb 
11235c1def83SBjoern A. Zeeb 	/* TODO: trace rx packet */
11245c1def83SBjoern A. Zeeb 
11255c1def83SBjoern A. Zeeb 	/* PN for multicast packets are not validate in HW,
11265c1def83SBjoern A. Zeeb 	 * so skip 802.3 rx path
11275c1def83SBjoern A. Zeeb 	 * Also, fast_rx expects the STA to be authorized, hence
11285c1def83SBjoern A. Zeeb 	 * eapol packets are sent in slow path.
11295c1def83SBjoern A. Zeeb 	 */
11305c1def83SBjoern A. Zeeb 	if (decap == DP_RX_DECAP_TYPE_ETHERNET2_DIX && !is_eapol_tkip &&
11315c1def83SBjoern A. Zeeb 	    !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED))
11325c1def83SBjoern A. Zeeb 		rx_status->flag |= RX_FLAG_8023;
11335c1def83SBjoern A. Zeeb 
11345c1def83SBjoern A. Zeeb 	ieee80211_rx_napi(ar->hw, pubsta, msdu, napi);
11355c1def83SBjoern A. Zeeb }
11365c1def83SBjoern A. Zeeb 
ath12k_dp_mon_rx_deliver(struct ath12k * ar,u32 mac_id,struct sk_buff * head_msdu,struct hal_rx_mon_ppdu_info * ppduinfo,struct napi_struct * napi)11375c1def83SBjoern A. Zeeb static int ath12k_dp_mon_rx_deliver(struct ath12k *ar, u32 mac_id,
11385c1def83SBjoern A. Zeeb 				    struct sk_buff *head_msdu,
11395c1def83SBjoern A. Zeeb 				    struct hal_rx_mon_ppdu_info *ppduinfo,
11405c1def83SBjoern A. Zeeb 				    struct napi_struct *napi)
11415c1def83SBjoern A. Zeeb {
11425c1def83SBjoern A. Zeeb 	struct ath12k_pdev_dp *dp = &ar->dp;
11435c1def83SBjoern A. Zeeb 	struct sk_buff *mon_skb, *skb_next, *header;
11445c1def83SBjoern A. Zeeb 	struct ieee80211_rx_status *rxs = &dp->rx_status;
11455c1def83SBjoern A. Zeeb 	bool fcs_err = false;
11465c1def83SBjoern A. Zeeb 
11475c1def83SBjoern A. Zeeb 	mon_skb = ath12k_dp_mon_rx_merg_msdus(ar, mac_id, head_msdu,
11485c1def83SBjoern A. Zeeb 					      rxs, &fcs_err);
11495c1def83SBjoern A. Zeeb 	if (!mon_skb)
11505c1def83SBjoern A. Zeeb 		goto mon_deliver_fail;
11515c1def83SBjoern A. Zeeb 
11525c1def83SBjoern A. Zeeb 	header = mon_skb;
11535c1def83SBjoern A. Zeeb 	rxs->flag = 0;
11545c1def83SBjoern A. Zeeb 
11555c1def83SBjoern A. Zeeb 	if (fcs_err)
11565c1def83SBjoern A. Zeeb 		rxs->flag = RX_FLAG_FAILED_FCS_CRC;
11575c1def83SBjoern A. Zeeb 
11585c1def83SBjoern A. Zeeb 	do {
11595c1def83SBjoern A. Zeeb 		skb_next = mon_skb->next;
11605c1def83SBjoern A. Zeeb 		if (!skb_next)
11615c1def83SBjoern A. Zeeb 			rxs->flag &= ~RX_FLAG_AMSDU_MORE;
11625c1def83SBjoern A. Zeeb 		else
11635c1def83SBjoern A. Zeeb 			rxs->flag |= RX_FLAG_AMSDU_MORE;
11645c1def83SBjoern A. Zeeb 
11655c1def83SBjoern A. Zeeb 		if (mon_skb == header) {
11665c1def83SBjoern A. Zeeb 			header = NULL;
11675c1def83SBjoern A. Zeeb 			rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN;
11685c1def83SBjoern A. Zeeb 		} else {
11695c1def83SBjoern A. Zeeb 			rxs->flag |= RX_FLAG_ALLOW_SAME_PN;
11705c1def83SBjoern A. Zeeb 		}
11715c1def83SBjoern A. Zeeb 		rxs->flag |= RX_FLAG_ONLY_MONITOR;
11725c1def83SBjoern A. Zeeb 		ath12k_dp_mon_update_radiotap(ar, ppduinfo, mon_skb, rxs);
11735c1def83SBjoern A. Zeeb 		ath12k_dp_mon_rx_deliver_msdu(ar, napi, mon_skb, rxs);
11745c1def83SBjoern A. Zeeb 		mon_skb = skb_next;
11755c1def83SBjoern A. Zeeb 	} while (mon_skb);
11765c1def83SBjoern A. Zeeb 	rxs->flag = 0;
11775c1def83SBjoern A. Zeeb 
11785c1def83SBjoern A. Zeeb 	return 0;
11795c1def83SBjoern A. Zeeb 
11805c1def83SBjoern A. Zeeb mon_deliver_fail:
11815c1def83SBjoern A. Zeeb 	mon_skb = head_msdu;
11825c1def83SBjoern A. Zeeb 	while (mon_skb) {
11835c1def83SBjoern A. Zeeb 		skb_next = mon_skb->next;
11845c1def83SBjoern A. Zeeb 		dev_kfree_skb_any(mon_skb);
11855c1def83SBjoern A. Zeeb 		mon_skb = skb_next;
11865c1def83SBjoern A. Zeeb 	}
11875c1def83SBjoern A. Zeeb 	return -EINVAL;
11885c1def83SBjoern A. Zeeb }
11895c1def83SBjoern A. Zeeb 
11905c1def83SBjoern A. Zeeb static enum hal_rx_mon_status
ath12k_dp_mon_parse_rx_dest(struct ath12k_base * ab,struct ath12k_mon_data * pmon,struct sk_buff * skb)11915c1def83SBjoern A. Zeeb ath12k_dp_mon_parse_rx_dest(struct ath12k_base *ab, struct ath12k_mon_data *pmon,
11925c1def83SBjoern A. Zeeb 			    struct sk_buff *skb)
11935c1def83SBjoern A. Zeeb {
11945c1def83SBjoern A. Zeeb 	struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
11955c1def83SBjoern A. Zeeb 	struct hal_tlv_hdr *tlv;
11965c1def83SBjoern A. Zeeb 	enum hal_rx_mon_status hal_status;
11975c1def83SBjoern A. Zeeb 	u32 tlv_userid = 0;
11985c1def83SBjoern A. Zeeb 	u16 tlv_tag, tlv_len;
11995c1def83SBjoern A. Zeeb 	u8 *ptr = skb->data;
12005c1def83SBjoern A. Zeeb 
12015c1def83SBjoern A. Zeeb 	memset(ppdu_info, 0, sizeof(struct hal_rx_mon_ppdu_info));
12025c1def83SBjoern A. Zeeb 
12035c1def83SBjoern A. Zeeb 	do {
12045c1def83SBjoern A. Zeeb 		tlv = (struct hal_tlv_hdr *)ptr;
12055c1def83SBjoern A. Zeeb 		tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG);
12065c1def83SBjoern A. Zeeb 		tlv_len = le32_get_bits(tlv->tl, HAL_TLV_HDR_LEN);
12075c1def83SBjoern A. Zeeb 		tlv_userid = le32_get_bits(tlv->tl, HAL_TLV_USR_ID);
12085c1def83SBjoern A. Zeeb 		ptr += sizeof(*tlv);
12095c1def83SBjoern A. Zeeb 
12105c1def83SBjoern A. Zeeb 		/* The actual length of PPDU_END is the combined length of many PHY
12115c1def83SBjoern A. Zeeb 		 * TLVs that follow. Skip the TLV header and
12125c1def83SBjoern A. Zeeb 		 * rx_rxpcu_classification_overview that follows the header to get to
12135c1def83SBjoern A. Zeeb 		 * next TLV.
12145c1def83SBjoern A. Zeeb 		 */
12155c1def83SBjoern A. Zeeb 
12165c1def83SBjoern A. Zeeb 		if (tlv_tag == HAL_RX_PPDU_END)
12175c1def83SBjoern A. Zeeb 			tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview);
12185c1def83SBjoern A. Zeeb 
12195c1def83SBjoern A. Zeeb 		hal_status = ath12k_dp_mon_rx_parse_status_tlv(ab, pmon,
12205c1def83SBjoern A. Zeeb 							       tlv_tag, ptr, tlv_userid);
12215c1def83SBjoern A. Zeeb 		ptr += tlv_len;
12225c1def83SBjoern A. Zeeb 		ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN);
12235c1def83SBjoern A. Zeeb 
12245c1def83SBjoern A. Zeeb 		if ((ptr - skb->data) >= DP_RX_BUFFER_SIZE)
12255c1def83SBjoern A. Zeeb 			break;
12265c1def83SBjoern A. Zeeb 
12275c1def83SBjoern A. Zeeb 	} while (hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE);
12285c1def83SBjoern A. Zeeb 
12295c1def83SBjoern A. Zeeb 	return hal_status;
12305c1def83SBjoern A. Zeeb }
12315c1def83SBjoern A. Zeeb 
12325c1def83SBjoern A. Zeeb enum hal_rx_mon_status
ath12k_dp_mon_rx_parse_mon_status(struct ath12k * ar,struct ath12k_mon_data * pmon,int mac_id,struct sk_buff * skb,struct napi_struct * napi)12335c1def83SBjoern A. Zeeb ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,
12345c1def83SBjoern A. Zeeb 				  struct ath12k_mon_data *pmon,
12355c1def83SBjoern A. Zeeb 				  int mac_id,
12365c1def83SBjoern A. Zeeb 				  struct sk_buff *skb,
12375c1def83SBjoern A. Zeeb 				  struct napi_struct *napi)
12385c1def83SBjoern A. Zeeb {
12395c1def83SBjoern A. Zeeb 	struct ath12k_base *ab = ar->ab;
12405c1def83SBjoern A. Zeeb 	struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
12415c1def83SBjoern A. Zeeb 	struct dp_mon_mpdu *tmp;
12425c1def83SBjoern A. Zeeb 	struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;
12435c1def83SBjoern A. Zeeb 	struct sk_buff *head_msdu, *tail_msdu;
12445c1def83SBjoern A. Zeeb 	enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE;
12455c1def83SBjoern A. Zeeb 
12465c1def83SBjoern A. Zeeb 	ath12k_dp_mon_parse_rx_dest(ab, pmon, skb);
12475c1def83SBjoern A. Zeeb 
12485c1def83SBjoern A. Zeeb 	list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) {
12495c1def83SBjoern A. Zeeb 		list_del(&mon_mpdu->list);
12505c1def83SBjoern A. Zeeb 		head_msdu = mon_mpdu->head;
12515c1def83SBjoern A. Zeeb 		tail_msdu = mon_mpdu->tail;
12525c1def83SBjoern A. Zeeb 
12535c1def83SBjoern A. Zeeb 		if (head_msdu && tail_msdu) {
12545c1def83SBjoern A. Zeeb 			ath12k_dp_mon_rx_deliver(ar, mac_id, head_msdu,
12555c1def83SBjoern A. Zeeb 						 ppdu_info, napi);
12565c1def83SBjoern A. Zeeb 		}
12575c1def83SBjoern A. Zeeb 
12585c1def83SBjoern A. Zeeb 		kfree(mon_mpdu);
12595c1def83SBjoern A. Zeeb 	}
12605c1def83SBjoern A. Zeeb 	return hal_status;
12615c1def83SBjoern A. Zeeb }
12625c1def83SBjoern A. Zeeb 
ath12k_dp_mon_buf_replenish(struct ath12k_base * ab,struct dp_rxdma_ring * buf_ring,int req_entries)12635c1def83SBjoern A. Zeeb int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab,
12645c1def83SBjoern A. Zeeb 				struct dp_rxdma_ring *buf_ring,
12655c1def83SBjoern A. Zeeb 				int req_entries)
12665c1def83SBjoern A. Zeeb {
12675c1def83SBjoern A. Zeeb 	struct hal_mon_buf_ring *mon_buf;
12685c1def83SBjoern A. Zeeb 	struct sk_buff *skb;
12695c1def83SBjoern A. Zeeb 	struct hal_srng *srng;
12705c1def83SBjoern A. Zeeb 	dma_addr_t paddr;
12715c1def83SBjoern A. Zeeb 	u32 cookie;
12725c1def83SBjoern A. Zeeb 	int buf_id;
12735c1def83SBjoern A. Zeeb 
12745c1def83SBjoern A. Zeeb 	srng = &ab->hal.srng_list[buf_ring->refill_buf_ring.ring_id];
12755c1def83SBjoern A. Zeeb 	spin_lock_bh(&srng->lock);
12765c1def83SBjoern A. Zeeb 	ath12k_hal_srng_access_begin(ab, srng);
12775c1def83SBjoern A. Zeeb 
12785c1def83SBjoern A. Zeeb 	while (req_entries > 0) {
12795c1def83SBjoern A. Zeeb 		skb = dev_alloc_skb(DP_RX_BUFFER_SIZE + DP_RX_BUFFER_ALIGN_SIZE);
12805c1def83SBjoern A. Zeeb 		if (unlikely(!skb))
12815c1def83SBjoern A. Zeeb 			goto fail_alloc_skb;
12825c1def83SBjoern A. Zeeb 
12835c1def83SBjoern A. Zeeb 		if (!IS_ALIGNED((unsigned long)skb->data, DP_RX_BUFFER_ALIGN_SIZE)) {
12845c1def83SBjoern A. Zeeb 			skb_pull(skb,
12855c1def83SBjoern A. Zeeb 				 PTR_ALIGN(skb->data, DP_RX_BUFFER_ALIGN_SIZE) -
12865c1def83SBjoern A. Zeeb 				 skb->data);
12875c1def83SBjoern A. Zeeb 		}
12885c1def83SBjoern A. Zeeb 
12895c1def83SBjoern A. Zeeb 		paddr = dma_map_single(ab->dev, skb->data,
12905c1def83SBjoern A. Zeeb 				       skb->len + skb_tailroom(skb),
12915c1def83SBjoern A. Zeeb 				       DMA_FROM_DEVICE);
12925c1def83SBjoern A. Zeeb 
12935c1def83SBjoern A. Zeeb 		if (unlikely(dma_mapping_error(ab->dev, paddr)))
12945c1def83SBjoern A. Zeeb 			goto fail_free_skb;
12955c1def83SBjoern A. Zeeb 
12965c1def83SBjoern A. Zeeb 		spin_lock_bh(&buf_ring->idr_lock);
12975c1def83SBjoern A. Zeeb 		buf_id = idr_alloc(&buf_ring->bufs_idr, skb, 0,
12985c1def83SBjoern A. Zeeb 				   buf_ring->bufs_max * 3, GFP_ATOMIC);
12995c1def83SBjoern A. Zeeb 		spin_unlock_bh(&buf_ring->idr_lock);
13005c1def83SBjoern A. Zeeb 
13015c1def83SBjoern A. Zeeb 		if (unlikely(buf_id < 0))
13025c1def83SBjoern A. Zeeb 			goto fail_dma_unmap;
13035c1def83SBjoern A. Zeeb 
13045c1def83SBjoern A. Zeeb 		mon_buf = ath12k_hal_srng_src_get_next_entry(ab, srng);
13055c1def83SBjoern A. Zeeb 		if (unlikely(!mon_buf))
13065c1def83SBjoern A. Zeeb 			goto fail_idr_remove;
13075c1def83SBjoern A. Zeeb 
13085c1def83SBjoern A. Zeeb 		ATH12K_SKB_RXCB(skb)->paddr = paddr;
13095c1def83SBjoern A. Zeeb 
13105c1def83SBjoern A. Zeeb 		cookie = u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID);
13115c1def83SBjoern A. Zeeb 
13125c1def83SBjoern A. Zeeb 		mon_buf->paddr_lo = cpu_to_le32(lower_32_bits(paddr));
13135c1def83SBjoern A. Zeeb 		mon_buf->paddr_hi = cpu_to_le32(upper_32_bits(paddr));
13145c1def83SBjoern A. Zeeb 		mon_buf->cookie = cpu_to_le64(cookie);
13155c1def83SBjoern A. Zeeb 
13165c1def83SBjoern A. Zeeb 		req_entries--;
13175c1def83SBjoern A. Zeeb 	}
13185c1def83SBjoern A. Zeeb 
13195c1def83SBjoern A. Zeeb 	ath12k_hal_srng_access_end(ab, srng);
13205c1def83SBjoern A. Zeeb 	spin_unlock_bh(&srng->lock);
13215c1def83SBjoern A. Zeeb 	return 0;
13225c1def83SBjoern A. Zeeb 
13235c1def83SBjoern A. Zeeb fail_idr_remove:
13245c1def83SBjoern A. Zeeb 	spin_lock_bh(&buf_ring->idr_lock);
13255c1def83SBjoern A. Zeeb 	idr_remove(&buf_ring->bufs_idr, buf_id);
13265c1def83SBjoern A. Zeeb 	spin_unlock_bh(&buf_ring->idr_lock);
13275c1def83SBjoern A. Zeeb fail_dma_unmap:
13285c1def83SBjoern A. Zeeb 	dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb),
13295c1def83SBjoern A. Zeeb 			 DMA_FROM_DEVICE);
13305c1def83SBjoern A. Zeeb fail_free_skb:
13315c1def83SBjoern A. Zeeb 	dev_kfree_skb_any(skb);
13325c1def83SBjoern A. Zeeb fail_alloc_skb:
13335c1def83SBjoern A. Zeeb 	ath12k_hal_srng_access_end(ab, srng);
13345c1def83SBjoern A. Zeeb 	spin_unlock_bh(&srng->lock);
13355c1def83SBjoern A. Zeeb 	return -ENOMEM;
13365c1def83SBjoern A. Zeeb }
13375c1def83SBjoern A. Zeeb 
13385c1def83SBjoern A. Zeeb static struct dp_mon_tx_ppdu_info *
ath12k_dp_mon_tx_get_ppdu_info(struct ath12k_mon_data * pmon,unsigned int ppdu_id,enum dp_mon_tx_ppdu_info_type type)13395c1def83SBjoern A. Zeeb ath12k_dp_mon_tx_get_ppdu_info(struct ath12k_mon_data *pmon,
13405c1def83SBjoern A. Zeeb 			       unsigned int ppdu_id,
13415c1def83SBjoern A. Zeeb 			       enum dp_mon_tx_ppdu_info_type type)
13425c1def83SBjoern A. Zeeb {
13435c1def83SBjoern A. Zeeb 	struct dp_mon_tx_ppdu_info *tx_ppdu_info;
13445c1def83SBjoern A. Zeeb 
13455c1def83SBjoern A. Zeeb 	if (type == DP_MON_TX_PROT_PPDU_INFO) {
13465c1def83SBjoern A. Zeeb 		tx_ppdu_info = pmon->tx_prot_ppdu_info;
13475c1def83SBjoern A. Zeeb 
13485c1def83SBjoern A. Zeeb 		if (tx_ppdu_info && !tx_ppdu_info->is_used)
13495c1def83SBjoern A. Zeeb 			return tx_ppdu_info;
13505c1def83SBjoern A. Zeeb 		kfree(tx_ppdu_info);
13515c1def83SBjoern A. Zeeb 	} else {
13525c1def83SBjoern A. Zeeb 		tx_ppdu_info = pmon->tx_data_ppdu_info;
13535c1def83SBjoern A. Zeeb 
13545c1def83SBjoern A. Zeeb 		if (tx_ppdu_info && !tx_ppdu_info->is_used)
13555c1def83SBjoern A. Zeeb 			return tx_ppdu_info;
13565c1def83SBjoern A. Zeeb 		kfree(tx_ppdu_info);
13575c1def83SBjoern A. Zeeb 	}
13585c1def83SBjoern A. Zeeb 
13595c1def83SBjoern A. Zeeb 	/* allocate new tx_ppdu_info */
13605c1def83SBjoern A. Zeeb 	tx_ppdu_info = kzalloc(sizeof(*tx_ppdu_info), GFP_ATOMIC);
13615c1def83SBjoern A. Zeeb 	if (!tx_ppdu_info)
13625c1def83SBjoern A. Zeeb 		return NULL;
13635c1def83SBjoern A. Zeeb 
13645c1def83SBjoern A. Zeeb 	tx_ppdu_info->is_used = 0;
13655c1def83SBjoern A. Zeeb 	tx_ppdu_info->ppdu_id = ppdu_id;
13665c1def83SBjoern A. Zeeb 
13675c1def83SBjoern A. Zeeb 	if (type == DP_MON_TX_PROT_PPDU_INFO)
13685c1def83SBjoern A. Zeeb 		pmon->tx_prot_ppdu_info = tx_ppdu_info;
13695c1def83SBjoern A. Zeeb 	else
13705c1def83SBjoern A. Zeeb 		pmon->tx_data_ppdu_info = tx_ppdu_info;
13715c1def83SBjoern A. Zeeb 
13725c1def83SBjoern A. Zeeb 	return tx_ppdu_info;
13735c1def83SBjoern A. Zeeb }
13745c1def83SBjoern A. Zeeb 
13755c1def83SBjoern A. Zeeb static struct dp_mon_tx_ppdu_info *
ath12k_dp_mon_hal_tx_ppdu_info(struct ath12k_mon_data * pmon,u16 tlv_tag)13765c1def83SBjoern A. Zeeb ath12k_dp_mon_hal_tx_ppdu_info(struct ath12k_mon_data *pmon,
13775c1def83SBjoern A. Zeeb 			       u16 tlv_tag)
13785c1def83SBjoern A. Zeeb {
13795c1def83SBjoern A. Zeeb 	switch (tlv_tag) {
13805c1def83SBjoern A. Zeeb 	case HAL_TX_FES_SETUP:
13815c1def83SBjoern A. Zeeb 	case HAL_TX_FLUSH:
13825c1def83SBjoern A. Zeeb 	case HAL_PCU_PPDU_SETUP_INIT:
13835c1def83SBjoern A. Zeeb 	case HAL_TX_PEER_ENTRY:
13845c1def83SBjoern A. Zeeb 	case HAL_TX_QUEUE_EXTENSION:
13855c1def83SBjoern A. Zeeb 	case HAL_TX_MPDU_START:
13865c1def83SBjoern A. Zeeb 	case HAL_TX_MSDU_START:
13875c1def83SBjoern A. Zeeb 	case HAL_TX_DATA:
13885c1def83SBjoern A. Zeeb 	case HAL_MON_BUF_ADDR:
13895c1def83SBjoern A. Zeeb 	case HAL_TX_MPDU_END:
13905c1def83SBjoern A. Zeeb 	case HAL_TX_LAST_MPDU_FETCHED:
13915c1def83SBjoern A. Zeeb 	case HAL_TX_LAST_MPDU_END:
13925c1def83SBjoern A. Zeeb 	case HAL_COEX_TX_REQ:
13935c1def83SBjoern A. Zeeb 	case HAL_TX_RAW_OR_NATIVE_FRAME_SETUP:
13945c1def83SBjoern A. Zeeb 	case HAL_SCH_CRITICAL_TLV_REFERENCE:
13955c1def83SBjoern A. Zeeb 	case HAL_TX_FES_SETUP_COMPLETE:
13965c1def83SBjoern A. Zeeb 	case HAL_TQM_MPDU_GLOBAL_START:
13975c1def83SBjoern A. Zeeb 	case HAL_SCHEDULER_END:
13985c1def83SBjoern A. Zeeb 	case HAL_TX_FES_STATUS_USER_PPDU:
13995c1def83SBjoern A. Zeeb 		break;
14005c1def83SBjoern A. Zeeb 	case HAL_TX_FES_STATUS_PROT: {
14015c1def83SBjoern A. Zeeb 		if (!pmon->tx_prot_ppdu_info->is_used)
14025c1def83SBjoern A. Zeeb 			pmon->tx_prot_ppdu_info->is_used = true;
14035c1def83SBjoern A. Zeeb 
14045c1def83SBjoern A. Zeeb 		return pmon->tx_prot_ppdu_info;
14055c1def83SBjoern A. Zeeb 	}
14065c1def83SBjoern A. Zeeb 	}
14075c1def83SBjoern A. Zeeb 
14085c1def83SBjoern A. Zeeb 	if (!pmon->tx_data_ppdu_info->is_used)
14095c1def83SBjoern A. Zeeb 		pmon->tx_data_ppdu_info->is_used = true;
14105c1def83SBjoern A. Zeeb 
14115c1def83SBjoern A. Zeeb 	return pmon->tx_data_ppdu_info;
14125c1def83SBjoern A. Zeeb }
14135c1def83SBjoern A. Zeeb 
14145c1def83SBjoern A. Zeeb #define MAX_MONITOR_HEADER 512
14155c1def83SBjoern A. Zeeb #define MAX_DUMMY_FRM_BODY 128
14165c1def83SBjoern A. Zeeb 
ath12k_dp_mon_tx_alloc_skb(void)14175c1def83SBjoern A. Zeeb struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void)
14185c1def83SBjoern A. Zeeb {
14195c1def83SBjoern A. Zeeb 	struct sk_buff *skb;
14205c1def83SBjoern A. Zeeb 
14215c1def83SBjoern A. Zeeb 	skb = dev_alloc_skb(MAX_MONITOR_HEADER + MAX_DUMMY_FRM_BODY);
14225c1def83SBjoern A. Zeeb 	if (!skb)
14235c1def83SBjoern A. Zeeb 		return NULL;
14245c1def83SBjoern A. Zeeb 
14255c1def83SBjoern A. Zeeb 	skb_reserve(skb, MAX_MONITOR_HEADER);
14265c1def83SBjoern A. Zeeb 
14275c1def83SBjoern A. Zeeb 	if (!IS_ALIGNED((unsigned long)skb->data, 4))
14285c1def83SBjoern A. Zeeb 		skb_pull(skb, PTR_ALIGN(skb->data, 4) - skb->data);
14295c1def83SBjoern A. Zeeb 
14305c1def83SBjoern A. Zeeb 	return skb;
14315c1def83SBjoern A. Zeeb }
14325c1def83SBjoern A. Zeeb 
14335c1def83SBjoern A. Zeeb static int
ath12k_dp_mon_tx_gen_cts2self_frame(struct dp_mon_tx_ppdu_info * tx_ppdu_info)14345c1def83SBjoern A. Zeeb ath12k_dp_mon_tx_gen_cts2self_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)
14355c1def83SBjoern A. Zeeb {
14365c1def83SBjoern A. Zeeb 	struct sk_buff *skb;
14375c1def83SBjoern A. Zeeb 	struct ieee80211_cts *cts;
14385c1def83SBjoern A. Zeeb 
14395c1def83SBjoern A. Zeeb 	skb = ath12k_dp_mon_tx_alloc_skb();
14405c1def83SBjoern A. Zeeb 	if (!skb)
14415c1def83SBjoern A. Zeeb 		return -ENOMEM;
14425c1def83SBjoern A. Zeeb 
14435c1def83SBjoern A. Zeeb 	cts = (struct ieee80211_cts *)skb->data;
14445c1def83SBjoern A. Zeeb 	memset(cts, 0, MAX_DUMMY_FRM_BODY);
14455c1def83SBjoern A. Zeeb 	cts->frame_control =
14465c1def83SBjoern A. Zeeb 		cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
14475c1def83SBjoern A. Zeeb 	cts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration);
14485c1def83SBjoern A. Zeeb 	memcpy(cts->ra, tx_ppdu_info->rx_status.addr1, sizeof(cts->ra));
14495c1def83SBjoern A. Zeeb 
14505c1def83SBjoern A. Zeeb 	skb_put(skb, sizeof(*cts));
14515c1def83SBjoern A. Zeeb 	tx_ppdu_info->tx_mon_mpdu->head = skb;
14525c1def83SBjoern A. Zeeb 	tx_ppdu_info->tx_mon_mpdu->tail = NULL;
14535c1def83SBjoern A. Zeeb 	list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,
14545c1def83SBjoern A. Zeeb 		      &tx_ppdu_info->dp_tx_mon_mpdu_list);
14555c1def83SBjoern A. Zeeb 
14565c1def83SBjoern A. Zeeb 	return 0;
14575c1def83SBjoern A. Zeeb }
14585c1def83SBjoern A. Zeeb 
14595c1def83SBjoern A. Zeeb static int
ath12k_dp_mon_tx_gen_rts_frame(struct dp_mon_tx_ppdu_info * tx_ppdu_info)14605c1def83SBjoern A. Zeeb ath12k_dp_mon_tx_gen_rts_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)
14615c1def83SBjoern A. Zeeb {
14625c1def83SBjoern A. Zeeb 	struct sk_buff *skb;
14635c1def83SBjoern A. Zeeb 	struct ieee80211_rts *rts;
14645c1def83SBjoern A. Zeeb 
14655c1def83SBjoern A. Zeeb 	skb = ath12k_dp_mon_tx_alloc_skb();
14665c1def83SBjoern A. Zeeb 	if (!skb)
14675c1def83SBjoern A. Zeeb 		return -ENOMEM;
14685c1def83SBjoern A. Zeeb 
14695c1def83SBjoern A. Zeeb 	rts = (struct ieee80211_rts *)skb->data;
14705c1def83SBjoern A. Zeeb 	memset(rts, 0, MAX_DUMMY_FRM_BODY);
14715c1def83SBjoern A. Zeeb 	rts->frame_control =
14725c1def83SBjoern A. Zeeb 		cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
14735c1def83SBjoern A. Zeeb 	rts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration);
14745c1def83SBjoern A. Zeeb 	memcpy(rts->ra, tx_ppdu_info->rx_status.addr1, sizeof(rts->ra));
14755c1def83SBjoern A. Zeeb 	memcpy(rts->ta, tx_ppdu_info->rx_status.addr2, sizeof(rts->ta));
14765c1def83SBjoern A. Zeeb 
14775c1def83SBjoern A. Zeeb 	skb_put(skb, sizeof(*rts));
14785c1def83SBjoern A. Zeeb 	tx_ppdu_info->tx_mon_mpdu->head = skb;
14795c1def83SBjoern A. Zeeb 	tx_ppdu_info->tx_mon_mpdu->tail = NULL;
14805c1def83SBjoern A. Zeeb 	list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,
14815c1def83SBjoern A. Zeeb 		      &tx_ppdu_info->dp_tx_mon_mpdu_list);
14825c1def83SBjoern A. Zeeb 
14835c1def83SBjoern A. Zeeb 	return 0;
14845c1def83SBjoern A. Zeeb }
14855c1def83SBjoern A. Zeeb 
14865c1def83SBjoern A. Zeeb static int
ath12k_dp_mon_tx_gen_3addr_qos_null_frame(struct dp_mon_tx_ppdu_info * tx_ppdu_info)14875c1def83SBjoern A. Zeeb ath12k_dp_mon_tx_gen_3addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)
14885c1def83SBjoern A. Zeeb {
14895c1def83SBjoern A. Zeeb 	struct sk_buff *skb;
14905c1def83SBjoern A. Zeeb 	struct ieee80211_qos_hdr *qhdr;
14915c1def83SBjoern A. Zeeb 
14925c1def83SBjoern A. Zeeb 	skb = ath12k_dp_mon_tx_alloc_skb();
14935c1def83SBjoern A. Zeeb 	if (!skb)
14945c1def83SBjoern A. Zeeb 		return -ENOMEM;
14955c1def83SBjoern A. Zeeb 
14965c1def83SBjoern A. Zeeb 	qhdr = (struct ieee80211_qos_hdr *)skb->data;
14975c1def83SBjoern A. Zeeb 	memset(qhdr, 0, MAX_DUMMY_FRM_BODY);
14985c1def83SBjoern A. Zeeb 	qhdr->frame_control =
14995c1def83SBjoern A. Zeeb 		cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC);
15005c1def83SBjoern A. Zeeb 	qhdr->duration_id = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration);
15015c1def83SBjoern A. Zeeb 	memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN);
15025c1def83SBjoern A. Zeeb 	memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN);
15035c1def83SBjoern A. Zeeb 	memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN);
15045c1def83SBjoern A. Zeeb 
15055c1def83SBjoern A. Zeeb 	skb_put(skb, sizeof(*qhdr));
15065c1def83SBjoern A. Zeeb 	tx_ppdu_info->tx_mon_mpdu->head = skb;
15075c1def83SBjoern A. Zeeb 	tx_ppdu_info->tx_mon_mpdu->tail = NULL;
15085c1def83SBjoern A. Zeeb 	list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,
15095c1def83SBjoern A. Zeeb 		      &tx_ppdu_info->dp_tx_mon_mpdu_list);
15105c1def83SBjoern A. Zeeb 
15115c1def83SBjoern A. Zeeb 	return 0;
15125c1def83SBjoern A. Zeeb }
15135c1def83SBjoern A. Zeeb 
15145c1def83SBjoern A. Zeeb static int
ath12k_dp_mon_tx_gen_4addr_qos_null_frame(struct dp_mon_tx_ppdu_info * tx_ppdu_info)15155c1def83SBjoern A. Zeeb ath12k_dp_mon_tx_gen_4addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)
15165c1def83SBjoern A. Zeeb {
15175c1def83SBjoern A. Zeeb 	struct sk_buff *skb;
15185c1def83SBjoern A. Zeeb 	struct dp_mon_qosframe_addr4 *qhdr;
15195c1def83SBjoern A. Zeeb 
15205c1def83SBjoern A. Zeeb 	skb = ath12k_dp_mon_tx_alloc_skb();
15215c1def83SBjoern A. Zeeb 	if (!skb)
15225c1def83SBjoern A. Zeeb 		return -ENOMEM;
15235c1def83SBjoern A. Zeeb 
15245c1def83SBjoern A. Zeeb 	qhdr = (struct dp_mon_qosframe_addr4 *)skb->data;
15255c1def83SBjoern A. Zeeb 	memset(qhdr, 0, MAX_DUMMY_FRM_BODY);
15265c1def83SBjoern A. Zeeb 	qhdr->frame_control =
15275c1def83SBjoern A. Zeeb 		cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC);
15285c1def83SBjoern A. Zeeb 	qhdr->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration);
15295c1def83SBjoern A. Zeeb 	memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN);
15305c1def83SBjoern A. Zeeb 	memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN);
15315c1def83SBjoern A. Zeeb 	memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN);
15325c1def83SBjoern A. Zeeb 	memcpy(qhdr->addr4, tx_ppdu_info->rx_status.addr4, ETH_ALEN);
15335c1def83SBjoern A. Zeeb 
15345c1def83SBjoern A. Zeeb 	skb_put(skb, sizeof(*qhdr));
15355c1def83SBjoern A. Zeeb 	tx_ppdu_info->tx_mon_mpdu->head = skb;
15365c1def83SBjoern A. Zeeb 	tx_ppdu_info->tx_mon_mpdu->tail = NULL;
15375c1def83SBjoern A. Zeeb 	list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,
15385c1def83SBjoern A. Zeeb 		      &tx_ppdu_info->dp_tx_mon_mpdu_list);
15395c1def83SBjoern A. Zeeb 
15405c1def83SBjoern A. Zeeb 	return 0;
15415c1def83SBjoern A. Zeeb }
15425c1def83SBjoern A. Zeeb 
15435c1def83SBjoern A. Zeeb static int
ath12k_dp_mon_tx_gen_ack_frame(struct dp_mon_tx_ppdu_info * tx_ppdu_info)15445c1def83SBjoern A. Zeeb ath12k_dp_mon_tx_gen_ack_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)
15455c1def83SBjoern A. Zeeb {
15465c1def83SBjoern A. Zeeb 	struct sk_buff *skb;
15475c1def83SBjoern A. Zeeb 	struct dp_mon_frame_min_one *fbmhdr;
15485c1def83SBjoern A. Zeeb 
15495c1def83SBjoern A. Zeeb 	skb = ath12k_dp_mon_tx_alloc_skb();
15505c1def83SBjoern A. Zeeb 	if (!skb)
15515c1def83SBjoern A. Zeeb 		return -ENOMEM;
15525c1def83SBjoern A. Zeeb 
15535c1def83SBjoern A. Zeeb 	fbmhdr = (struct dp_mon_frame_min_one *)skb->data;
15545c1def83SBjoern A. Zeeb 	memset(fbmhdr, 0, MAX_DUMMY_FRM_BODY);
15555c1def83SBjoern A. Zeeb 	fbmhdr->frame_control =
15565c1def83SBjoern A. Zeeb 		cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_CFACK);
15575c1def83SBjoern A. Zeeb 	memcpy(fbmhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN);
15585c1def83SBjoern A. Zeeb 
15595c1def83SBjoern A. Zeeb 	/* set duration zero for ack frame */
15605c1def83SBjoern A. Zeeb 	fbmhdr->duration = 0;
15615c1def83SBjoern A. Zeeb 
15625c1def83SBjoern A. Zeeb 	skb_put(skb, sizeof(*fbmhdr));
15635c1def83SBjoern A. Zeeb 	tx_ppdu_info->tx_mon_mpdu->head = skb;
15645c1def83SBjoern A. Zeeb 	tx_ppdu_info->tx_mon_mpdu->tail = NULL;
15655c1def83SBjoern A. Zeeb 	list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,
15665c1def83SBjoern A. Zeeb 		      &tx_ppdu_info->dp_tx_mon_mpdu_list);
15675c1def83SBjoern A. Zeeb 
15685c1def83SBjoern A. Zeeb 	return 0;
15695c1def83SBjoern A. Zeeb }
15705c1def83SBjoern A. Zeeb 
15715c1def83SBjoern A. Zeeb static int
ath12k_dp_mon_tx_gen_prot_frame(struct dp_mon_tx_ppdu_info * tx_ppdu_info)15725c1def83SBjoern A. Zeeb ath12k_dp_mon_tx_gen_prot_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)
15735c1def83SBjoern A. Zeeb {
15745c1def83SBjoern A. Zeeb 	int ret = 0;
15755c1def83SBjoern A. Zeeb 
15765c1def83SBjoern A. Zeeb 	switch (tx_ppdu_info->rx_status.medium_prot_type) {
15775c1def83SBjoern A. Zeeb 	case DP_MON_TX_MEDIUM_RTS_LEGACY:
15785c1def83SBjoern A. Zeeb 	case DP_MON_TX_MEDIUM_RTS_11AC_STATIC_BW:
15795c1def83SBjoern A. Zeeb 	case DP_MON_TX_MEDIUM_RTS_11AC_DYNAMIC_BW:
15805c1def83SBjoern A. Zeeb 		ret = ath12k_dp_mon_tx_gen_rts_frame(tx_ppdu_info);
15815c1def83SBjoern A. Zeeb 		break;
15825c1def83SBjoern A. Zeeb 	case DP_MON_TX_MEDIUM_CTS2SELF:
15835c1def83SBjoern A. Zeeb 		ret = ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info);
15845c1def83SBjoern A. Zeeb 		break;
15855c1def83SBjoern A. Zeeb 	case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_3ADDR:
15865c1def83SBjoern A. Zeeb 		ret = ath12k_dp_mon_tx_gen_3addr_qos_null_frame(tx_ppdu_info);
15875c1def83SBjoern A. Zeeb 		break;
15885c1def83SBjoern A. Zeeb 	case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_4ADDR:
15895c1def83SBjoern A. Zeeb 		ret = ath12k_dp_mon_tx_gen_4addr_qos_null_frame(tx_ppdu_info);
15905c1def83SBjoern A. Zeeb 		break;
15915c1def83SBjoern A. Zeeb 	}
15925c1def83SBjoern A. Zeeb 
15935c1def83SBjoern A. Zeeb 	return ret;
15945c1def83SBjoern A. Zeeb }
15955c1def83SBjoern A. Zeeb 
15965c1def83SBjoern A. Zeeb static enum dp_mon_tx_tlv_status
ath12k_dp_mon_tx_parse_status_tlv(struct ath12k_base * ab,struct ath12k_mon_data * pmon,u16 tlv_tag,u8 * tlv_data,u32 userid)15975c1def83SBjoern A. Zeeb ath12k_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab,
15985c1def83SBjoern A. Zeeb 				  struct ath12k_mon_data *pmon,
15995c1def83SBjoern A. Zeeb 				  u16 tlv_tag, u8 *tlv_data, u32 userid)
16005c1def83SBjoern A. Zeeb {
16015c1def83SBjoern A. Zeeb 	struct dp_mon_tx_ppdu_info *tx_ppdu_info;
16025c1def83SBjoern A. Zeeb 	enum dp_mon_tx_tlv_status status = DP_MON_TX_STATUS_PPDU_NOT_DONE;
16035c1def83SBjoern A. Zeeb 	u32 info[7];
16045c1def83SBjoern A. Zeeb 
16055c1def83SBjoern A. Zeeb 	tx_ppdu_info = ath12k_dp_mon_hal_tx_ppdu_info(pmon, tlv_tag);
16065c1def83SBjoern A. Zeeb 
16075c1def83SBjoern A. Zeeb 	switch (tlv_tag) {
16085c1def83SBjoern A. Zeeb 	case HAL_TX_FES_SETUP: {
16095c1def83SBjoern A. Zeeb 		struct hal_tx_fes_setup *tx_fes_setup =
16105c1def83SBjoern A. Zeeb 					(struct hal_tx_fes_setup *)tlv_data;
16115c1def83SBjoern A. Zeeb 
16125c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(tx_fes_setup->info0);
16135c1def83SBjoern A. Zeeb 		tx_ppdu_info->ppdu_id = __le32_to_cpu(tx_fes_setup->schedule_id);
16145c1def83SBjoern A. Zeeb 		tx_ppdu_info->num_users =
16155c1def83SBjoern A. Zeeb 			u32_get_bits(info[0], HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS);
16165c1def83SBjoern A. Zeeb 		status = DP_MON_TX_FES_SETUP;
16175c1def83SBjoern A. Zeeb 		break;
16185c1def83SBjoern A. Zeeb 	}
16195c1def83SBjoern A. Zeeb 
16205c1def83SBjoern A. Zeeb 	case HAL_TX_FES_STATUS_END: {
16215c1def83SBjoern A. Zeeb 		struct hal_tx_fes_status_end *tx_fes_status_end =
16225c1def83SBjoern A. Zeeb 			(struct hal_tx_fes_status_end *)tlv_data;
16235c1def83SBjoern A. Zeeb 		u32 tst_15_0, tst_31_16;
16245c1def83SBjoern A. Zeeb 
16255c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(tx_fes_status_end->info0);
16265c1def83SBjoern A. Zeeb 		tst_15_0 =
16275c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
16285c1def83SBjoern A. Zeeb 				     HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_15_0);
16295c1def83SBjoern A. Zeeb 		tst_31_16 =
16305c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
16315c1def83SBjoern A. Zeeb 				     HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_31_16);
16325c1def83SBjoern A. Zeeb 
16335c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.ppdu_ts = (tst_15_0 | (tst_31_16 << 16));
16345c1def83SBjoern A. Zeeb 		status = DP_MON_TX_FES_STATUS_END;
16355c1def83SBjoern A. Zeeb 		break;
16365c1def83SBjoern A. Zeeb 	}
16375c1def83SBjoern A. Zeeb 
16385c1def83SBjoern A. Zeeb 	case HAL_RX_RESPONSE_REQUIRED_INFO: {
16395c1def83SBjoern A. Zeeb 		struct hal_rx_resp_req_info *rx_resp_req_info =
16405c1def83SBjoern A. Zeeb 			(struct hal_rx_resp_req_info *)tlv_data;
16415c1def83SBjoern A. Zeeb 		u32 addr_32;
16425c1def83SBjoern A. Zeeb 		u16 addr_16;
16435c1def83SBjoern A. Zeeb 
16445c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(rx_resp_req_info->info0);
16455c1def83SBjoern A. Zeeb 		info[1] = __le32_to_cpu(rx_resp_req_info->info1);
16465c1def83SBjoern A. Zeeb 		info[2] = __le32_to_cpu(rx_resp_req_info->info2);
16475c1def83SBjoern A. Zeeb 		info[3] = __le32_to_cpu(rx_resp_req_info->info3);
16485c1def83SBjoern A. Zeeb 		info[4] = __le32_to_cpu(rx_resp_req_info->info4);
16495c1def83SBjoern A. Zeeb 		info[5] = __le32_to_cpu(rx_resp_req_info->info5);
16505c1def83SBjoern A. Zeeb 
16515c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.ppdu_id =
16525c1def83SBjoern A. Zeeb 			u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_PPDU_ID);
16535c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.reception_type =
16545c1def83SBjoern A. Zeeb 			u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_RECEPTION_TYPE);
16555c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.rx_duration =
16565c1def83SBjoern A. Zeeb 			u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_DURATION);
16575c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.mcs =
16585c1def83SBjoern A. Zeeb 			u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_RATE_MCS);
16595c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.sgi =
16605c1def83SBjoern A. Zeeb 			u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_SGI);
16615c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.is_stbc =
16625c1def83SBjoern A. Zeeb 			u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_STBC);
16635c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.ldpc =
16645c1def83SBjoern A. Zeeb 			u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_LDPC);
16655c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.is_ampdu =
16665c1def83SBjoern A. Zeeb 			u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_IS_AMPDU);
16675c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.num_users =
16685c1def83SBjoern A. Zeeb 			u32_get_bits(info[2], HAL_RX_RESP_REQ_INFO2_NUM_USER);
16695c1def83SBjoern A. Zeeb 
16705c1def83SBjoern A. Zeeb 		addr_32 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO3_ADDR1_31_0);
16715c1def83SBjoern A. Zeeb 		addr_16 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO4_ADDR1_47_32);
16725c1def83SBjoern A. Zeeb 		ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1);
16735c1def83SBjoern A. Zeeb 
16745c1def83SBjoern A. Zeeb 		addr_16 = u32_get_bits(info[4], HAL_RX_RESP_REQ_INFO4_ADDR1_15_0);
16755c1def83SBjoern A. Zeeb 		addr_32 = u32_get_bits(info[5], HAL_RX_RESP_REQ_INFO5_ADDR1_47_16);
16765c1def83SBjoern A. Zeeb 		ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2);
16775c1def83SBjoern A. Zeeb 
16785c1def83SBjoern A. Zeeb 		if (tx_ppdu_info->rx_status.reception_type == 0)
16795c1def83SBjoern A. Zeeb 			ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info);
16805c1def83SBjoern A. Zeeb 		status = DP_MON_RX_RESPONSE_REQUIRED_INFO;
16815c1def83SBjoern A. Zeeb 		break;
16825c1def83SBjoern A. Zeeb 	}
16835c1def83SBjoern A. Zeeb 
16845c1def83SBjoern A. Zeeb 	case HAL_PCU_PPDU_SETUP_INIT: {
16855c1def83SBjoern A. Zeeb 		struct hal_tx_pcu_ppdu_setup_init *ppdu_setup =
16865c1def83SBjoern A. Zeeb 			(struct hal_tx_pcu_ppdu_setup_init *)tlv_data;
16875c1def83SBjoern A. Zeeb 		u32 addr_32;
16885c1def83SBjoern A. Zeeb 		u16 addr_16;
16895c1def83SBjoern A. Zeeb 
16905c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(ppdu_setup->info0);
16915c1def83SBjoern A. Zeeb 		info[1] = __le32_to_cpu(ppdu_setup->info1);
16925c1def83SBjoern A. Zeeb 		info[2] = __le32_to_cpu(ppdu_setup->info2);
16935c1def83SBjoern A. Zeeb 		info[3] = __le32_to_cpu(ppdu_setup->info3);
16945c1def83SBjoern A. Zeeb 		info[4] = __le32_to_cpu(ppdu_setup->info4);
16955c1def83SBjoern A. Zeeb 		info[5] = __le32_to_cpu(ppdu_setup->info5);
16965c1def83SBjoern A. Zeeb 		info[6] = __le32_to_cpu(ppdu_setup->info6);
16975c1def83SBjoern A. Zeeb 
16985c1def83SBjoern A. Zeeb 		/* protection frame address 1 */
16995c1def83SBjoern A. Zeeb 		addr_32 = u32_get_bits(info[1],
17005c1def83SBjoern A. Zeeb 				       HAL_TX_PPDU_SETUP_INFO1_PROT_FRAME_ADDR1_31_0);
17015c1def83SBjoern A. Zeeb 		addr_16 = u32_get_bits(info[2],
17025c1def83SBjoern A. Zeeb 				       HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR1_47_32);
17035c1def83SBjoern A. Zeeb 		ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1);
17045c1def83SBjoern A. Zeeb 
17055c1def83SBjoern A. Zeeb 		/* protection frame address 2 */
17065c1def83SBjoern A. Zeeb 		addr_16 = u32_get_bits(info[2],
17075c1def83SBjoern A. Zeeb 				       HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR2_15_0);
17085c1def83SBjoern A. Zeeb 		addr_32 = u32_get_bits(info[3],
17095c1def83SBjoern A. Zeeb 				       HAL_TX_PPDU_SETUP_INFO3_PROT_FRAME_ADDR2_47_16);
17105c1def83SBjoern A. Zeeb 		ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2);
17115c1def83SBjoern A. Zeeb 
17125c1def83SBjoern A. Zeeb 		/* protection frame address 3 */
17135c1def83SBjoern A. Zeeb 		addr_32 = u32_get_bits(info[4],
17145c1def83SBjoern A. Zeeb 				       HAL_TX_PPDU_SETUP_INFO4_PROT_FRAME_ADDR3_31_0);
17155c1def83SBjoern A. Zeeb 		addr_16 = u32_get_bits(info[5],
17165c1def83SBjoern A. Zeeb 				       HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR3_47_32);
17175c1def83SBjoern A. Zeeb 		ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr3);
17185c1def83SBjoern A. Zeeb 
17195c1def83SBjoern A. Zeeb 		/* protection frame address 4 */
17205c1def83SBjoern A. Zeeb 		addr_16 = u32_get_bits(info[5],
17215c1def83SBjoern A. Zeeb 				       HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR4_15_0);
17225c1def83SBjoern A. Zeeb 		addr_32 = u32_get_bits(info[6],
17235c1def83SBjoern A. Zeeb 				       HAL_TX_PPDU_SETUP_INFO6_PROT_FRAME_ADDR4_47_16);
17245c1def83SBjoern A. Zeeb 		ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr4);
17255c1def83SBjoern A. Zeeb 
17265c1def83SBjoern A. Zeeb 		status = u32_get_bits(info[0],
17275c1def83SBjoern A. Zeeb 				      HAL_TX_PPDU_SETUP_INFO0_MEDIUM_PROT_TYPE);
17285c1def83SBjoern A. Zeeb 		break;
17295c1def83SBjoern A. Zeeb 	}
17305c1def83SBjoern A. Zeeb 
17315c1def83SBjoern A. Zeeb 	case HAL_TX_QUEUE_EXTENSION: {
17325c1def83SBjoern A. Zeeb 		struct hal_tx_queue_exten *tx_q_exten =
17335c1def83SBjoern A. Zeeb 			(struct hal_tx_queue_exten *)tlv_data;
17345c1def83SBjoern A. Zeeb 
17355c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(tx_q_exten->info0);
17365c1def83SBjoern A. Zeeb 
17375c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.frame_control =
17385c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
17395c1def83SBjoern A. Zeeb 				     HAL_TX_Q_EXT_INFO0_FRAME_CTRL);
17405c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.fc_valid = true;
17415c1def83SBjoern A. Zeeb 		break;
17425c1def83SBjoern A. Zeeb 	}
17435c1def83SBjoern A. Zeeb 
17445c1def83SBjoern A. Zeeb 	case HAL_TX_FES_STATUS_START: {
17455c1def83SBjoern A. Zeeb 		struct hal_tx_fes_status_start *tx_fes_start =
17465c1def83SBjoern A. Zeeb 			(struct hal_tx_fes_status_start *)tlv_data;
17475c1def83SBjoern A. Zeeb 
17485c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(tx_fes_start->info0);
17495c1def83SBjoern A. Zeeb 
17505c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.medium_prot_type =
17515c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
17525c1def83SBjoern A. Zeeb 				     HAL_TX_FES_STATUS_START_INFO0_MEDIUM_PROT_TYPE);
17535c1def83SBjoern A. Zeeb 		break;
17545c1def83SBjoern A. Zeeb 	}
17555c1def83SBjoern A. Zeeb 
17565c1def83SBjoern A. Zeeb 	case HAL_TX_FES_STATUS_PROT: {
17575c1def83SBjoern A. Zeeb 		struct hal_tx_fes_status_prot *tx_fes_status =
17585c1def83SBjoern A. Zeeb 			(struct hal_tx_fes_status_prot *)tlv_data;
17595c1def83SBjoern A. Zeeb 		u32 start_timestamp;
17605c1def83SBjoern A. Zeeb 		u32 end_timestamp;
17615c1def83SBjoern A. Zeeb 
17625c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(tx_fes_status->info0);
17635c1def83SBjoern A. Zeeb 		info[1] = __le32_to_cpu(tx_fes_status->info1);
17645c1def83SBjoern A. Zeeb 
17655c1def83SBjoern A. Zeeb 		start_timestamp =
17665c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
17675c1def83SBjoern A. Zeeb 				     HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_15_0);
17685c1def83SBjoern A. Zeeb 		start_timestamp |=
17695c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
17705c1def83SBjoern A. Zeeb 				     HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_31_16) << 15;
17715c1def83SBjoern A. Zeeb 		end_timestamp =
17725c1def83SBjoern A. Zeeb 			u32_get_bits(info[1],
17735c1def83SBjoern A. Zeeb 				     HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_15_0);
17745c1def83SBjoern A. Zeeb 		end_timestamp |=
17755c1def83SBjoern A. Zeeb 			u32_get_bits(info[1],
17765c1def83SBjoern A. Zeeb 				     HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_31_16) << 15;
17775c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.rx_duration = end_timestamp - start_timestamp;
17785c1def83SBjoern A. Zeeb 
17795c1def83SBjoern A. Zeeb 		ath12k_dp_mon_tx_gen_prot_frame(tx_ppdu_info);
17805c1def83SBjoern A. Zeeb 		break;
17815c1def83SBjoern A. Zeeb 	}
17825c1def83SBjoern A. Zeeb 
17835c1def83SBjoern A. Zeeb 	case HAL_TX_FES_STATUS_START_PPDU:
17845c1def83SBjoern A. Zeeb 	case HAL_TX_FES_STATUS_START_PROT: {
17855c1def83SBjoern A. Zeeb 		struct hal_tx_fes_status_start_prot *tx_fes_stat_start =
17865c1def83SBjoern A. Zeeb 			(struct hal_tx_fes_status_start_prot *)tlv_data;
17875c1def83SBjoern A. Zeeb 		u64 ppdu_ts;
17885c1def83SBjoern A. Zeeb 
17895c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(tx_fes_stat_start->info0);
17905c1def83SBjoern A. Zeeb 
17915c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.ppdu_ts =
17925c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
17935c1def83SBjoern A. Zeeb 				     HAL_TX_FES_STAT_STRT_INFO0_PROT_TS_LOWER_32);
17945c1def83SBjoern A. Zeeb 		ppdu_ts = (u32_get_bits(info[1],
17955c1def83SBjoern A. Zeeb 					HAL_TX_FES_STAT_STRT_INFO1_PROT_TS_UPPER_32));
17965c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.ppdu_ts |= ppdu_ts << 32;
17975c1def83SBjoern A. Zeeb 		break;
17985c1def83SBjoern A. Zeeb 	}
17995c1def83SBjoern A. Zeeb 
18005c1def83SBjoern A. Zeeb 	case HAL_TX_FES_STATUS_USER_PPDU: {
18015c1def83SBjoern A. Zeeb 		struct hal_tx_fes_status_user_ppdu *tx_fes_usr_ppdu =
18025c1def83SBjoern A. Zeeb 			(struct hal_tx_fes_status_user_ppdu *)tlv_data;
18035c1def83SBjoern A. Zeeb 
18045c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(tx_fes_usr_ppdu->info0);
18055c1def83SBjoern A. Zeeb 
18065c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.rx_duration =
18075c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
18085c1def83SBjoern A. Zeeb 				     HAL_TX_FES_STAT_USR_PPDU_INFO0_DURATION);
18095c1def83SBjoern A. Zeeb 		break;
18105c1def83SBjoern A. Zeeb 	}
18115c1def83SBjoern A. Zeeb 
18125c1def83SBjoern A. Zeeb 	case HAL_MACTX_HE_SIG_A_SU:
18135c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_he_sig_su(tlv_data, &tx_ppdu_info->rx_status);
18145c1def83SBjoern A. Zeeb 		break;
18155c1def83SBjoern A. Zeeb 
18165c1def83SBjoern A. Zeeb 	case HAL_MACTX_HE_SIG_A_MU_DL:
18175c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status);
18185c1def83SBjoern A. Zeeb 		break;
18195c1def83SBjoern A. Zeeb 
18205c1def83SBjoern A. Zeeb 	case HAL_MACTX_HE_SIG_B1_MU:
18215c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, &tx_ppdu_info->rx_status);
18225c1def83SBjoern A. Zeeb 		break;
18235c1def83SBjoern A. Zeeb 
18245c1def83SBjoern A. Zeeb 	case HAL_MACTX_HE_SIG_B2_MU:
18255c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, &tx_ppdu_info->rx_status);
18265c1def83SBjoern A. Zeeb 		break;
18275c1def83SBjoern A. Zeeb 
18285c1def83SBjoern A. Zeeb 	case HAL_MACTX_HE_SIG_B2_OFDMA:
18295c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, &tx_ppdu_info->rx_status);
18305c1def83SBjoern A. Zeeb 		break;
18315c1def83SBjoern A. Zeeb 
18325c1def83SBjoern A. Zeeb 	case HAL_MACTX_VHT_SIG_A:
18335c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status);
18345c1def83SBjoern A. Zeeb 		break;
18355c1def83SBjoern A. Zeeb 
18365c1def83SBjoern A. Zeeb 	case HAL_MACTX_L_SIG_A:
18375c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status);
18385c1def83SBjoern A. Zeeb 		break;
18395c1def83SBjoern A. Zeeb 
18405c1def83SBjoern A. Zeeb 	case HAL_MACTX_L_SIG_B:
18415c1def83SBjoern A. Zeeb 		ath12k_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status);
18425c1def83SBjoern A. Zeeb 		break;
18435c1def83SBjoern A. Zeeb 
18445c1def83SBjoern A. Zeeb 	case HAL_RX_FRAME_BITMAP_ACK: {
18455c1def83SBjoern A. Zeeb 		struct hal_rx_frame_bitmap_ack *fbm_ack =
18465c1def83SBjoern A. Zeeb 			(struct hal_rx_frame_bitmap_ack *)tlv_data;
18475c1def83SBjoern A. Zeeb 		u32 addr_32;
18485c1def83SBjoern A. Zeeb 		u16 addr_16;
18495c1def83SBjoern A. Zeeb 
18505c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(fbm_ack->info0);
18515c1def83SBjoern A. Zeeb 		info[1] = __le32_to_cpu(fbm_ack->info1);
18525c1def83SBjoern A. Zeeb 
18535c1def83SBjoern A. Zeeb 		addr_32 = u32_get_bits(info[0],
18545c1def83SBjoern A. Zeeb 				       HAL_RX_FBM_ACK_INFO0_ADDR1_31_0);
18555c1def83SBjoern A. Zeeb 		addr_16 = u32_get_bits(info[1],
18565c1def83SBjoern A. Zeeb 				       HAL_RX_FBM_ACK_INFO1_ADDR1_47_32);
18575c1def83SBjoern A. Zeeb 		ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1);
18585c1def83SBjoern A. Zeeb 
18595c1def83SBjoern A. Zeeb 		ath12k_dp_mon_tx_gen_ack_frame(tx_ppdu_info);
18605c1def83SBjoern A. Zeeb 		break;
18615c1def83SBjoern A. Zeeb 	}
18625c1def83SBjoern A. Zeeb 
18635c1def83SBjoern A. Zeeb 	case HAL_MACTX_PHY_DESC: {
18645c1def83SBjoern A. Zeeb 		struct hal_tx_phy_desc *tx_phy_desc =
18655c1def83SBjoern A. Zeeb 			(struct hal_tx_phy_desc *)tlv_data;
18665c1def83SBjoern A. Zeeb 
18675c1def83SBjoern A. Zeeb 		info[0] = __le32_to_cpu(tx_phy_desc->info0);
18685c1def83SBjoern A. Zeeb 		info[1] = __le32_to_cpu(tx_phy_desc->info1);
18695c1def83SBjoern A. Zeeb 		info[2] = __le32_to_cpu(tx_phy_desc->info2);
18705c1def83SBjoern A. Zeeb 		info[3] = __le32_to_cpu(tx_phy_desc->info3);
18715c1def83SBjoern A. Zeeb 
18725c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.beamformed =
18735c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
18745c1def83SBjoern A. Zeeb 				     HAL_TX_PHY_DESC_INFO0_BF_TYPE);
18755c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.preamble_type =
18765c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
18775c1def83SBjoern A. Zeeb 				     HAL_TX_PHY_DESC_INFO0_PREAMBLE_11B);
18785c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.mcs =
18795c1def83SBjoern A. Zeeb 			u32_get_bits(info[1],
18805c1def83SBjoern A. Zeeb 				     HAL_TX_PHY_DESC_INFO1_MCS);
18815c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.ltf_size =
18825c1def83SBjoern A. Zeeb 			u32_get_bits(info[3],
18835c1def83SBjoern A. Zeeb 				     HAL_TX_PHY_DESC_INFO3_LTF_SIZE);
18845c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.nss =
18855c1def83SBjoern A. Zeeb 			u32_get_bits(info[2],
18865c1def83SBjoern A. Zeeb 				     HAL_TX_PHY_DESC_INFO2_NSS);
18875c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.chan_num =
18885c1def83SBjoern A. Zeeb 			u32_get_bits(info[3],
18895c1def83SBjoern A. Zeeb 				     HAL_TX_PHY_DESC_INFO3_ACTIVE_CHANNEL);
18905c1def83SBjoern A. Zeeb 		tx_ppdu_info->rx_status.bw =
18915c1def83SBjoern A. Zeeb 			u32_get_bits(info[0],
18925c1def83SBjoern A. Zeeb 				     HAL_TX_PHY_DESC_INFO0_BANDWIDTH);
18935c1def83SBjoern A. Zeeb 		break;
18945c1def83SBjoern A. Zeeb 	}
18955c1def83SBjoern A. Zeeb 
18965c1def83SBjoern A. Zeeb 	case HAL_TX_MPDU_START: {
18975c1def83SBjoern A. Zeeb 		struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu;
18985c1def83SBjoern A. Zeeb 
18995c1def83SBjoern A. Zeeb 		mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC);
19005c1def83SBjoern A. Zeeb 		if (!mon_mpdu)
19015c1def83SBjoern A. Zeeb 			return DP_MON_TX_STATUS_PPDU_NOT_DONE;
19025c1def83SBjoern A. Zeeb 		status = DP_MON_TX_MPDU_START;
19035c1def83SBjoern A. Zeeb 		break;
19045c1def83SBjoern A. Zeeb 	}
19055c1def83SBjoern A. Zeeb 
19065c1def83SBjoern A. Zeeb 	case HAL_MON_BUF_ADDR: {
19075c1def83SBjoern A. Zeeb 		struct dp_rxdma_ring *buf_ring = &ab->dp.tx_mon_buf_ring;
19085c1def83SBjoern A. Zeeb 		struct dp_mon_packet_info *packet_info =
19095c1def83SBjoern A. Zeeb 			(struct dp_mon_packet_info *)tlv_data;
19105c1def83SBjoern A. Zeeb 		int buf_id = u32_get_bits(packet_info->cookie,
19115c1def83SBjoern A. Zeeb 					  DP_RXDMA_BUF_COOKIE_BUF_ID);
19125c1def83SBjoern A. Zeeb 		struct sk_buff *msdu;
19135c1def83SBjoern A. Zeeb 		struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu;
19145c1def83SBjoern A. Zeeb 		struct ath12k_skb_rxcb *rxcb;
19155c1def83SBjoern A. Zeeb 
19165c1def83SBjoern A. Zeeb 		spin_lock_bh(&buf_ring->idr_lock);
19175c1def83SBjoern A. Zeeb 		msdu = idr_remove(&buf_ring->bufs_idr, buf_id);
19185c1def83SBjoern A. Zeeb 		spin_unlock_bh(&buf_ring->idr_lock);
19195c1def83SBjoern A. Zeeb 
19205c1def83SBjoern A. Zeeb 		if (unlikely(!msdu)) {
19215c1def83SBjoern A. Zeeb 			ath12k_warn(ab, "monitor destination with invalid buf_id %d\n",
19225c1def83SBjoern A. Zeeb 				    buf_id);
19235c1def83SBjoern A. Zeeb 			return DP_MON_TX_STATUS_PPDU_NOT_DONE;
19245c1def83SBjoern A. Zeeb 		}
19255c1def83SBjoern A. Zeeb 
19265c1def83SBjoern A. Zeeb 		rxcb = ATH12K_SKB_RXCB(msdu);
19275c1def83SBjoern A. Zeeb 		dma_unmap_single(ab->dev, rxcb->paddr,
19285c1def83SBjoern A. Zeeb 				 msdu->len + skb_tailroom(msdu),
19295c1def83SBjoern A. Zeeb 				 DMA_FROM_DEVICE);
19305c1def83SBjoern A. Zeeb 
19315c1def83SBjoern A. Zeeb 		if (!mon_mpdu->head)
19325c1def83SBjoern A. Zeeb 			mon_mpdu->head = msdu;
19335c1def83SBjoern A. Zeeb 		else if (mon_mpdu->tail)
19345c1def83SBjoern A. Zeeb 			mon_mpdu->tail->next = msdu;
19355c1def83SBjoern A. Zeeb 
19365c1def83SBjoern A. Zeeb 		mon_mpdu->tail = msdu;
19375c1def83SBjoern A. Zeeb 
19385c1def83SBjoern A. Zeeb 		ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);
19395c1def83SBjoern A. Zeeb 		status = DP_MON_TX_BUFFER_ADDR;
19405c1def83SBjoern A. Zeeb 		break;
19415c1def83SBjoern A. Zeeb 	}
19425c1def83SBjoern A. Zeeb 
19435c1def83SBjoern A. Zeeb 	case HAL_TX_MPDU_END:
19445c1def83SBjoern A. Zeeb 		list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,
19455c1def83SBjoern A. Zeeb 			      &tx_ppdu_info->dp_tx_mon_mpdu_list);
19465c1def83SBjoern A. Zeeb 		break;
19475c1def83SBjoern A. Zeeb 	}
19485c1def83SBjoern A. Zeeb 
19495c1def83SBjoern A. Zeeb 	return status;
19505c1def83SBjoern A. Zeeb }
19515c1def83SBjoern A. Zeeb 
19525c1def83SBjoern A. Zeeb enum dp_mon_tx_tlv_status
ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag,struct hal_tlv_hdr * tx_tlv,u8 * num_users)19535c1def83SBjoern A. Zeeb ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag,
19545c1def83SBjoern A. Zeeb 				     struct hal_tlv_hdr *tx_tlv,
19555c1def83SBjoern A. Zeeb 				     u8 *num_users)
19565c1def83SBjoern A. Zeeb {
19575c1def83SBjoern A. Zeeb 	u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE;
19585c1def83SBjoern A. Zeeb 	u32 info0;
19595c1def83SBjoern A. Zeeb 
19605c1def83SBjoern A. Zeeb 	switch (tlv_tag) {
19615c1def83SBjoern A. Zeeb 	case HAL_TX_FES_SETUP: {
19625c1def83SBjoern A. Zeeb 		struct hal_tx_fes_setup *tx_fes_setup =
19635c1def83SBjoern A. Zeeb 				(struct hal_tx_fes_setup *)tx_tlv;
19645c1def83SBjoern A. Zeeb 
19655c1def83SBjoern A. Zeeb 		info0 = __le32_to_cpu(tx_fes_setup->info0);
19665c1def83SBjoern A. Zeeb 
19675c1def83SBjoern A. Zeeb 		*num_users = u32_get_bits(info0, HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS);
19685c1def83SBjoern A. Zeeb 		tlv_status = DP_MON_TX_FES_SETUP;
19695c1def83SBjoern A. Zeeb 		break;
19705c1def83SBjoern A. Zeeb 	}
19715c1def83SBjoern A. Zeeb 
19725c1def83SBjoern A. Zeeb 	case HAL_RX_RESPONSE_REQUIRED_INFO: {
19735c1def83SBjoern A. Zeeb 		/* TODO: need to update *num_users */
19745c1def83SBjoern A. Zeeb 		tlv_status = DP_MON_RX_RESPONSE_REQUIRED_INFO;
19755c1def83SBjoern A. Zeeb 		break;
19765c1def83SBjoern A. Zeeb 	}
19775c1def83SBjoern A. Zeeb 	}
19785c1def83SBjoern A. Zeeb 
19795c1def83SBjoern A. Zeeb 	return tlv_status;
19805c1def83SBjoern A. Zeeb }
19815c1def83SBjoern A. Zeeb 
19825c1def83SBjoern A. Zeeb static void
ath12k_dp_mon_tx_process_ppdu_info(struct ath12k * ar,int mac_id,struct napi_struct * napi,struct dp_mon_tx_ppdu_info * tx_ppdu_info)19835c1def83SBjoern A. Zeeb ath12k_dp_mon_tx_process_ppdu_info(struct ath12k *ar, int mac_id,
19845c1def83SBjoern A. Zeeb 				   struct napi_struct *napi,
19855c1def83SBjoern A. Zeeb 				   struct dp_mon_tx_ppdu_info *tx_ppdu_info)
19865c1def83SBjoern A. Zeeb {
19875c1def83SBjoern A. Zeeb 	struct dp_mon_mpdu *tmp, *mon_mpdu;
19885c1def83SBjoern A. Zeeb 	struct sk_buff *head_msdu;
19895c1def83SBjoern A. Zeeb 
19905c1def83SBjoern A. Zeeb 	list_for_each_entry_safe(mon_mpdu, tmp,
19915c1def83SBjoern A. Zeeb 				 &tx_ppdu_info->dp_tx_mon_mpdu_list, list) {
19925c1def83SBjoern A. Zeeb 		list_del(&mon_mpdu->list);
19935c1def83SBjoern A. Zeeb 		head_msdu = mon_mpdu->head;
19945c1def83SBjoern A. Zeeb 
19955c1def83SBjoern A. Zeeb 		if (head_msdu)
19965c1def83SBjoern A. Zeeb 			ath12k_dp_mon_rx_deliver(ar, mac_id, head_msdu,
19975c1def83SBjoern A. Zeeb 						 &tx_ppdu_info->rx_status, napi);
19985c1def83SBjoern A. Zeeb 
19995c1def83SBjoern A. Zeeb 		kfree(mon_mpdu);
20005c1def83SBjoern A. Zeeb 	}
20015c1def83SBjoern A. Zeeb }
20025c1def83SBjoern A. Zeeb 
20035c1def83SBjoern A. Zeeb enum hal_rx_mon_status
ath12k_dp_mon_tx_parse_mon_status(struct ath12k * ar,struct ath12k_mon_data * pmon,int mac_id,struct sk_buff * skb,struct napi_struct * napi,u32 ppdu_id)20045c1def83SBjoern A. Zeeb ath12k_dp_mon_tx_parse_mon_status(struct ath12k *ar,
20055c1def83SBjoern A. Zeeb 				  struct ath12k_mon_data *pmon,
20065c1def83SBjoern A. Zeeb 				  int mac_id,
20075c1def83SBjoern A. Zeeb 				  struct sk_buff *skb,
20085c1def83SBjoern A. Zeeb 				  struct napi_struct *napi,
20095c1def83SBjoern A. Zeeb 				  u32 ppdu_id)
20105c1def83SBjoern A. Zeeb {
20115c1def83SBjoern A. Zeeb 	struct ath12k_base *ab = ar->ab;
20125c1def83SBjoern A. Zeeb 	struct dp_mon_tx_ppdu_info *tx_prot_ppdu_info, *tx_data_ppdu_info;
20135c1def83SBjoern A. Zeeb 	struct hal_tlv_hdr *tlv;
20145c1def83SBjoern A. Zeeb 	u8 *ptr = skb->data;
20155c1def83SBjoern A. Zeeb 	u16 tlv_tag;
20165c1def83SBjoern A. Zeeb 	u16 tlv_len;
20175c1def83SBjoern A. Zeeb 	u32 tlv_userid = 0;
20185c1def83SBjoern A. Zeeb 	u8 num_user;
20195c1def83SBjoern A. Zeeb 	u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE;
20205c1def83SBjoern A. Zeeb 
20215c1def83SBjoern A. Zeeb 	tx_prot_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id,
20225c1def83SBjoern A. Zeeb 							   DP_MON_TX_PROT_PPDU_INFO);
20235c1def83SBjoern A. Zeeb 	if (!tx_prot_ppdu_info)
20245c1def83SBjoern A. Zeeb 		return -ENOMEM;
20255c1def83SBjoern A. Zeeb 
20265c1def83SBjoern A. Zeeb 	tlv = (struct hal_tlv_hdr *)ptr;
20275c1def83SBjoern A. Zeeb 	tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG);
20285c1def83SBjoern A. Zeeb 
20295c1def83SBjoern A. Zeeb 	tlv_status = ath12k_dp_mon_tx_status_get_num_user(tlv_tag, tlv, &num_user);
20305c1def83SBjoern A. Zeeb 	if (tlv_status == DP_MON_TX_STATUS_PPDU_NOT_DONE || !num_user)
20315c1def83SBjoern A. Zeeb 		return -EINVAL;
20325c1def83SBjoern A. Zeeb 
20335c1def83SBjoern A. Zeeb 	tx_data_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id,
20345c1def83SBjoern A. Zeeb 							   DP_MON_TX_DATA_PPDU_INFO);
20355c1def83SBjoern A. Zeeb 	if (!tx_data_ppdu_info)
20365c1def83SBjoern A. Zeeb 		return -ENOMEM;
20375c1def83SBjoern A. Zeeb 
20385c1def83SBjoern A. Zeeb 	do {
20395c1def83SBjoern A. Zeeb 		tlv = (struct hal_tlv_hdr *)ptr;
20405c1def83SBjoern A. Zeeb 		tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG);
20415c1def83SBjoern A. Zeeb 		tlv_len = le32_get_bits(tlv->tl, HAL_TLV_HDR_LEN);
20425c1def83SBjoern A. Zeeb 		tlv_userid = le32_get_bits(tlv->tl, HAL_TLV_USR_ID);
20435c1def83SBjoern A. Zeeb 
20445c1def83SBjoern A. Zeeb 		tlv_status = ath12k_dp_mon_tx_parse_status_tlv(ab, pmon,
20455c1def83SBjoern A. Zeeb 							       tlv_tag, ptr,
20465c1def83SBjoern A. Zeeb 							       tlv_userid);
20475c1def83SBjoern A. Zeeb 		ptr += tlv_len;
20485c1def83SBjoern A. Zeeb 		ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN);
20495c1def83SBjoern A. Zeeb 		if ((ptr - skb->data) >= DP_TX_MONITOR_BUF_SIZE)
20505c1def83SBjoern A. Zeeb 			break;
20515c1def83SBjoern A. Zeeb 	} while (tlv_status != DP_MON_TX_FES_STATUS_END);
20525c1def83SBjoern A. Zeeb 
20535c1def83SBjoern A. Zeeb 	ath12k_dp_mon_tx_process_ppdu_info(ar, mac_id, napi, tx_data_ppdu_info);
20545c1def83SBjoern A. Zeeb 	ath12k_dp_mon_tx_process_ppdu_info(ar, mac_id, napi, tx_prot_ppdu_info);
20555c1def83SBjoern A. Zeeb 
20565c1def83SBjoern A. Zeeb 	return tlv_status;
20575c1def83SBjoern A. Zeeb }
20585c1def83SBjoern A. Zeeb 
ath12k_dp_mon_srng_process(struct ath12k * ar,int mac_id,int * budget,enum dp_monitor_mode monitor_mode,struct napi_struct * napi)20595c1def83SBjoern A. Zeeb int ath12k_dp_mon_srng_process(struct ath12k *ar, int mac_id, int *budget,
20605c1def83SBjoern A. Zeeb 			       enum dp_monitor_mode monitor_mode,
20615c1def83SBjoern A. Zeeb 			       struct napi_struct *napi)
20625c1def83SBjoern A. Zeeb {
20635c1def83SBjoern A. Zeeb 	struct hal_mon_dest_desc *mon_dst_desc;
20645c1def83SBjoern A. Zeeb 	struct ath12k_pdev_dp *pdev_dp = &ar->dp;
20655c1def83SBjoern A. Zeeb 	struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data;
20665c1def83SBjoern A. Zeeb 	struct ath12k_base *ab = ar->ab;
20675c1def83SBjoern A. Zeeb 	struct ath12k_dp *dp = &ab->dp;
20685c1def83SBjoern A. Zeeb 	struct sk_buff *skb;
20695c1def83SBjoern A. Zeeb 	struct ath12k_skb_rxcb *rxcb;
20705c1def83SBjoern A. Zeeb 	struct dp_srng *mon_dst_ring;
20715c1def83SBjoern A. Zeeb 	struct hal_srng *srng;
20725c1def83SBjoern A. Zeeb 	struct dp_rxdma_ring *buf_ring;
20735c1def83SBjoern A. Zeeb 	u64 cookie;
20745c1def83SBjoern A. Zeeb 	u32 ppdu_id;
20755c1def83SBjoern A. Zeeb 	int num_buffs_reaped = 0, srng_id, buf_id;
20765c1def83SBjoern A. Zeeb 	u8 dest_idx = 0, i;
20775c1def83SBjoern A. Zeeb 	bool end_of_ppdu;
20785c1def83SBjoern A. Zeeb 	struct hal_rx_mon_ppdu_info *ppdu_info;
20795c1def83SBjoern A. Zeeb 	struct ath12k_peer *peer = NULL;
20805c1def83SBjoern A. Zeeb 
20815c1def83SBjoern A. Zeeb 	ppdu_info = &pmon->mon_ppdu_info;
20825c1def83SBjoern A. Zeeb 	memset(ppdu_info, 0, sizeof(*ppdu_info));
20835c1def83SBjoern A. Zeeb 	ppdu_info->peer_id = HAL_INVALID_PEERID;
20845c1def83SBjoern A. Zeeb 
20855c1def83SBjoern A. Zeeb 	srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id);
20865c1def83SBjoern A. Zeeb 
20875c1def83SBjoern A. Zeeb 	if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) {
20885c1def83SBjoern A. Zeeb 		mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id];
20895c1def83SBjoern A. Zeeb 		buf_ring = &dp->rxdma_mon_buf_ring;
20905c1def83SBjoern A. Zeeb 	} else {
20915c1def83SBjoern A. Zeeb 		mon_dst_ring = &pdev_dp->tx_mon_dst_ring[srng_id];
20925c1def83SBjoern A. Zeeb 		buf_ring = &dp->tx_mon_buf_ring;
20935c1def83SBjoern A. Zeeb 	}
20945c1def83SBjoern A. Zeeb 
20955c1def83SBjoern A. Zeeb 	srng = &ab->hal.srng_list[mon_dst_ring->ring_id];
20965c1def83SBjoern A. Zeeb 
20975c1def83SBjoern A. Zeeb 	spin_lock_bh(&srng->lock);
20985c1def83SBjoern A. Zeeb 	ath12k_hal_srng_access_begin(ab, srng);
20995c1def83SBjoern A. Zeeb 
21005c1def83SBjoern A. Zeeb 	while (likely(*budget)) {
21015c1def83SBjoern A. Zeeb 		*budget -= 1;
21025c1def83SBjoern A. Zeeb 		mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng);
21035c1def83SBjoern A. Zeeb 		if (unlikely(!mon_dst_desc))
21045c1def83SBjoern A. Zeeb 			break;
21055c1def83SBjoern A. Zeeb 
21065c1def83SBjoern A. Zeeb 		cookie = le32_to_cpu(mon_dst_desc->cookie);
21075c1def83SBjoern A. Zeeb 		buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID);
21085c1def83SBjoern A. Zeeb 
21095c1def83SBjoern A. Zeeb 		spin_lock_bh(&buf_ring->idr_lock);
21105c1def83SBjoern A. Zeeb 		skb = idr_remove(&buf_ring->bufs_idr, buf_id);
21115c1def83SBjoern A. Zeeb 		spin_unlock_bh(&buf_ring->idr_lock);
21125c1def83SBjoern A. Zeeb 
21135c1def83SBjoern A. Zeeb 		if (unlikely(!skb)) {
21145c1def83SBjoern A. Zeeb 			ath12k_warn(ab, "monitor destination with invalid buf_id %d\n",
21155c1def83SBjoern A. Zeeb 				    buf_id);
21165c1def83SBjoern A. Zeeb 			goto move_next;
21175c1def83SBjoern A. Zeeb 		}
21185c1def83SBjoern A. Zeeb 
21195c1def83SBjoern A. Zeeb 		rxcb = ATH12K_SKB_RXCB(skb);
21205c1def83SBjoern A. Zeeb 		dma_unmap_single(ab->dev, rxcb->paddr,
21215c1def83SBjoern A. Zeeb 				 skb->len + skb_tailroom(skb),
21225c1def83SBjoern A. Zeeb 				 DMA_FROM_DEVICE);
21235c1def83SBjoern A. Zeeb 
21245c1def83SBjoern A. Zeeb 		pmon->dest_skb_q[dest_idx] = skb;
21255c1def83SBjoern A. Zeeb 		dest_idx++;
21265c1def83SBjoern A. Zeeb 		ppdu_id = le32_to_cpu(mon_dst_desc->ppdu_id);
21275c1def83SBjoern A. Zeeb 		end_of_ppdu = le32_get_bits(mon_dst_desc->info0,
21285c1def83SBjoern A. Zeeb 					    HAL_MON_DEST_INFO0_END_OF_PPDU);
21295c1def83SBjoern A. Zeeb 		if (!end_of_ppdu)
21305c1def83SBjoern A. Zeeb 			continue;
21315c1def83SBjoern A. Zeeb 
21325c1def83SBjoern A. Zeeb 		for (i = 0; i < dest_idx; i++) {
21335c1def83SBjoern A. Zeeb 			skb = pmon->dest_skb_q[i];
21345c1def83SBjoern A. Zeeb 
21355c1def83SBjoern A. Zeeb 			if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE)
21365c1def83SBjoern A. Zeeb 				ath12k_dp_mon_rx_parse_mon_status(ar, pmon, mac_id,
21375c1def83SBjoern A. Zeeb 								  skb, napi);
21385c1def83SBjoern A. Zeeb 			else
21395c1def83SBjoern A. Zeeb 				ath12k_dp_mon_tx_parse_mon_status(ar, pmon, mac_id,
21405c1def83SBjoern A. Zeeb 								  skb, napi, ppdu_id);
21415c1def83SBjoern A. Zeeb 
21425c1def83SBjoern A. Zeeb 			peer = ath12k_peer_find_by_id(ab, ppdu_info->peer_id);
21435c1def83SBjoern A. Zeeb 
21445c1def83SBjoern A. Zeeb 			if (!peer || !peer->sta) {
21455c1def83SBjoern A. Zeeb 				ath12k_dbg(ab, ATH12K_DBG_DATA,
21465c1def83SBjoern A. Zeeb 					   "failed to find the peer with peer_id %d\n",
21475c1def83SBjoern A. Zeeb 					   ppdu_info->peer_id);
21485c1def83SBjoern A. Zeeb 				dev_kfree_skb_any(skb);
21495c1def83SBjoern A. Zeeb 				continue;
21505c1def83SBjoern A. Zeeb 			}
21515c1def83SBjoern A. Zeeb 
21525c1def83SBjoern A. Zeeb 			dev_kfree_skb_any(skb);
21535c1def83SBjoern A. Zeeb 			pmon->dest_skb_q[i] = NULL;
21545c1def83SBjoern A. Zeeb 		}
21555c1def83SBjoern A. Zeeb 
21565c1def83SBjoern A. Zeeb 		dest_idx = 0;
21575c1def83SBjoern A. Zeeb move_next:
21585c1def83SBjoern A. Zeeb 		ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);
21595c1def83SBjoern A. Zeeb 		ath12k_hal_srng_src_get_next_entry(ab, srng);
21605c1def83SBjoern A. Zeeb 		num_buffs_reaped++;
21615c1def83SBjoern A. Zeeb 	}
21625c1def83SBjoern A. Zeeb 
21635c1def83SBjoern A. Zeeb 	ath12k_hal_srng_access_end(ab, srng);
21645c1def83SBjoern A. Zeeb 	spin_unlock_bh(&srng->lock);
21655c1def83SBjoern A. Zeeb 
21665c1def83SBjoern A. Zeeb 	return num_buffs_reaped;
21675c1def83SBjoern A. Zeeb }
21685c1def83SBjoern A. Zeeb 
21695c1def83SBjoern A. Zeeb static void
ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats * rx_stats,struct hal_rx_mon_ppdu_info * ppdu_info,struct hal_rx_user_status * user_stats,u32 num_msdu)21705c1def83SBjoern A. Zeeb ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_stats,
21715c1def83SBjoern A. Zeeb 					      struct hal_rx_mon_ppdu_info *ppdu_info,
21725c1def83SBjoern A. Zeeb 					      struct hal_rx_user_status *user_stats,
21735c1def83SBjoern A. Zeeb 					      u32 num_msdu)
21745c1def83SBjoern A. Zeeb {
21755c1def83SBjoern A. Zeeb 	u32 rate_idx = 0;
21765c1def83SBjoern A. Zeeb 	u32 mcs_idx = (user_stats) ? user_stats->mcs : ppdu_info->mcs;
21775c1def83SBjoern A. Zeeb 	u32 nss_idx = (user_stats) ? user_stats->nss - 1 : ppdu_info->nss - 1;
21785c1def83SBjoern A. Zeeb 	u32 bw_idx = ppdu_info->bw;
21795c1def83SBjoern A. Zeeb 	u32 gi_idx = ppdu_info->gi;
21805c1def83SBjoern A. Zeeb 
21815c1def83SBjoern A. Zeeb 	if ((mcs_idx > HAL_RX_MAX_MCS_HE) || (nss_idx >= HAL_RX_MAX_NSS) ||
21825c1def83SBjoern A. Zeeb 	    (bw_idx >= HAL_RX_BW_MAX) || (gi_idx >= HAL_RX_GI_MAX)) {
21835c1def83SBjoern A. Zeeb 		return;
21845c1def83SBjoern A. Zeeb 	}
21855c1def83SBjoern A. Zeeb 
21865c1def83SBjoern A. Zeeb 	if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N ||
21875c1def83SBjoern A. Zeeb 	    ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC) {
21885c1def83SBjoern A. Zeeb 		rate_idx = mcs_idx * 8 + 8 * 10 * nss_idx;
21895c1def83SBjoern A. Zeeb 		rate_idx += bw_idx * 2 + gi_idx;
21905c1def83SBjoern A. Zeeb 	} else if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX) {
21915c1def83SBjoern A. Zeeb 		gi_idx = ath12k_he_gi_to_nl80211_he_gi(ppdu_info->gi);
21925c1def83SBjoern A. Zeeb 		rate_idx = mcs_idx * 12 + 12 * 12 * nss_idx;
21935c1def83SBjoern A. Zeeb 		rate_idx += bw_idx * 3 + gi_idx;
21945c1def83SBjoern A. Zeeb 	} else {
21955c1def83SBjoern A. Zeeb 		return;
21965c1def83SBjoern A. Zeeb 	}
21975c1def83SBjoern A. Zeeb 
21985c1def83SBjoern A. Zeeb 	rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu;
21995c1def83SBjoern A. Zeeb 	if (user_stats)
22005c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.rx_rate[rate_idx] += user_stats->mpdu_ok_byte_count;
22015c1def83SBjoern A. Zeeb 	else
22025c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len;
22035c1def83SBjoern A. Zeeb }
22045c1def83SBjoern A. Zeeb 
ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k * ar,struct ath12k_sta * arsta,struct hal_rx_mon_ppdu_info * ppdu_info)22055c1def83SBjoern A. Zeeb static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k *ar,
22065c1def83SBjoern A. Zeeb 						  struct ath12k_sta *arsta,
22075c1def83SBjoern A. Zeeb 						  struct hal_rx_mon_ppdu_info *ppdu_info)
22085c1def83SBjoern A. Zeeb {
22095c1def83SBjoern A. Zeeb 	struct ath12k_rx_peer_stats *rx_stats = arsta->rx_stats;
22105c1def83SBjoern A. Zeeb 	u32 num_msdu;
22115c1def83SBjoern A. Zeeb 
22125c1def83SBjoern A. Zeeb 	if (!rx_stats)
22135c1def83SBjoern A. Zeeb 		return;
22145c1def83SBjoern A. Zeeb 
22155c1def83SBjoern A. Zeeb 	arsta->rssi_comb = ppdu_info->rssi_comb;
22165c1def83SBjoern A. Zeeb 
22175c1def83SBjoern A. Zeeb 	num_msdu = ppdu_info->tcp_msdu_count + ppdu_info->tcp_ack_msdu_count +
22185c1def83SBjoern A. Zeeb 		   ppdu_info->udp_msdu_count + ppdu_info->other_msdu_count;
22195c1def83SBjoern A. Zeeb 
22205c1def83SBjoern A. Zeeb 	rx_stats->num_msdu += num_msdu;
22215c1def83SBjoern A. Zeeb 	rx_stats->tcp_msdu_count += ppdu_info->tcp_msdu_count +
22225c1def83SBjoern A. Zeeb 				    ppdu_info->tcp_ack_msdu_count;
22235c1def83SBjoern A. Zeeb 	rx_stats->udp_msdu_count += ppdu_info->udp_msdu_count;
22245c1def83SBjoern A. Zeeb 	rx_stats->other_msdu_count += ppdu_info->other_msdu_count;
22255c1def83SBjoern A. Zeeb 
22265c1def83SBjoern A. Zeeb 	if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A ||
22275c1def83SBjoern A. Zeeb 	    ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) {
22285c1def83SBjoern A. Zeeb 		ppdu_info->nss = 1;
22295c1def83SBjoern A. Zeeb 		ppdu_info->mcs = HAL_RX_MAX_MCS;
22305c1def83SBjoern A. Zeeb 		ppdu_info->tid = IEEE80211_NUM_TIDS;
22315c1def83SBjoern A. Zeeb 	}
22325c1def83SBjoern A. Zeeb 
22335c1def83SBjoern A. Zeeb 	if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX)
22345c1def83SBjoern A. Zeeb 		rx_stats->coding_count[ppdu_info->ldpc] += num_msdu;
22355c1def83SBjoern A. Zeeb 
22365c1def83SBjoern A. Zeeb 	if (ppdu_info->tid <= IEEE80211_NUM_TIDS)
22375c1def83SBjoern A. Zeeb 		rx_stats->tid_count[ppdu_info->tid] += num_msdu;
22385c1def83SBjoern A. Zeeb 
22395c1def83SBjoern A. Zeeb 	if (ppdu_info->preamble_type < HAL_RX_PREAMBLE_MAX)
22405c1def83SBjoern A. Zeeb 		rx_stats->pream_cnt[ppdu_info->preamble_type] += num_msdu;
22415c1def83SBjoern A. Zeeb 
22425c1def83SBjoern A. Zeeb 	if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX)
22435c1def83SBjoern A. Zeeb 		rx_stats->reception_type[ppdu_info->reception_type] += num_msdu;
22445c1def83SBjoern A. Zeeb 
22455c1def83SBjoern A. Zeeb 	if (ppdu_info->is_stbc)
22465c1def83SBjoern A. Zeeb 		rx_stats->stbc_count += num_msdu;
22475c1def83SBjoern A. Zeeb 
22485c1def83SBjoern A. Zeeb 	if (ppdu_info->beamformed)
22495c1def83SBjoern A. Zeeb 		rx_stats->beamformed_count += num_msdu;
22505c1def83SBjoern A. Zeeb 
22515c1def83SBjoern A. Zeeb 	if (ppdu_info->num_mpdu_fcs_ok > 1)
22525c1def83SBjoern A. Zeeb 		rx_stats->ampdu_msdu_count += num_msdu;
22535c1def83SBjoern A. Zeeb 	else
22545c1def83SBjoern A. Zeeb 		rx_stats->non_ampdu_msdu_count += num_msdu;
22555c1def83SBjoern A. Zeeb 
22565c1def83SBjoern A. Zeeb 	rx_stats->num_mpdu_fcs_ok += ppdu_info->num_mpdu_fcs_ok;
22575c1def83SBjoern A. Zeeb 	rx_stats->num_mpdu_fcs_err += ppdu_info->num_mpdu_fcs_err;
22585c1def83SBjoern A. Zeeb 	rx_stats->dcm_count += ppdu_info->dcm;
22595c1def83SBjoern A. Zeeb 
22605c1def83SBjoern A. Zeeb 	rx_stats->rx_duration += ppdu_info->rx_duration;
22615c1def83SBjoern A. Zeeb 	arsta->rx_duration = rx_stats->rx_duration;
22625c1def83SBjoern A. Zeeb 
22635c1def83SBjoern A. Zeeb 	if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) {
22645c1def83SBjoern A. Zeeb 		rx_stats->pkt_stats.nss_count[ppdu_info->nss - 1] += num_msdu;
22655c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.nss_count[ppdu_info->nss - 1] += ppdu_info->mpdu_len;
22665c1def83SBjoern A. Zeeb 	}
22675c1def83SBjoern A. Zeeb 
22685c1def83SBjoern A. Zeeb 	if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N &&
22695c1def83SBjoern A. Zeeb 	    ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) {
22705c1def83SBjoern A. Zeeb 		rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu;
22715c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;
22725c1def83SBjoern A. Zeeb 		/* To fit into rate table for HT packets */
22735c1def83SBjoern A. Zeeb 		ppdu_info->mcs = ppdu_info->mcs % 8;
22745c1def83SBjoern A. Zeeb 	}
22755c1def83SBjoern A. Zeeb 
22765c1def83SBjoern A. Zeeb 	if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC &&
22775c1def83SBjoern A. Zeeb 	    ppdu_info->mcs <= HAL_RX_MAX_MCS_VHT) {
22785c1def83SBjoern A. Zeeb 		rx_stats->pkt_stats.vht_mcs_count[ppdu_info->mcs] += num_msdu;
22795c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.vht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;
22805c1def83SBjoern A. Zeeb 	}
22815c1def83SBjoern A. Zeeb 
22825c1def83SBjoern A. Zeeb 	if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX &&
22835c1def83SBjoern A. Zeeb 	    ppdu_info->mcs <= HAL_RX_MAX_MCS_HE) {
22845c1def83SBjoern A. Zeeb 		rx_stats->pkt_stats.he_mcs_count[ppdu_info->mcs] += num_msdu;
22855c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.he_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;
22865c1def83SBjoern A. Zeeb 	}
22875c1def83SBjoern A. Zeeb 
22885c1def83SBjoern A. Zeeb 	if ((ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A ||
22895c1def83SBjoern A. Zeeb 	     ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) &&
22905c1def83SBjoern A. Zeeb 	     ppdu_info->rate < HAL_RX_LEGACY_RATE_INVALID) {
22915c1def83SBjoern A. Zeeb 		rx_stats->pkt_stats.legacy_count[ppdu_info->rate] += num_msdu;
22925c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.legacy_count[ppdu_info->rate] += ppdu_info->mpdu_len;
22935c1def83SBjoern A. Zeeb 	}
22945c1def83SBjoern A. Zeeb 
22955c1def83SBjoern A. Zeeb 	if (ppdu_info->gi < HAL_RX_GI_MAX) {
22965c1def83SBjoern A. Zeeb 		rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu;
22975c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.gi_count[ppdu_info->gi] += ppdu_info->mpdu_len;
22985c1def83SBjoern A. Zeeb 	}
22995c1def83SBjoern A. Zeeb 
23005c1def83SBjoern A. Zeeb 	if (ppdu_info->bw < HAL_RX_BW_MAX) {
23015c1def83SBjoern A. Zeeb 		rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu;
23025c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len;
23035c1def83SBjoern A. Zeeb 	}
23045c1def83SBjoern A. Zeeb 
23055c1def83SBjoern A. Zeeb 	ath12k_dp_mon_rx_update_peer_rate_table_stats(rx_stats, ppdu_info,
23065c1def83SBjoern A. Zeeb 						      NULL, num_msdu);
23075c1def83SBjoern A. Zeeb }
23085c1def83SBjoern A. Zeeb 
ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info * ppdu_info)23095c1def83SBjoern A. Zeeb void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info)
23105c1def83SBjoern A. Zeeb {
23115c1def83SBjoern A. Zeeb 	struct hal_rx_user_status *rx_user_status;
23125c1def83SBjoern A. Zeeb 	u32 num_users, i, mu_ul_user_v0_word0, mu_ul_user_v0_word1, ru_size;
23135c1def83SBjoern A. Zeeb 
23145c1def83SBjoern A. Zeeb 	if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_MIMO ||
23155c1def83SBjoern A. Zeeb 	      ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA ||
23165c1def83SBjoern A. Zeeb 	      ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO))
23175c1def83SBjoern A. Zeeb 		return;
23185c1def83SBjoern A. Zeeb 
23195c1def83SBjoern A. Zeeb 	num_users = ppdu_info->num_users;
23205c1def83SBjoern A. Zeeb 	if (num_users > HAL_MAX_UL_MU_USERS)
23215c1def83SBjoern A. Zeeb 		num_users = HAL_MAX_UL_MU_USERS;
23225c1def83SBjoern A. Zeeb 
23235c1def83SBjoern A. Zeeb 	for (i = 0; i < num_users; i++) {
23245c1def83SBjoern A. Zeeb 		rx_user_status = &ppdu_info->userstats[i];
23255c1def83SBjoern A. Zeeb 		mu_ul_user_v0_word0 =
23265c1def83SBjoern A. Zeeb 			rx_user_status->ul_ofdma_user_v0_word0;
23275c1def83SBjoern A. Zeeb 		mu_ul_user_v0_word1 =
23285c1def83SBjoern A. Zeeb 			rx_user_status->ul_ofdma_user_v0_word1;
23295c1def83SBjoern A. Zeeb 
23305c1def83SBjoern A. Zeeb 		if (u32_get_bits(mu_ul_user_v0_word0,
23315c1def83SBjoern A. Zeeb 				 HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID) &&
23325c1def83SBjoern A. Zeeb 		    !u32_get_bits(mu_ul_user_v0_word0,
23335c1def83SBjoern A. Zeeb 				  HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER)) {
23345c1def83SBjoern A. Zeeb 			rx_user_status->mcs =
23355c1def83SBjoern A. Zeeb 				u32_get_bits(mu_ul_user_v0_word1,
23365c1def83SBjoern A. Zeeb 					     HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS);
23375c1def83SBjoern A. Zeeb 			rx_user_status->nss =
23385c1def83SBjoern A. Zeeb 				u32_get_bits(mu_ul_user_v0_word1,
23395c1def83SBjoern A. Zeeb 					     HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS) + 1;
23405c1def83SBjoern A. Zeeb 
23415c1def83SBjoern A. Zeeb 			rx_user_status->ofdma_info_valid = 1;
23425c1def83SBjoern A. Zeeb 			rx_user_status->ul_ofdma_ru_start_index =
23435c1def83SBjoern A. Zeeb 				u32_get_bits(mu_ul_user_v0_word1,
23445c1def83SBjoern A. Zeeb 					     HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START);
23455c1def83SBjoern A. Zeeb 
23465c1def83SBjoern A. Zeeb 			ru_size = u32_get_bits(mu_ul_user_v0_word1,
23475c1def83SBjoern A. Zeeb 					       HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE);
23485c1def83SBjoern A. Zeeb 			rx_user_status->ul_ofdma_ru_width = ru_size;
23495c1def83SBjoern A. Zeeb 			rx_user_status->ul_ofdma_ru_size = ru_size;
23505c1def83SBjoern A. Zeeb 		}
23515c1def83SBjoern A. Zeeb 		rx_user_status->ldpc = u32_get_bits(mu_ul_user_v0_word1,
23525c1def83SBjoern A. Zeeb 						    HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC);
23535c1def83SBjoern A. Zeeb 	}
23545c1def83SBjoern A. Zeeb 	ppdu_info->ldpc = 1;
23555c1def83SBjoern A. Zeeb }
23565c1def83SBjoern A. Zeeb 
23575c1def83SBjoern A. Zeeb static void
ath12k_dp_mon_rx_update_user_stats(struct ath12k * ar,struct hal_rx_mon_ppdu_info * ppdu_info,u32 uid)23585c1def83SBjoern A. Zeeb ath12k_dp_mon_rx_update_user_stats(struct ath12k *ar,
23595c1def83SBjoern A. Zeeb 				   struct hal_rx_mon_ppdu_info *ppdu_info,
23605c1def83SBjoern A. Zeeb 				   u32 uid)
23615c1def83SBjoern A. Zeeb {
23625c1def83SBjoern A. Zeeb 	struct ath12k_sta *arsta = NULL;
23635c1def83SBjoern A. Zeeb 	struct ath12k_rx_peer_stats *rx_stats = NULL;
23645c1def83SBjoern A. Zeeb 	struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid];
23655c1def83SBjoern A. Zeeb 	struct ath12k_peer *peer;
23665c1def83SBjoern A. Zeeb 	u32 num_msdu;
23675c1def83SBjoern A. Zeeb 
23685c1def83SBjoern A. Zeeb 	if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF)
23695c1def83SBjoern A. Zeeb 		return;
23705c1def83SBjoern A. Zeeb 
23715c1def83SBjoern A. Zeeb 	peer = ath12k_peer_find_by_ast(ar->ab, user_stats->ast_index);
23725c1def83SBjoern A. Zeeb 
23735c1def83SBjoern A. Zeeb 	if (!peer) {
23745c1def83SBjoern A. Zeeb 		ath12k_warn(ar->ab, "peer ast idx %d can't be found\n",
23755c1def83SBjoern A. Zeeb 			    user_stats->ast_index);
23765c1def83SBjoern A. Zeeb 		return;
23775c1def83SBjoern A. Zeeb 	}
23785c1def83SBjoern A. Zeeb 
23795c1def83SBjoern A. Zeeb 	arsta = (struct ath12k_sta *)peer->sta->drv_priv;
23805c1def83SBjoern A. Zeeb 	rx_stats = arsta->rx_stats;
23815c1def83SBjoern A. Zeeb 
23825c1def83SBjoern A. Zeeb 	if (!rx_stats)
23835c1def83SBjoern A. Zeeb 		return;
23845c1def83SBjoern A. Zeeb 
23855c1def83SBjoern A. Zeeb 	arsta->rssi_comb = ppdu_info->rssi_comb;
23865c1def83SBjoern A. Zeeb 
23875c1def83SBjoern A. Zeeb 	num_msdu = user_stats->tcp_msdu_count + user_stats->tcp_ack_msdu_count +
23885c1def83SBjoern A. Zeeb 		   user_stats->udp_msdu_count + user_stats->other_msdu_count;
23895c1def83SBjoern A. Zeeb 
23905c1def83SBjoern A. Zeeb 	rx_stats->num_msdu += num_msdu;
23915c1def83SBjoern A. Zeeb 	rx_stats->tcp_msdu_count += user_stats->tcp_msdu_count +
23925c1def83SBjoern A. Zeeb 				    user_stats->tcp_ack_msdu_count;
23935c1def83SBjoern A. Zeeb 	rx_stats->udp_msdu_count += user_stats->udp_msdu_count;
23945c1def83SBjoern A. Zeeb 	rx_stats->other_msdu_count += user_stats->other_msdu_count;
23955c1def83SBjoern A. Zeeb 
23965c1def83SBjoern A. Zeeb 	if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX)
23975c1def83SBjoern A. Zeeb 		rx_stats->coding_count[ppdu_info->ldpc] += num_msdu;
23985c1def83SBjoern A. Zeeb 
23995c1def83SBjoern A. Zeeb 	if (user_stats->tid <= IEEE80211_NUM_TIDS)
24005c1def83SBjoern A. Zeeb 		rx_stats->tid_count[user_stats->tid] += num_msdu;
24015c1def83SBjoern A. Zeeb 
24025c1def83SBjoern A. Zeeb 	if (user_stats->preamble_type < HAL_RX_PREAMBLE_MAX)
24035c1def83SBjoern A. Zeeb 		rx_stats->pream_cnt[user_stats->preamble_type] += num_msdu;
24045c1def83SBjoern A. Zeeb 
24055c1def83SBjoern A. Zeeb 	if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX)
24065c1def83SBjoern A. Zeeb 		rx_stats->reception_type[ppdu_info->reception_type] += num_msdu;
24075c1def83SBjoern A. Zeeb 
24085c1def83SBjoern A. Zeeb 	if (ppdu_info->is_stbc)
24095c1def83SBjoern A. Zeeb 		rx_stats->stbc_count += num_msdu;
24105c1def83SBjoern A. Zeeb 
24115c1def83SBjoern A. Zeeb 	if (ppdu_info->beamformed)
24125c1def83SBjoern A. Zeeb 		rx_stats->beamformed_count += num_msdu;
24135c1def83SBjoern A. Zeeb 
24145c1def83SBjoern A. Zeeb 	if (user_stats->mpdu_cnt_fcs_ok > 1)
24155c1def83SBjoern A. Zeeb 		rx_stats->ampdu_msdu_count += num_msdu;
24165c1def83SBjoern A. Zeeb 	else
24175c1def83SBjoern A. Zeeb 		rx_stats->non_ampdu_msdu_count += num_msdu;
24185c1def83SBjoern A. Zeeb 
24195c1def83SBjoern A. Zeeb 	rx_stats->num_mpdu_fcs_ok += user_stats->mpdu_cnt_fcs_ok;
24205c1def83SBjoern A. Zeeb 	rx_stats->num_mpdu_fcs_err += user_stats->mpdu_cnt_fcs_err;
24215c1def83SBjoern A. Zeeb 	rx_stats->dcm_count += ppdu_info->dcm;
24225c1def83SBjoern A. Zeeb 	if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA ||
24235c1def83SBjoern A. Zeeb 	    ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)
24245c1def83SBjoern A. Zeeb 		rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu;
24255c1def83SBjoern A. Zeeb 
24265c1def83SBjoern A. Zeeb 	rx_stats->rx_duration += ppdu_info->rx_duration;
24275c1def83SBjoern A. Zeeb 	arsta->rx_duration = rx_stats->rx_duration;
24285c1def83SBjoern A. Zeeb 
24295c1def83SBjoern A. Zeeb 	if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) {
24305c1def83SBjoern A. Zeeb 		rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu;
24315c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.nss_count[user_stats->nss - 1] +=
24325c1def83SBjoern A. Zeeb 						user_stats->mpdu_ok_byte_count;
24335c1def83SBjoern A. Zeeb 	}
24345c1def83SBjoern A. Zeeb 
24355c1def83SBjoern A. Zeeb 	if (user_stats->preamble_type == HAL_RX_PREAMBLE_11AX &&
24365c1def83SBjoern A. Zeeb 	    user_stats->mcs <= HAL_RX_MAX_MCS_HE) {
24375c1def83SBjoern A. Zeeb 		rx_stats->pkt_stats.he_mcs_count[user_stats->mcs] += num_msdu;
24385c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.he_mcs_count[user_stats->mcs] +=
24395c1def83SBjoern A. Zeeb 						user_stats->mpdu_ok_byte_count;
24405c1def83SBjoern A. Zeeb 	}
24415c1def83SBjoern A. Zeeb 
24425c1def83SBjoern A. Zeeb 	if (ppdu_info->gi < HAL_RX_GI_MAX) {
24435c1def83SBjoern A. Zeeb 		rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu;
24445c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.gi_count[ppdu_info->gi] +=
24455c1def83SBjoern A. Zeeb 						user_stats->mpdu_ok_byte_count;
24465c1def83SBjoern A. Zeeb 	}
24475c1def83SBjoern A. Zeeb 
24485c1def83SBjoern A. Zeeb 	if (ppdu_info->bw < HAL_RX_BW_MAX) {
24495c1def83SBjoern A. Zeeb 		rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu;
24505c1def83SBjoern A. Zeeb 		rx_stats->byte_stats.bw_count[ppdu_info->bw] +=
24515c1def83SBjoern A. Zeeb 						user_stats->mpdu_ok_byte_count;
24525c1def83SBjoern A. Zeeb 	}
24535c1def83SBjoern A. Zeeb 
24545c1def83SBjoern A. Zeeb 	ath12k_dp_mon_rx_update_peer_rate_table_stats(rx_stats, ppdu_info,
24555c1def83SBjoern A. Zeeb 						      user_stats, num_msdu);
24565c1def83SBjoern A. Zeeb }
24575c1def83SBjoern A. Zeeb 
24585c1def83SBjoern A. Zeeb static void
ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k * ar,struct hal_rx_mon_ppdu_info * ppdu_info)24595c1def83SBjoern A. Zeeb ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k *ar,
24605c1def83SBjoern A. Zeeb 				      struct hal_rx_mon_ppdu_info *ppdu_info)
24615c1def83SBjoern A. Zeeb {
24625c1def83SBjoern A. Zeeb 	u32 num_users, i;
24635c1def83SBjoern A. Zeeb 
24645c1def83SBjoern A. Zeeb 	num_users = ppdu_info->num_users;
24655c1def83SBjoern A. Zeeb 	if (num_users > HAL_MAX_UL_MU_USERS)
24665c1def83SBjoern A. Zeeb 		num_users = HAL_MAX_UL_MU_USERS;
24675c1def83SBjoern A. Zeeb 
24685c1def83SBjoern A. Zeeb 	for (i = 0; i < num_users; i++)
24695c1def83SBjoern A. Zeeb 		ath12k_dp_mon_rx_update_user_stats(ar, ppdu_info, i);
24705c1def83SBjoern A. Zeeb }
24715c1def83SBjoern A. Zeeb 
ath12k_dp_mon_rx_process_stats(struct ath12k * ar,int mac_id,struct napi_struct * napi,int * budget)24725c1def83SBjoern A. Zeeb int ath12k_dp_mon_rx_process_stats(struct ath12k *ar, int mac_id,
24735c1def83SBjoern A. Zeeb 				   struct napi_struct *napi, int *budget)
24745c1def83SBjoern A. Zeeb {
24755c1def83SBjoern A. Zeeb 	struct ath12k_base *ab = ar->ab;
24765c1def83SBjoern A. Zeeb 	struct ath12k_pdev_dp *pdev_dp = &ar->dp;
24775c1def83SBjoern A. Zeeb 	struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data;
24785c1def83SBjoern A. Zeeb 	struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
24795c1def83SBjoern A. Zeeb 	struct ath12k_dp *dp = &ab->dp;
24805c1def83SBjoern A. Zeeb 	struct hal_mon_dest_desc *mon_dst_desc;
24815c1def83SBjoern A. Zeeb 	struct sk_buff *skb;
24825c1def83SBjoern A. Zeeb 	struct ath12k_skb_rxcb *rxcb;
24835c1def83SBjoern A. Zeeb 	struct dp_srng *mon_dst_ring;
24845c1def83SBjoern A. Zeeb 	struct hal_srng *srng;
24855c1def83SBjoern A. Zeeb 	struct dp_rxdma_ring *buf_ring;
24865c1def83SBjoern A. Zeeb 	struct ath12k_sta *arsta = NULL;
24875c1def83SBjoern A. Zeeb 	struct ath12k_peer *peer;
24885c1def83SBjoern A. Zeeb 	u64 cookie;
24895c1def83SBjoern A. Zeeb 	int num_buffs_reaped = 0, srng_id, buf_id;
24905c1def83SBjoern A. Zeeb 	u8 dest_idx = 0, i;
24915c1def83SBjoern A. Zeeb 	bool end_of_ppdu;
24925c1def83SBjoern A. Zeeb 	u32 hal_status;
24935c1def83SBjoern A. Zeeb 
24945c1def83SBjoern A. Zeeb 	srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id);
24955c1def83SBjoern A. Zeeb 	mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id];
24965c1def83SBjoern A. Zeeb 	buf_ring = &dp->rxdma_mon_buf_ring;
24975c1def83SBjoern A. Zeeb 
24985c1def83SBjoern A. Zeeb 	srng = &ab->hal.srng_list[mon_dst_ring->ring_id];
24995c1def83SBjoern A. Zeeb 	spin_lock_bh(&srng->lock);
25005c1def83SBjoern A. Zeeb 	ath12k_hal_srng_access_begin(ab, srng);
25015c1def83SBjoern A. Zeeb 
25025c1def83SBjoern A. Zeeb 	while (likely(*budget)) {
25035c1def83SBjoern A. Zeeb 		*budget -= 1;
25045c1def83SBjoern A. Zeeb 		mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng);
25055c1def83SBjoern A. Zeeb 		if (unlikely(!mon_dst_desc))
25065c1def83SBjoern A. Zeeb 			break;
25075c1def83SBjoern A. Zeeb 		cookie = le32_to_cpu(mon_dst_desc->cookie);
25085c1def83SBjoern A. Zeeb 		buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID);
25095c1def83SBjoern A. Zeeb 
25105c1def83SBjoern A. Zeeb 		spin_lock_bh(&buf_ring->idr_lock);
25115c1def83SBjoern A. Zeeb 		skb = idr_remove(&buf_ring->bufs_idr, buf_id);
25125c1def83SBjoern A. Zeeb 		spin_unlock_bh(&buf_ring->idr_lock);
25135c1def83SBjoern A. Zeeb 
25145c1def83SBjoern A. Zeeb 		if (unlikely(!skb)) {
25155c1def83SBjoern A. Zeeb 			ath12k_warn(ab, "monitor destination with invalid buf_id %d\n",
25165c1def83SBjoern A. Zeeb 				    buf_id);
25175c1def83SBjoern A. Zeeb 			goto move_next;
25185c1def83SBjoern A. Zeeb 		}
25195c1def83SBjoern A. Zeeb 
25205c1def83SBjoern A. Zeeb 		rxcb = ATH12K_SKB_RXCB(skb);
25215c1def83SBjoern A. Zeeb 		dma_unmap_single(ab->dev, rxcb->paddr,
25225c1def83SBjoern A. Zeeb 				 skb->len + skb_tailroom(skb),
25235c1def83SBjoern A. Zeeb 				 DMA_FROM_DEVICE);
25245c1def83SBjoern A. Zeeb 		pmon->dest_skb_q[dest_idx] = skb;
25255c1def83SBjoern A. Zeeb 		dest_idx++;
25265c1def83SBjoern A. Zeeb 		end_of_ppdu = le32_get_bits(mon_dst_desc->info0,
25275c1def83SBjoern A. Zeeb 					    HAL_MON_DEST_INFO0_END_OF_PPDU);
25285c1def83SBjoern A. Zeeb 		if (!end_of_ppdu)
25295c1def83SBjoern A. Zeeb 			continue;
25305c1def83SBjoern A. Zeeb 
25315c1def83SBjoern A. Zeeb 		for (i = 0; i < dest_idx; i++) {
25325c1def83SBjoern A. Zeeb 			skb = pmon->dest_skb_q[i];
25335c1def83SBjoern A. Zeeb 			hal_status = ath12k_dp_mon_parse_rx_dest(ab, pmon, skb);
25345c1def83SBjoern A. Zeeb 
25355c1def83SBjoern A. Zeeb 			if (ppdu_info->peer_id == HAL_INVALID_PEERID ||
25365c1def83SBjoern A. Zeeb 			    hal_status != HAL_RX_MON_STATUS_PPDU_DONE) {
25375c1def83SBjoern A. Zeeb 				dev_kfree_skb_any(skb);
25385c1def83SBjoern A. Zeeb 				continue;
25395c1def83SBjoern A. Zeeb 			}
25405c1def83SBjoern A. Zeeb 
25415c1def83SBjoern A. Zeeb 			rcu_read_lock();
25425c1def83SBjoern A. Zeeb 			spin_lock_bh(&ab->base_lock);
25435c1def83SBjoern A. Zeeb 			peer = ath12k_peer_find_by_id(ab, ppdu_info->peer_id);
25445c1def83SBjoern A. Zeeb 			if (!peer || !peer->sta) {
25455c1def83SBjoern A. Zeeb 				ath12k_dbg(ab, ATH12K_DBG_DATA,
25465c1def83SBjoern A. Zeeb 					   "failed to find the peer with peer_id %d\n",
25475c1def83SBjoern A. Zeeb 					   ppdu_info->peer_id);
25485c1def83SBjoern A. Zeeb 				spin_unlock_bh(&ab->base_lock);
25495c1def83SBjoern A. Zeeb 				rcu_read_unlock();
25505c1def83SBjoern A. Zeeb 				dev_kfree_skb_any(skb);
25515c1def83SBjoern A. Zeeb 				continue;
25525c1def83SBjoern A. Zeeb 			}
25535c1def83SBjoern A. Zeeb 
25545c1def83SBjoern A. Zeeb 			if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) {
25555c1def83SBjoern A. Zeeb 				arsta = (struct ath12k_sta *)peer->sta->drv_priv;
25565c1def83SBjoern A. Zeeb 				ath12k_dp_mon_rx_update_peer_su_stats(ar, arsta,
25575c1def83SBjoern A. Zeeb 								      ppdu_info);
25585c1def83SBjoern A. Zeeb 			} else if ((ppdu_info->fc_valid) &&
25595c1def83SBjoern A. Zeeb 				   (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) {
25605c1def83SBjoern A. Zeeb 				ath12k_dp_mon_rx_process_ulofdma(ppdu_info);
25615c1def83SBjoern A. Zeeb 				ath12k_dp_mon_rx_update_peer_mu_stats(ar, ppdu_info);
25625c1def83SBjoern A. Zeeb 			}
25635c1def83SBjoern A. Zeeb 
25645c1def83SBjoern A. Zeeb 			spin_unlock_bh(&ab->base_lock);
25655c1def83SBjoern A. Zeeb 			rcu_read_unlock();
25665c1def83SBjoern A. Zeeb 			dev_kfree_skb_any(skb);
25675c1def83SBjoern A. Zeeb 			memset(ppdu_info, 0, sizeof(*ppdu_info));
25685c1def83SBjoern A. Zeeb 			ppdu_info->peer_id = HAL_INVALID_PEERID;
25695c1def83SBjoern A. Zeeb 		}
25705c1def83SBjoern A. Zeeb 
25715c1def83SBjoern A. Zeeb 		dest_idx = 0;
25725c1def83SBjoern A. Zeeb move_next:
25735c1def83SBjoern A. Zeeb 		ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);
25745c1def83SBjoern A. Zeeb 		ath12k_hal_srng_src_get_next_entry(ab, srng);
25755c1def83SBjoern A. Zeeb 		num_buffs_reaped++;
25765c1def83SBjoern A. Zeeb 	}
25775c1def83SBjoern A. Zeeb 
25785c1def83SBjoern A. Zeeb 	ath12k_hal_srng_access_end(ab, srng);
25795c1def83SBjoern A. Zeeb 	spin_unlock_bh(&srng->lock);
25805c1def83SBjoern A. Zeeb 	return num_buffs_reaped;
25815c1def83SBjoern A. Zeeb }
25825c1def83SBjoern A. Zeeb 
ath12k_dp_mon_process_ring(struct ath12k_base * ab,int mac_id,struct napi_struct * napi,int budget,enum dp_monitor_mode monitor_mode)25835c1def83SBjoern A. Zeeb int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id,
25845c1def83SBjoern A. Zeeb 			       struct napi_struct *napi, int budget,
25855c1def83SBjoern A. Zeeb 			       enum dp_monitor_mode monitor_mode)
25865c1def83SBjoern A. Zeeb {
25875c1def83SBjoern A. Zeeb 	struct ath12k *ar = ath12k_ab_to_ar(ab, mac_id);
25885c1def83SBjoern A. Zeeb 	int num_buffs_reaped = 0;
25895c1def83SBjoern A. Zeeb 
25905c1def83SBjoern A. Zeeb 	if (!ar->monitor_started)
25915c1def83SBjoern A. Zeeb 		ath12k_dp_mon_rx_process_stats(ar, mac_id, napi, &budget);
25925c1def83SBjoern A. Zeeb 	else
25935c1def83SBjoern A. Zeeb 		num_buffs_reaped = ath12k_dp_mon_srng_process(ar, mac_id, &budget,
25945c1def83SBjoern A. Zeeb 							      monitor_mode, napi);
25955c1def83SBjoern A. Zeeb 
25965c1def83SBjoern A. Zeeb 	return num_buffs_reaped;
25975c1def83SBjoern A. Zeeb }
2598