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