Separate Wi-Fi 7-specific monitor-mode processing from common ath12k data path code to improve modularity. Move monitor status ring processing to wifi7/dp_mon.c: - ath12k_dp_mon_srng_process() - __ath12k_dp_mon_process_ring() - ath12k_dp_mon_process_ring() Rename the above to use the ath12k_wifi7_ prefix and export helper functions required by the ath12k_wifi7 module. Update the Wi-Fi 7 module Makefile to build dp_mon.o. No functional changes are intended; this is preparatory refactoring to isolate Wi-Fi 7 monitor-mode code from shared ath12k code. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh --- drivers/net/wireless/ath/ath12k/dp_mon.c | 256 ++---------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 19 +- .../net/wireless/ath/ath12k/wifi7/Makefile | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp.c | 16 +- drivers/net/wireless/ath/ath12k/wifi7/dp.h | 1 + .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 244 +++++++++++++++++ .../net/wireless/ath/ath12k/wifi7/dp_mon.h | 17 ++ 7 files changed, 305 insertions(+), 249 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 0533d8bf9c1c..5e2bf24d6b7e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2541,7 +2541,7 @@ ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, return 0; } -static enum hal_rx_mon_status +enum hal_rx_mon_status ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb) { @@ -2592,6 +2592,7 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_da return hal_status; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_rx_dest); enum hal_rx_mon_status ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, @@ -2619,6 +2620,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, return hal_status; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_mon_status); int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *buf_ring, @@ -2694,6 +2696,7 @@ int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, spin_unlock_bh(&srng->lock); return -ENOMEM; } +EXPORT_SYMBOL(ath12k_dp_mon_buf_replenish); int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, @@ -3490,8 +3493,8 @@ ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_st stats->rx_rate[bw_idx][gi_idx][nss_idx][mcs_idx] += len; } -static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, + struct hal_rx_mon_ppdu_info *ppdu_info) { struct ath12k_rx_peer_stats *rx_stats = peer->peer_stats.rx_stats; u32 num_msdu; @@ -3598,6 +3601,7 @@ static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *pe ath12k_dp_mon_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, NULL, num_msdu); } +EXPORT_SYMBOL(ath12k_dp_mon_rx_update_peer_su_stats); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -3646,6 +3650,7 @@ void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) } ppdu_info->ldpc = 1; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_process_ulofdma); static void ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, @@ -3746,7 +3751,7 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, user_stats, num_msdu); } -static void +void ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -3759,169 +3764,18 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, for (i = 0; i < num_users; i++) ath12k_dp_mon_rx_update_user_stats(ab, ppdu_info, i); } +EXPORT_SYMBOL(ath12k_dp_mon_rx_update_peer_mu_stats); -static void +void ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) { memset(ppdu_info, 0, sizeof(*ppdu_info)); ppdu_info->peer_id = HAL_INVALID_PEERID; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_memset_ppdu_info); -int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, - struct napi_struct *napi) -{ - struct ath12k_dp *dp = pdev_dp->dp; - struct ath12k_base *ab = dp->ab; - struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data; - struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - struct hal_mon_dest_desc *mon_dst_desc; - struct sk_buff *skb; - struct ath12k_skb_rxcb *rxcb; - struct dp_srng *mon_dst_ring; - struct hal_srng *srng; - struct dp_rxdma_mon_ring *buf_ring; - struct ath12k_dp_link_peer *peer; - struct sk_buff_head skb_list; - u64 cookie; - int num_buffs_reaped = 0, srng_id, buf_id; - u32 hal_status, end_offset, info0, end_reason; - u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, pdev_dp->mac_id); - - __skb_queue_head_init(&skb_list); - srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, pdev_idx); - mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id]; - buf_ring = &dp->rxdma_mon_buf_ring; - - srng = &ab->hal.srng_list[mon_dst_ring->ring_id]; - spin_lock_bh(&srng->lock); - ath12k_hal_srng_access_begin(ab, srng); - - while (likely(*budget)) { - mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng); - if (unlikely(!mon_dst_desc)) - break; - - /* In case of empty descriptor, the cookie in the ring descriptor - * is invalid. Therefore, this entry is skipped, and ring processing - * continues. - */ - info0 = le32_to_cpu(mon_dst_desc->info0); - if (u32_get_bits(info0, HAL_MON_DEST_INFO0_EMPTY_DESC)) - goto move_next; - - cookie = le32_to_cpu(mon_dst_desc->cookie); - buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); - - spin_lock_bh(&buf_ring->idr_lock); - skb = idr_remove(&buf_ring->bufs_idr, buf_id); - spin_unlock_bh(&buf_ring->idr_lock); - - if (unlikely(!skb)) { - ath12k_warn(ab, "monitor destination with invalid buf_id %d\n", - buf_id); - goto move_next; - } - - rxcb = ATH12K_SKB_RXCB(skb); - dma_unmap_single(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - end_reason = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_REASON); - - /* HAL_MON_FLUSH_DETECTED implies that an rx flush received at the end of - * rx PPDU and HAL_MON_PPDU_TRUNCATED implies that the PPDU got - * truncated due to a system level error. In both the cases, buffer data - * can be discarded - */ - if ((end_reason == HAL_MON_FLUSH_DETECTED) || - (end_reason == HAL_MON_PPDU_TRUNCATED)) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "Monitor dest descriptor end reason %d", end_reason); - dev_kfree_skb_any(skb); - goto move_next; - } - - /* Calculate the budget when the ring descriptor with the - * HAL_MON_END_OF_PPDU to ensure that one PPDU worth of data is always - * reaped. This helps to efficiently utilize the NAPI budget. - */ - if (end_reason == HAL_MON_END_OF_PPDU) { - *budget -= 1; - rxcb->is_end_of_ppdu = true; - } - - end_offset = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_OFFSET); - if (likely(end_offset <= DP_RX_BUFFER_SIZE)) { - skb_put(skb, end_offset); - } else { - ath12k_warn(ab, - "invalid offset on mon stats destination %u\n", - end_offset); - skb_put(skb, DP_RX_BUFFER_SIZE); - } - - __skb_queue_tail(&skb_list, skb); - -move_next: - ath12k_dp_mon_buf_replenish(ab, buf_ring, 1); - ath12k_hal_srng_dst_get_next_entry(ab, srng); - num_buffs_reaped++; - } - - ath12k_hal_srng_access_end(ab, srng); - spin_unlock_bh(&srng->lock); - - if (!num_buffs_reaped) - return 0; - - /* In some cases, one PPDU worth of data can be spread across multiple NAPI - * schedules, To avoid losing existing parsed ppdu_info information, skip - * the memset of the ppdu_info structure and continue processing it. - */ - if (!ppdu_info->ppdu_continuation) - ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); - - while ((skb = __skb_dequeue(&skb_list))) { - hal_status = ath12k_dp_mon_rx_parse_mon_status(pdev_dp, pmon, skb, napi); - if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { - ppdu_info->ppdu_continuation = true; - dev_kfree_skb_any(skb); - continue; - } - - if (ppdu_info->peer_id == HAL_INVALID_PEERID) - goto free_skb; - - rcu_read_lock(); - peer = ath12k_dp_link_peer_find_by_peerid(pdev_dp, ppdu_info->peer_id); - if (!peer || !peer->sta) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "failed to find the peer with monitor peer_id %d\n", - ppdu_info->peer_id); - goto next_skb; - } - - if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { - ath12k_dp_mon_rx_update_peer_su_stats(peer, ppdu_info); - } else if ((ppdu_info->fc_valid) && - (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { - ath12k_dp_mon_rx_process_ulofdma(ppdu_info); - ath12k_dp_mon_rx_update_peer_mu_stats(ab, ppdu_info); - } - -next_skb: - rcu_read_unlock(); -free_skb: - dev_kfree_skb_any(skb); - ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); - } - - return num_buffs_reaped; -} - -static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, - int *budget, struct sk_buff_head *skb_list) +int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, + int *budget, struct sk_buff_head *skb_list) { const struct ath12k_hw_hal_params *hal_params; int buf_id, srng_id, num_buffs_reaped = 0; @@ -4064,6 +3918,7 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, return num_buffs_reaped; } +EXPORT_SYMBOL(ath12k_dp_rx_reap_mon_status_ring); static u32 ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, @@ -4259,8 +4114,8 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, */ #define MON_DEST_RING_STUCK_MAX_CNT 16 -static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, - u32 quota, struct napi_struct *napi) +void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, + u32 quota, struct napi_struct *napi) { struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; struct ath12k_pdev_mon_stats *rx_mon_stats; @@ -4361,79 +4216,4 @@ static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, rx_bufs_used); } } - -static int -__ath12k_dp_mon_process_ring(struct ath12k *ar, int mac_id, - struct napi_struct *napi, int *budget) -{ - struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; - struct ath12k_pdev_mon_stats *rx_mon_stats = &pmon->rx_mon_stats; - struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - enum hal_rx_mon_status hal_status; - struct sk_buff_head skb_list; - int num_buffs_reaped; - struct sk_buff *skb; - - __skb_queue_head_init(&skb_list); - - num_buffs_reaped = ath12k_dp_rx_reap_mon_status_ring(ar->ab, mac_id, - budget, &skb_list); - if (!num_buffs_reaped) - goto exit; - - while ((skb = __skb_dequeue(&skb_list))) { - memset(ppdu_info, 0, sizeof(*ppdu_info)); - ppdu_info->peer_id = HAL_INVALID_PEERID; - - hal_status = ath12k_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); - - if (ar->monitor_started && - pmon->mon_ppdu_status == DP_PPDU_STATUS_START && - hal_status == HAL_TLV_STATUS_PPDU_DONE) { - rx_mon_stats->status_ppdu_done++; - pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; - ath12k_dp_rx_mon_dest_process(ar, mac_id, *budget, napi); - pmon->mon_ppdu_status = DP_PPDU_STATUS_START; - } - - dev_kfree_skb_any(skb); - } - -exit: - return num_buffs_reaped; -} - -int ath12k_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, - struct napi_struct *napi, int budget, - enum dp_monitor_mode monitor_mode) -{ - u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, mac_id); - struct ath12k_pdev_dp *dp_pdev; - struct ath12k *ar; - int num_buffs_reaped = 0; - - rcu_read_lock(); - - dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); - if (!dp_pdev) { - rcu_read_unlock(); - return 0; - } - - if (dp->hw_params->rxdma1_enable) { - if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) - num_buffs_reaped = ath12k_dp_mon_srng_process(dp_pdev, &budget, - napi); - } else { - ar = ath12k_pdev_dp_to_ar(dp_pdev); - - if (ar->monitor_started) - num_buffs_reaped = - __ath12k_dp_mon_process_ring(ar, mac_id, napi, &budget); - } - - rcu_read_unlock(); - - return num_buffs_reaped; -} -EXPORT_SYMBOL(ath12k_dp_mon_process_ring); +EXPORT_SYMBOL(ath12k_dp_rx_mon_dest_process); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 3e6ff4b0a6d9..689d7a0fff5c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -89,9 +89,6 @@ int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int req_entries); -int ath12k_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, - struct napi_struct *napi, int budget, - enum dp_monitor_mode monitor_mode); struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void); enum dp_mon_tx_tlv_status ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag, @@ -104,6 +101,18 @@ ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, u32 ppdu_id); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info); -int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, - struct napi_struct *napi); +enum hal_rx_mon_status +ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, + struct sk_buff *skb); +int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, + int *budget, struct sk_buff_head *skb_list); +void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, + u32 quota, struct napi_struct *napi); +void +ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, + struct hal_rx_mon_ppdu_info *ppdu_info); +void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/Makefile b/drivers/net/wireless/ath/ath12k/wifi7/Makefile index 30258a1b313d..dcfa732bb95b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/Makefile +++ b/drivers/net/wireless/ath/ath12k/wifi7/Makefile @@ -11,6 +11,7 @@ ath12k_wifi7-y += core.o \ dp_rx.o \ dp_tx.o \ dp.o \ + dp_mon.o \ hal.o \ hal_qcn9274.o \ hal_wcn7850.o diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 30c27e005ed8..0b2c7f37c756 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -9,6 +9,7 @@ #include "../dp_tx.h" #include "hal_desc.h" #include "../dp_mon.h" +#include "dp_mon.h" #include "../dp_cmn.h" #include "dp_rx.h" #include "dp.h" @@ -66,8 +67,9 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(dp, id, napi, budget, - 0); + ath12k_wifi7_dp_mon_process_ring(dp, id, napi, + budget, + 0); budget -= work_done; tot_work_done += work_done; if (budget <= 0) @@ -86,8 +88,9 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(dp, id, napi, budget, - monitor_mode); + ath12k_wifi7_dp_mon_process_ring(dp, id, napi, + budget, + monitor_mode); budget -= work_done; tot_work_done += work_done; @@ -107,8 +110,9 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(dp, id, napi, budget, - monitor_mode); + ath12k_wifi7_dp_mon_process_ring(dp, id, + napi, budget, + monitor_mode); budget -= work_done; tot_work_done += work_done; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.h b/drivers/net/wireless/ath/ath12k/wifi7/dp.h index 72fdfb368c99..a5f0941d34e2 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.h @@ -12,6 +12,7 @@ struct ath12k_base; struct ath12k_dp; +enum dp_monitor_mode; struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab); void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c new file mode 100644 index 000000000000..4135ff5e8759 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "hal_desc.h" +#include "../dp_mon.h" +#include "dp_mon.h" +#include "../debug.h" +#include "hal_qcn9274.h" +#include "dp_rx.h" +#include "../peer.h" + +static int +__ath12k_wifi7_dp_mon_process_ring(struct ath12k *ar, int mac_id, + struct napi_struct *napi, int *budget) +{ + struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; + struct ath12k_pdev_mon_stats *rx_mon_stats = &pmon->rx_mon_stats; + struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; + enum hal_rx_mon_status hal_status; + struct sk_buff_head skb_list; + int num_buffs_reaped; + struct sk_buff *skb; + + __skb_queue_head_init(&skb_list); + + num_buffs_reaped = ath12k_dp_rx_reap_mon_status_ring(ar->ab, mac_id, + budget, &skb_list); + if (!num_buffs_reaped) + goto exit; + + while ((skb = __skb_dequeue(&skb_list))) { + memset(ppdu_info, 0, sizeof(*ppdu_info)); + ppdu_info->peer_id = HAL_INVALID_PEERID; + + hal_status = ath12k_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); + + if (ar->monitor_started && + pmon->mon_ppdu_status == DP_PPDU_STATUS_START && + hal_status == HAL_TLV_STATUS_PPDU_DONE) { + rx_mon_stats->status_ppdu_done++; + pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; + ath12k_dp_rx_mon_dest_process(ar, mac_id, *budget, napi); + pmon->mon_ppdu_status = DP_PPDU_STATUS_START; + } + + dev_kfree_skb_any(skb); + } + +exit: + return num_buffs_reaped; +} + +static int +ath12k_wifi7_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, + struct napi_struct *napi) +{ + struct ath12k_dp *dp = pdev_dp->dp; + struct ath12k_base *ab = dp->ab; + struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data; + struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; + struct hal_mon_dest_desc *mon_dst_desc; + struct sk_buff *skb; + struct ath12k_skb_rxcb *rxcb; + struct dp_srng *mon_dst_ring; + struct hal_srng *srng; + struct dp_rxdma_mon_ring *buf_ring; + struct ath12k_dp_link_peer *peer; + struct sk_buff_head skb_list; + u64 cookie; + int num_buffs_reaped = 0, srng_id, buf_id; + u32 hal_status, end_offset, info0, end_reason; + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, pdev_dp->mac_id); + + __skb_queue_head_init(&skb_list); + srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, pdev_idx); + mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id]; + buf_ring = &dp->rxdma_mon_buf_ring; + + srng = &ab->hal.srng_list[mon_dst_ring->ring_id]; + spin_lock_bh(&srng->lock); + ath12k_hal_srng_access_begin(ab, srng); + + while (likely(*budget)) { + mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng); + if (unlikely(!mon_dst_desc)) + break; + + /* In case of empty descriptor, the cookie in the ring descriptor + * is invalid. Therefore, this entry is skipped, and ring processing + * continues. + */ + info0 = le32_to_cpu(mon_dst_desc->info0); + if (u32_get_bits(info0, HAL_MON_DEST_INFO0_EMPTY_DESC)) + goto move_next; + + cookie = le32_to_cpu(mon_dst_desc->cookie); + buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); + + spin_lock_bh(&buf_ring->idr_lock); + skb = idr_remove(&buf_ring->bufs_idr, buf_id); + spin_unlock_bh(&buf_ring->idr_lock); + + if (unlikely(!skb)) { + ath12k_warn(ab, "monitor destination with invalid buf_id %d\n", + buf_id); + goto move_next; + } + + rxcb = ATH12K_SKB_RXCB(skb); + dma_unmap_single(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + end_reason = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_REASON); + + /* HAL_MON_FLUSH_DETECTED implies that an rx flush received at the end of + * rx PPDU and HAL_MON_PPDU_TRUNCATED implies that the PPDU got + * truncated due to a system level error. In both the cases, buffer data + * can be discarded + */ + if ((end_reason == HAL_MON_FLUSH_DETECTED) || + (end_reason == HAL_MON_PPDU_TRUNCATED)) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Monitor dest descriptor end reason %d", end_reason); + dev_kfree_skb_any(skb); + goto move_next; + } + + /* Calculate the budget when the ring descriptor with the + * HAL_MON_END_OF_PPDU to ensure that one PPDU worth of data is always + * reaped. This helps to efficiently utilize the NAPI budget. + */ + if (end_reason == HAL_MON_END_OF_PPDU) { + *budget -= 1; + rxcb->is_end_of_ppdu = true; + } + + end_offset = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_OFFSET); + if (likely(end_offset <= DP_RX_BUFFER_SIZE)) { + skb_put(skb, end_offset); + } else { + ath12k_warn(ab, + "invalid offset on mon stats destination %u\n", + end_offset); + skb_put(skb, DP_RX_BUFFER_SIZE); + } + + __skb_queue_tail(&skb_list, skb); + +move_next: + ath12k_dp_mon_buf_replenish(ab, buf_ring, 1); + ath12k_hal_srng_dst_get_next_entry(ab, srng); + num_buffs_reaped++; + } + + ath12k_hal_srng_access_end(ab, srng); + spin_unlock_bh(&srng->lock); + + if (!num_buffs_reaped) + return 0; + + /* In some cases, one PPDU worth of data can be spread across multiple NAPI + * schedules, To avoid losing existing parsed ppdu_info information, skip + * the memset of the ppdu_info structure and continue processing it. + */ + if (!ppdu_info->ppdu_continuation) + ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); + + while ((skb = __skb_dequeue(&skb_list))) { + hal_status = ath12k_dp_mon_rx_parse_mon_status(pdev_dp, pmon, skb, napi); + if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { + ppdu_info->ppdu_continuation = true; + dev_kfree_skb_any(skb); + continue; + } + + if (ppdu_info->peer_id == HAL_INVALID_PEERID) + goto free_skb; + + rcu_read_lock(); + peer = ath12k_dp_link_peer_find_by_peerid(pdev_dp, ppdu_info->peer_id); + if (!peer || !peer->sta) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "failed to find the peer with monitor peer_id %d\n", + ppdu_info->peer_id); + goto next_skb; + } + + if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { + ath12k_dp_mon_rx_update_peer_su_stats(peer, ppdu_info); + } else if ((ppdu_info->fc_valid) && + (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { + ath12k_dp_mon_rx_process_ulofdma(ppdu_info); + ath12k_dp_mon_rx_update_peer_mu_stats(ab, ppdu_info); + } + +next_skb: + rcu_read_unlock(); +free_skb: + dev_kfree_skb_any(skb); + ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); + } + + return num_buffs_reaped; +} + +int ath12k_wifi7_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, + struct napi_struct *napi, int budget, + enum dp_monitor_mode monitor_mode) +{ + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, mac_id); + struct ath12k_pdev_dp *dp_pdev; + struct ath12k *ar; + int num_buffs_reaped = 0; + + rcu_read_lock(); + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + if (!dp_pdev) { + rcu_read_unlock(); + return 0; + } + + if (dp->hw_params->rxdma1_enable) { + if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) + num_buffs_reaped = ath12k_wifi7_dp_mon_srng_process(dp_pdev, + &budget, + napi); + } else { + ar = ath12k_pdev_dp_to_ar(dp_pdev); + + if (ar->monitor_started) + num_buffs_reaped = + __ath12k_wifi7_dp_mon_process_ring(ar, mac_id, napi, + &budget); + } + + rcu_read_unlock(); + + return num_buffs_reaped; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h new file mode 100644 index 000000000000..3cf82864c41c --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_MON_WIFI7_H +#define ATH12K_DP_MON_WIFI7_H + +#include "hw.h" + +enum dp_monitor_mode; + +int ath12k_wifi7_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, + struct napi_struct *napi, int budget, + enum dp_monitor_mode monitor_mode); +#endif -- 2.34.1 Split Wi-Fi 7-specific monitor status processing out of ath12k common code and into the Wi-Fi 7 module to improve modularity. Move the following functions to wifi7/dp_mon.c and rename them with the ath12k_wifi7_ prefix: - ath12k_dp_mon_rx_parse_mon_status() - ath12k_dp_rx_reap_mon_status_ring() - ath12k_dp_mon_parse_rx_dest() - ath12k_dp_rx_mon_buf_done() - ath12k_dp_rx_mon_dest_process() - ath12k_dp_mon_rx_memset_ppdu_info() Export helper functions required by the Wi-Fi 7 monitor path. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh --- drivers/net/wireless/ath/ath12k/dp_mon.c | 409 +----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 38 +- drivers/net/wireless/ath/ath12k/hal.c | 2 + .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 399 ++++++++++++++++- 4 files changed, 433 insertions(+), 415 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 5e2bf24d6b7e..37a5d46b1ca4 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -1461,7 +1461,7 @@ ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, RX_MSDU_END_INFO11_DECAP_FORMAT); } -static enum hal_rx_mon_status +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) @@ -1733,6 +1733,7 @@ ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, return HAL_RX_MON_STATUS_PPDU_NOT_DONE; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_status_tlv); static void ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, @@ -1761,7 +1762,7 @@ ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, } } -static struct sk_buff +struct sk_buff *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int *buf_id) @@ -1804,46 +1805,7 @@ static struct sk_buff fail_alloc_skb: return NULL; } - -static enum dp_mon_status_buf_state -ath12k_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng, - struct dp_rxdma_mon_ring *rx_ring) -{ - struct ath12k_skb_rxcb *rxcb; - struct hal_tlv_64_hdr *tlv; - struct sk_buff *skb; - void *status_desc; - dma_addr_t paddr; - u32 cookie; - int buf_id; - u8 rbm; - - status_desc = ath12k_hal_srng_src_next_peek(ab, srng); - if (!status_desc) - return DP_MON_STATUS_NO_DMA; - - ath12k_hal_rx_buf_addr_info_get(&ab->hal, status_desc, &paddr, &cookie, &rbm); - - buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); - - spin_lock_bh(&rx_ring->idr_lock); - skb = idr_find(&rx_ring->bufs_idr, buf_id); - spin_unlock_bh(&rx_ring->idr_lock); - - if (!skb) - return DP_MON_STATUS_NO_DMA; - - rxcb = ATH12K_SKB_RXCB(skb); - dma_sync_single_for_cpu(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - tlv = (struct hal_tlv_64_hdr *)skb->data; - if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != HAL_RX_STATUS_BUFFER_DONE) - return DP_MON_STATUS_NO_DMA; - - return DP_MON_STATUS_REPLINISH; -} +EXPORT_SYMBOL(ath12k_dp_rx_alloc_mon_status_buf); static u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) { @@ -2358,10 +2320,10 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } -static int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, - struct dp_mon_mpdu *mon_mpdu, - struct hal_rx_mon_ppdu_info *ppduinfo, - struct napi_struct *napi) +int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, + struct dp_mon_mpdu *mon_mpdu, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct napi_struct *napi) { struct sk_buff *mon_skb, *skb_next, *header; struct ieee80211_rx_status *rxs = &dp_pdev->rx_status; @@ -2412,8 +2374,9 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, } return -EINVAL; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_deliver); -static int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) +int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) { if (skb->len > len) { skb_trim(skb, len); @@ -2430,6 +2393,7 @@ static int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) return 0; } +EXPORT_SYMBOL(ath12k_dp_pkt_set_pktlen); /* Hardware fill buffer with 128 bytes aligned. So need to reap it * with 128 bytes aligned. @@ -2503,7 +2467,7 @@ ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, return 0; } -static int +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, @@ -2540,87 +2504,7 @@ ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, return 0; } - -enum hal_rx_mon_status -ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, - struct sk_buff *skb) -{ - struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); - struct hal_tlv_64_hdr *tlv; - struct ath12k_skb_rxcb *rxcb; - enum hal_rx_mon_status hal_status; - u16 tlv_tag, tlv_len; - u8 *ptr = skb->data; - - do { - tlv = (struct hal_tlv_64_hdr *)ptr; - tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG); - - /* The actual length of PPDU_END is the combined length of many PHY - * TLVs that follow. Skip the TLV header and - * rx_rxpcu_classification_overview that follows the header to get to - * next TLV. - */ - - if (tlv_tag == HAL_RX_PPDU_END) - tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview); - 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); - - if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable && - ath12k_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; - ptr = PTR_ALIGN(ptr, HAL_TLV_64_ALIGN); - - if ((ptr - skb->data) > skb->len) - break; - - } while ((hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE) || - (hal_status == HAL_RX_MON_STATUS_BUF_ADDR) || - (hal_status == HAL_RX_MON_STATUS_MPDU_START) || - (hal_status == HAL_RX_MON_STATUS_MPDU_END) || - (hal_status == HAL_RX_MON_STATUS_MSDU_END)); - - rxcb = ATH12K_SKB_RXCB(skb); - if (rxcb->is_end_of_ppdu) - hal_status = HAL_RX_MON_STATUS_PPDU_DONE; - - return hal_status; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_rx_dest); - -enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - struct sk_buff *skb, - struct napi_struct *napi) -{ - struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - struct dp_mon_mpdu *tmp; - struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; - enum hal_rx_mon_status hal_status; - - hal_status = ath12k_dp_mon_parse_rx_dest(dp_pdev, pmon, skb); - if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) - return hal_status; - - list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) { - list_del(&mon_mpdu->list); - - if (mon_mpdu->head && mon_mpdu->tail) - ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, ppdu_info, napi); - - kfree(mon_mpdu); - } - - return hal_status; -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_mon_status); +EXPORT_SYMBOL(ath12k_dp_mon_parse_rx_dest_tlv); int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *buf_ring, @@ -3766,161 +3650,7 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, } EXPORT_SYMBOL(ath12k_dp_mon_rx_update_peer_mu_stats); -void -ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) -{ - memset(ppdu_info, 0, sizeof(*ppdu_info)); - ppdu_info->peer_id = HAL_INVALID_PEERID; -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_memset_ppdu_info); - -int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, - int *budget, struct sk_buff_head *skb_list) -{ - const struct ath12k_hw_hal_params *hal_params; - int buf_id, srng_id, num_buffs_reaped = 0; - enum dp_mon_status_buf_state reap_status; - struct dp_rxdma_mon_ring *rx_ring; - struct ath12k_mon_data *pmon; - struct ath12k_skb_rxcb *rxcb; - struct hal_tlv_64_hdr *tlv; - void *rx_mon_status_desc; - struct hal_srng *srng; - struct ath12k_dp *dp; - struct sk_buff *skb; - struct ath12k *ar; - dma_addr_t paddr; - u32 cookie; - u8 rbm; - - ar = ab->pdevs[ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id)].ar; - dp = ath12k_ab_to_dp(ab); - pmon = &ar->dp.mon_data; - srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id); - rx_ring = &dp->rx_mon_status_refill_ring[srng_id]; - - srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id]; - - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, srng); - - while (*budget) { - *budget -= 1; - rx_mon_status_desc = ath12k_hal_srng_src_peek(ab, srng); - if (!rx_mon_status_desc) { - pmon->buf_state = DP_MON_STATUS_REPLINISH; - break; - } - ath12k_hal_rx_buf_addr_info_get(&ab->hal, rx_mon_status_desc, &paddr, - &cookie, &rbm); - if (paddr) { - buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); - - spin_lock_bh(&rx_ring->idr_lock); - skb = idr_find(&rx_ring->bufs_idr, buf_id); - spin_unlock_bh(&rx_ring->idr_lock); - - if (!skb) { - ath12k_warn(ab, "rx monitor status with invalid buf_id %d\n", - buf_id); - pmon->buf_state = DP_MON_STATUS_REPLINISH; - goto move_next; - } - - rxcb = ATH12K_SKB_RXCB(skb); - - dma_sync_single_for_cpu(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - tlv = (struct hal_tlv_64_hdr *)skb->data; - if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != - HAL_RX_STATUS_BUFFER_DONE) { - pmon->buf_state = DP_MON_STATUS_NO_DMA; - ath12k_warn(ab, - "mon status DONE not set %llx, buf_id %d\n", - le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG), - buf_id); - /* RxDMA status done bit might not be set even - * though tp is moved by HW. - */ - - /* If done status is missing: - * 1. As per MAC team's suggestion, - * when HP + 1 entry is peeked and if DMA - * is not done and if HP + 2 entry's DMA done - * is set. skip HP + 1 entry and - * start processing in next interrupt. - * 2. If HP + 2 entry's DMA done is not set, - * poll onto HP + 1 entry DMA done to be set. - * Check status for same buffer for next time - * dp_rx_mon_status_srng_process - */ - reap_status = ath12k_dp_rx_mon_buf_done(ab, srng, - rx_ring); - if (reap_status == DP_MON_STATUS_NO_DMA) - continue; - - spin_lock_bh(&rx_ring->idr_lock); - idr_remove(&rx_ring->bufs_idr, buf_id); - spin_unlock_bh(&rx_ring->idr_lock); - - dma_unmap_single(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - dev_kfree_skb_any(skb); - pmon->buf_state = DP_MON_STATUS_REPLINISH; - goto move_next; - } - - spin_lock_bh(&rx_ring->idr_lock); - idr_remove(&rx_ring->bufs_idr, buf_id); - spin_unlock_bh(&rx_ring->idr_lock); - - dma_unmap_single(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - if (ath12k_dp_pkt_set_pktlen(skb, RX_MON_STATUS_BUF_SIZE)) { - dev_kfree_skb_any(skb); - goto move_next; - } - __skb_queue_tail(skb_list, skb); - } else { - pmon->buf_state = DP_MON_STATUS_REPLINISH; - } -move_next: - skb = ath12k_dp_rx_alloc_mon_status_buf(ab, rx_ring, - &buf_id); - hal_params = ab->hal.hal_params; - - if (!skb) { - ath12k_warn(ab, "failed to alloc buffer for status ring\n"); - ath12k_hal_rx_buf_addr_info_set(&ab->hal, rx_mon_status_desc, - 0, 0, hal_params->rx_buf_rbm); - num_buffs_reaped++; - break; - } - rxcb = ATH12K_SKB_RXCB(skb); - - cookie = u32_encode_bits(mac_id, DP_RXDMA_BUF_COOKIE_PDEV_ID) | - u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); - - ath12k_hal_rx_buf_addr_info_set(&ab->hal, rx_mon_status_desc, rxcb->paddr, - cookie, hal_params->rx_buf_rbm); - ath12k_hal_srng_src_get_next_entry(ab, srng); - num_buffs_reaped++; - } - ath12k_hal_srng_access_end(ab, srng); - spin_unlock_bh(&srng->lock); - - return num_buffs_reaped; -} -EXPORT_SYMBOL(ath12k_dp_rx_reap_mon_status_ring); - -static u32 +u32 ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, void *ring_entry, struct sk_buff **head_msdu, struct sk_buff **tail_msdu, @@ -4107,113 +3837,4 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, return rx_bufs_used; } - -/* The destination ring processing is stuck if the destination is not - * moving while status ring moves 16 PPDU. The destination ring processing - * skips this destination ring PPDU as a workaround. - */ -#define MON_DEST_RING_STUCK_MAX_CNT 16 - -void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, - u32 quota, struct napi_struct *napi) -{ - struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; - struct ath12k_pdev_mon_stats *rx_mon_stats; - u32 ppdu_id, rx_bufs_used = 0, ring_id; - u32 mpdu_rx_bufs_used, npackets = 0; - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - void *ring_entry, *mon_dst_srng; - struct dp_mon_mpdu *tmp_mpdu; - LIST_HEAD(rx_desc_used_list); - struct hal_srng *srng; - - ring_id = dp->rxdma_err_dst_ring[mac_id].ring_id; - srng = &ab->hal.srng_list[ring_id]; - - mon_dst_srng = &ab->hal.srng_list[ring_id]; - - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, mon_dst_srng); - - ppdu_id = pmon->mon_ppdu_info.ppdu_id; - rx_mon_stats = &pmon->rx_mon_stats; - - while ((ring_entry = ath12k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) { - struct sk_buff *head_msdu, *tail_msdu; - - head_msdu = NULL; - tail_msdu = NULL; - - mpdu_rx_bufs_used = ath12k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry, - &head_msdu, &tail_msdu, - &rx_desc_used_list, - &npackets, &ppdu_id); - - rx_bufs_used += mpdu_rx_bufs_used; - - if (mpdu_rx_bufs_used) { - dp->mon_dest_ring_stuck_cnt = 0; - } else { - dp->mon_dest_ring_stuck_cnt++; - rx_mon_stats->dest_mon_not_reaped++; - } - - if (dp->mon_dest_ring_stuck_cnt > MON_DEST_RING_STUCK_MAX_CNT) { - rx_mon_stats->dest_mon_stuck++; - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "status ring ppdu_id=%d dest ring ppdu_id=%d mon_dest_ring_stuck_cnt=%d dest_mon_not_reaped=%u dest_mon_stuck=%u\n", - pmon->mon_ppdu_info.ppdu_id, ppdu_id, - dp->mon_dest_ring_stuck_cnt, - rx_mon_stats->dest_mon_not_reaped, - rx_mon_stats->dest_mon_stuck); - spin_lock_bh(&pmon->mon_lock); - pmon->mon_ppdu_info.ppdu_id = ppdu_id; - spin_unlock_bh(&pmon->mon_lock); - continue; - } - - if (ppdu_id != pmon->mon_ppdu_info.ppdu_id) { - spin_lock_bh(&pmon->mon_lock); - pmon->mon_ppdu_status = DP_PPDU_STATUS_START; - spin_unlock_bh(&pmon->mon_lock); - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "dest_rx: new ppdu_id %x != status ppdu_id %x dest_mon_not_reaped = %u dest_mon_stuck = %u\n", - ppdu_id, pmon->mon_ppdu_info.ppdu_id, - rx_mon_stats->dest_mon_not_reaped, - rx_mon_stats->dest_mon_stuck); - break; - } - - if (head_msdu && tail_msdu) { - tmp_mpdu = kzalloc(sizeof(*tmp_mpdu), GFP_ATOMIC); - if (!tmp_mpdu) - break; - - tmp_mpdu->head = head_msdu; - tmp_mpdu->tail = tail_msdu; - tmp_mpdu->err_bitmap = pmon->err_bitmap; - tmp_mpdu->decap_format = pmon->decap_format; - ath12k_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, - &pmon->mon_ppdu_info, napi); - rx_mon_stats->dest_mpdu_done++; - kfree(tmp_mpdu); - } - - ring_entry = ath12k_hal_srng_dst_get_next_entry(ar->ab, - mon_dst_srng); - } - ath12k_hal_srng_access_end(ar->ab, mon_dst_srng); - - spin_unlock_bh(&srng->lock); - - if (rx_bufs_used) { - rx_mon_stats->dest_ppdu_done++; - ath12k_dp_rx_bufs_replenish(ar->ab->dp, - &dp->rx_refill_buf_ring, - &rx_desc_used_list, - rx_bufs_used); - } -} -EXPORT_SYMBOL(ath12k_dp_rx_mon_dest_process); +EXPORT_SYMBOL(ath12k_dp_rx_mon_mpdu_pop); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 689d7a0fff5c..726434ab74ac 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -78,11 +78,6 @@ struct dp_mon_tx_ppdu_info { struct dp_mon_mpdu *tx_mon_mpdu; }; -enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - struct sk_buff *skb, - struct napi_struct *napi); int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *buf_ring, int req_entries); @@ -101,18 +96,33 @@ ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, u32 ppdu_id); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info); -enum hal_rx_mon_status -ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, - struct sk_buff *skb); -int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, - int *budget, struct sk_buff_head *skb_list); -void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, - u32 quota, struct napi_struct *napi); void ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, struct hal_rx_mon_ppdu_info *ppdu_info); -void -ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info); +u32 +ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, + void *ring_entry, struct sk_buff **head_msdu, + struct sk_buff **tail_msdu, + struct list_head *used_list, + u32 *npackets, u32 *ppdu_id); +int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len); +int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, + struct dp_mon_mpdu *mon_mpdu, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct napi_struct *napi); +int +ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + enum hal_rx_mon_status hal_status, + const void *tlv_data); +enum hal_rx_mon_status +ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + const struct hal_tlv_64_hdr *tlv); +struct sk_buff +*ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, + struct dp_rxdma_mon_ring *rx_ring, + int *buf_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index efa039f6df92..91d697ad1799 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -402,6 +402,7 @@ void *ath12k_hal_srng_src_next_peek(struct ath12k_base *ab, return desc; } +EXPORT_SYMBOL(ath12k_hal_srng_src_next_peek); void *ath12k_hal_srng_src_get_next_entry(struct ath12k_base *ab, struct hal_srng *srng) @@ -447,6 +448,7 @@ void *ath12k_hal_srng_src_peek(struct ath12k_base *ab, struct hal_srng *srng) return srng->ring_base_vaddr + srng->u.src_ring.hp; } +EXPORT_SYMBOL(ath12k_hal_srng_src_peek); void *ath12k_hal_srng_src_reap_next(struct ath12k_base *ab, struct hal_srng *srng) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 4135ff5e8759..ffebeb1652e7 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -12,6 +12,390 @@ #include "dp_rx.h" #include "../peer.h" +static void +ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) +{ + memset(ppdu_info, 0, sizeof(*ppdu_info)); + ppdu_info->peer_id = HAL_INVALID_PEERID; +} + +/* The destination ring processing is stuck if the destination is not + * moving while status ring moves 16 PPDU. The destination ring processing + * skips this destination ring PPDU as a workaround. + */ +#define MON_DEST_RING_STUCK_MAX_CNT 16 + +static void +ath12k_wifi7_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, + u32 quota, struct napi_struct *napi) +{ + struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; + struct ath12k_pdev_mon_stats *rx_mon_stats; + u32 ppdu_id, rx_bufs_used = 0, ring_id; + u32 mpdu_rx_bufs_used, npackets = 0; + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + void *ring_entry, *mon_dst_srng; + struct dp_mon_mpdu *tmp_mpdu; + LIST_HEAD(rx_desc_used_list); + struct hal_srng *srng; + + ring_id = dp->rxdma_err_dst_ring[mac_id].ring_id; + srng = &ab->hal.srng_list[ring_id]; + + mon_dst_srng = &ab->hal.srng_list[ring_id]; + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, mon_dst_srng); + + ppdu_id = pmon->mon_ppdu_info.ppdu_id; + rx_mon_stats = &pmon->rx_mon_stats; + + while ((ring_entry = ath12k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) { + struct sk_buff *head_msdu, *tail_msdu; + + head_msdu = NULL; + tail_msdu = NULL; + + mpdu_rx_bufs_used = ath12k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry, + &head_msdu, &tail_msdu, + &rx_desc_used_list, + &npackets, &ppdu_id); + + rx_bufs_used += mpdu_rx_bufs_used; + + if (mpdu_rx_bufs_used) { + dp->mon_dest_ring_stuck_cnt = 0; + } else { + dp->mon_dest_ring_stuck_cnt++; + rx_mon_stats->dest_mon_not_reaped++; + } + + if (dp->mon_dest_ring_stuck_cnt > MON_DEST_RING_STUCK_MAX_CNT) { + rx_mon_stats->dest_mon_stuck++; + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "status ring ppdu_id=%d dest ring ppdu_id=%d mon_dest_ring_stuck_cnt=%d dest_mon_not_reaped=%u dest_mon_stuck=%u\n", + pmon->mon_ppdu_info.ppdu_id, ppdu_id, + dp->mon_dest_ring_stuck_cnt, + rx_mon_stats->dest_mon_not_reaped, + rx_mon_stats->dest_mon_stuck); + spin_lock_bh(&pmon->mon_lock); + pmon->mon_ppdu_info.ppdu_id = ppdu_id; + spin_unlock_bh(&pmon->mon_lock); + continue; + } + + if (ppdu_id != pmon->mon_ppdu_info.ppdu_id) { + spin_lock_bh(&pmon->mon_lock); + pmon->mon_ppdu_status = DP_PPDU_STATUS_START; + spin_unlock_bh(&pmon->mon_lock); + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "dest_rx: new ppdu_id %x != status ppdu_id %x dest_mon_not_reaped = %u dest_mon_stuck = %u\n", + ppdu_id, pmon->mon_ppdu_info.ppdu_id, + rx_mon_stats->dest_mon_not_reaped, + rx_mon_stats->dest_mon_stuck); + break; + } + + if (head_msdu && tail_msdu) { + tmp_mpdu = kzalloc(sizeof(*tmp_mpdu), GFP_ATOMIC); + if (!tmp_mpdu) + break; + + tmp_mpdu->head = head_msdu; + tmp_mpdu->tail = tail_msdu; + tmp_mpdu->err_bitmap = pmon->err_bitmap; + tmp_mpdu->decap_format = pmon->decap_format; + ath12k_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, + &pmon->mon_ppdu_info, napi); + rx_mon_stats->dest_mpdu_done++; + kfree(tmp_mpdu); + } + + ring_entry = ath12k_hal_srng_dst_get_next_entry(ar->ab, + mon_dst_srng); + } + ath12k_hal_srng_access_end(ar->ab, mon_dst_srng); + + spin_unlock_bh(&srng->lock); + + if (rx_bufs_used) { + rx_mon_stats->dest_ppdu_done++; + ath12k_dp_rx_bufs_replenish(ar->ab->dp, + &dp->rx_refill_buf_ring, + &rx_desc_used_list, + rx_bufs_used); + } +} + +static enum dp_mon_status_buf_state +ath12k_wifi7_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng, + struct dp_rxdma_mon_ring *rx_ring) +{ + struct ath12k_skb_rxcb *rxcb; + struct hal_tlv_64_hdr *tlv; + struct sk_buff *skb; + void *status_desc; + dma_addr_t paddr; + u32 cookie; + int buf_id; + u8 rbm; + + status_desc = ath12k_hal_srng_src_next_peek(ab, srng); + if (!status_desc) + return DP_MON_STATUS_NO_DMA; + + ath12k_wifi7_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm); + + buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); + + spin_lock_bh(&rx_ring->idr_lock); + skb = idr_find(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + + if (!skb) + return DP_MON_STATUS_NO_DMA; + + rxcb = ATH12K_SKB_RXCB(skb); + dma_sync_single_for_cpu(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + tlv = (struct hal_tlv_64_hdr *)skb->data; + if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != HAL_RX_STATUS_BUFFER_DONE) + return DP_MON_STATUS_NO_DMA; + + return DP_MON_STATUS_REPLINISH; +} + +static enum hal_rx_mon_status +ath12k_wifi7_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + struct sk_buff *skb) +{ + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + struct hal_tlv_64_hdr *tlv; + struct ath12k_skb_rxcb *rxcb; + enum hal_rx_mon_status hal_status; + u16 tlv_tag, tlv_len; + u8 *ptr = skb->data; + + do { + tlv = (struct hal_tlv_64_hdr *)ptr; + tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG); + + /* The actual length of PPDU_END is the combined length of many PHY + * TLVs that follow. Skip the TLV header and + * rx_rxpcu_classification_overview that follows the header to get to + * next TLV. + */ + + if (tlv_tag == HAL_RX_PPDU_END) + tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview); + 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); + + if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable && + ath12k_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; + ptr = PTR_ALIGN(ptr, HAL_TLV_64_ALIGN); + + if ((ptr - skb->data) > skb->len) + break; + + } while ((hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE) || + (hal_status == HAL_RX_MON_STATUS_BUF_ADDR) || + (hal_status == HAL_RX_MON_STATUS_MPDU_START) || + (hal_status == HAL_RX_MON_STATUS_MPDU_END) || + (hal_status == HAL_RX_MON_STATUS_MSDU_END)); + + rxcb = ATH12K_SKB_RXCB(skb); + if (rxcb->is_end_of_ppdu) + hal_status = HAL_RX_MON_STATUS_PPDU_DONE; + + return hal_status; +} + +static enum hal_rx_mon_status +ath12k_wifi7_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + struct sk_buff *skb, + struct napi_struct *napi) +{ + struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; + struct dp_mon_mpdu *tmp; + struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; + enum hal_rx_mon_status hal_status; + + hal_status = ath12k_wifi7_dp_mon_parse_rx_dest(dp_pdev, pmon, skb); + if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) + return hal_status; + + list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) { + list_del(&mon_mpdu->list); + + if (mon_mpdu->head && mon_mpdu->tail) + ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, ppdu_info, napi); + + kfree(mon_mpdu); + } + + return hal_status; +} + +static int +ath12k_wifi7_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, + int *budget, struct sk_buff_head *skb_list) +{ + const struct ath12k_hw_hal_params *hal_params; + int buf_id, srng_id, num_buffs_reaped = 0; + enum dp_mon_status_buf_state reap_status; + struct dp_rxdma_mon_ring *rx_ring; + struct ath12k_mon_data *pmon; + struct ath12k_skb_rxcb *rxcb; + struct hal_tlv_64_hdr *tlv; + void *rx_mon_status_desc; + struct hal_srng *srng; + struct ath12k_dp *dp; + struct sk_buff *skb; + struct ath12k *ar; + dma_addr_t paddr; + u32 cookie; + u8 rbm; + + ar = ab->pdevs[ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id)].ar; + dp = ath12k_ab_to_dp(ab); + pmon = &ar->dp.mon_data; + srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id); + rx_ring = &dp->rx_mon_status_refill_ring[srng_id]; + + srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id]; + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + while (*budget) { + *budget -= 1; + rx_mon_status_desc = ath12k_hal_srng_src_peek(ab, srng); + if (!rx_mon_status_desc) { + pmon->buf_state = DP_MON_STATUS_REPLINISH; + break; + } + ath12k_wifi7_hal_rx_buf_addr_info_get(rx_mon_status_desc, &paddr, + &cookie, &rbm); + if (paddr) { + buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); + + spin_lock_bh(&rx_ring->idr_lock); + skb = idr_find(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + + if (!skb) { + ath12k_warn(ab, "rx monitor status with invalid buf_id %d\n", + buf_id); + pmon->buf_state = DP_MON_STATUS_REPLINISH; + goto move_next; + } + + rxcb = ATH12K_SKB_RXCB(skb); + + dma_sync_single_for_cpu(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + tlv = (struct hal_tlv_64_hdr *)skb->data; + if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != + HAL_RX_STATUS_BUFFER_DONE) { + pmon->buf_state = DP_MON_STATUS_NO_DMA; + ath12k_warn(ab, + "mon status DONE not set %llx, buf_id %d\n", + le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG), + buf_id); + /* RxDMA status done bit might not be set even + * though tp is moved by HW. + */ + + /* If done status is missing: + * 1. As per MAC team's suggestion, + * when HP + 1 entry is peeked and if DMA + * is not done and if HP + 2 entry's DMA done + * is set. skip HP + 1 entry and + * start processing in next interrupt. + * 2. If HP + 2 entry's DMA done is not set, + * poll onto HP + 1 entry DMA done to be set. + * Check status for same buffer for next time + * dp_rx_mon_status_srng_process + */ + reap_status = ath12k_wifi7_dp_rx_mon_buf_done(ab, srng, + rx_ring); + if (reap_status == DP_MON_STATUS_NO_DMA) + continue; + + spin_lock_bh(&rx_ring->idr_lock); + idr_remove(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + + dma_unmap_single(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + dev_kfree_skb_any(skb); + pmon->buf_state = DP_MON_STATUS_REPLINISH; + goto move_next; + } + + spin_lock_bh(&rx_ring->idr_lock); + idr_remove(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + + dma_unmap_single(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + if (ath12k_dp_pkt_set_pktlen(skb, RX_MON_STATUS_BUF_SIZE)) { + dev_kfree_skb_any(skb); + goto move_next; + } + __skb_queue_tail(skb_list, skb); + } else { + pmon->buf_state = DP_MON_STATUS_REPLINISH; + } +move_next: + skb = ath12k_dp_rx_alloc_mon_status_buf(ab, rx_ring, + &buf_id); + hal_params = ab->hal.hal_params; + + if (!skb) { + ath12k_warn(ab, "failed to alloc buffer for status ring\n"); + ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, + 0, 0, + hal_params->rx_buf_rbm); + num_buffs_reaped++; + break; + } + rxcb = ATH12K_SKB_RXCB(skb); + + cookie = u32_encode_bits(mac_id, DP_RXDMA_BUF_COOKIE_PDEV_ID) | + u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); + + ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, + cookie, hal_params->rx_buf_rbm); + ath12k_hal_srng_src_get_next_entry(ab, srng); + num_buffs_reaped++; + } + ath12k_hal_srng_access_end(ab, srng); + spin_unlock_bh(&srng->lock); + + return num_buffs_reaped; +} + static int __ath12k_wifi7_dp_mon_process_ring(struct ath12k *ar, int mac_id, struct napi_struct *napi, int *budget) @@ -26,8 +410,8 @@ __ath12k_wifi7_dp_mon_process_ring(struct ath12k *ar, int mac_id, __skb_queue_head_init(&skb_list); - num_buffs_reaped = ath12k_dp_rx_reap_mon_status_ring(ar->ab, mac_id, - budget, &skb_list); + num_buffs_reaped = ath12k_wifi7_dp_rx_reap_mon_status_ring(ar->ab, mac_id, + budget, &skb_list); if (!num_buffs_reaped) goto exit; @@ -35,14 +419,14 @@ __ath12k_wifi7_dp_mon_process_ring(struct ath12k *ar, int mac_id, memset(ppdu_info, 0, sizeof(*ppdu_info)); ppdu_info->peer_id = HAL_INVALID_PEERID; - hal_status = ath12k_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); + hal_status = ath12k_wifi7_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); if (ar->monitor_started && pmon->mon_ppdu_status == DP_PPDU_STATUS_START && hal_status == HAL_TLV_STATUS_PPDU_DONE) { rx_mon_stats->status_ppdu_done++; pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; - ath12k_dp_rx_mon_dest_process(ar, mac_id, *budget, napi); + ath12k_wifi7_dp_rx_mon_dest_process(ar, mac_id, *budget, napi); pmon->mon_ppdu_status = DP_PPDU_STATUS_START; } @@ -167,10 +551,11 @@ ath12k_wifi7_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, * the memset of the ppdu_info structure and continue processing it. */ if (!ppdu_info->ppdu_continuation) - ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); + ath12k_wifi7_dp_mon_rx_memset_ppdu_info(ppdu_info); while ((skb = __skb_dequeue(&skb_list))) { - hal_status = ath12k_dp_mon_rx_parse_mon_status(pdev_dp, pmon, skb, napi); + hal_status = ath12k_wifi7_dp_mon_rx_parse_mon_status(pdev_dp, pmon, + skb, napi); if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { ppdu_info->ppdu_continuation = true; dev_kfree_skb_any(skb); @@ -201,7 +586,7 @@ ath12k_wifi7_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, rcu_read_unlock(); free_skb: dev_kfree_skb_any(skb); - ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); + ath12k_wifi7_dp_mon_rx_memset_ppdu_info(ppdu_info); } return num_buffs_reaped; -- 2.34.1 Separate Wi-Fi 7-specific monitor code from ath12k common code to improve modularity. Move the following monitor MPDU pop function to the new file wifi7/dp_mon.c and rename them with the ath12k_wifi7_ prefix: - ath12k_dp_rx_mon_mpdu_pop() Export helper functions required by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh --- drivers/net/wireless/ath/ath12k/dp_mon.c | 207 +----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 15 +- drivers/net/wireless/ath/ath12k/hal.h | 5 + .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 201 ++++++++++++++++- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 11 + drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 3 + .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 5 - 7 files changed, 230 insertions(+), 217 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 37a5d46b1ca4..16361dd77a6a 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -17,16 +17,6 @@ #define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) -static bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc) -{ - u32 tlv_tag; - - tlv_tag = ab->hal.ops->rx_desc_get_mpdu_start_tag(rx_desc); - - return tlv_tag == HAL_RX_MPDU_START; -} - static 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) @@ -1807,7 +1797,7 @@ struct sk_buff } EXPORT_SYMBOL(ath12k_dp_rx_alloc_mon_status_buf); -static u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) +u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) { u32 ret = 0; @@ -1826,8 +1816,8 @@ static u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) } return ret; } +EXPORT_SYMBOL(ath12k_dp_mon_comp_ppduid); -static void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, struct hal_rx_msdu_link *msdu_link, dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, @@ -1841,6 +1831,7 @@ void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, *pp_buf_addr_info = buf_addr_info; } +EXPORT_SYMBOL(ath12k_dp_mon_next_link_desc_get); static void ath12k_dp_mon_fill_rx_rate(struct ath12k_pdev_dp *dp_pdev, @@ -2400,7 +2391,7 @@ EXPORT_SYMBOL(ath12k_dp_pkt_set_pktlen); */ #define RXDMA_DATA_DMA_BLOCK_SIZE 128 -static void +void ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, bool *is_frag, u32 *total_len, u32 *frag_len, u32 *msdu_cnt) @@ -2420,6 +2411,7 @@ ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, *msdu_cnt -= 1; } } +EXPORT_SYMBOL(ath12k_dp_mon_get_buf_len); static int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, @@ -3649,192 +3641,3 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, ath12k_dp_mon_rx_update_user_stats(ab, ppdu_info, i); } EXPORT_SYMBOL(ath12k_dp_mon_rx_update_peer_mu_stats); - -u32 -ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, - void *ring_entry, struct sk_buff **head_msdu, - struct sk_buff **tail_msdu, - struct list_head *used_list, - u32 *npackets, u32 *ppdu_id) -{ - struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - struct ath12k_buffer_addr *p_buf_addr_info, *p_last_buf_addr_info; - u32 msdu_ppdu_id = 0, msdu_cnt = 0, total_len = 0, frag_len = 0; - u32 rx_buf_size, rx_pkt_offset, sw_cookie; - bool is_frag, is_first_msdu, drop_mpdu = false; - struct hal_reo_entrance_ring *ent_desc = - (struct hal_reo_entrance_ring *)ring_entry; - u32 rx_bufs_used = 0, i = 0, desc_bank = 0; - struct hal_rx_desc *rx_desc, *tail_rx_desc; - struct hal_rx_msdu_link *msdu_link_desc; - struct sk_buff *msdu = NULL, *last = NULL; - struct ath12k_rx_desc_info *desc_info; - struct ath12k_buffer_addr buf_info; - struct hal_rx_msdu_list msdu_list; - struct ath12k_skb_rxcb *rxcb; - u16 num_msdus = 0; - dma_addr_t paddr; - u8 rbm; - - ath12k_hal_rx_reo_ent_buf_paddr_get(&ab->hal, ring_entry, &paddr, - &sw_cookie, - &p_last_buf_addr_info, &rbm, - &msdu_cnt); - - spin_lock_bh(&pmon->mon_lock); - - if (le32_get_bits(ent_desc->info1, - HAL_REO_ENTR_RING_INFO1_RXDMA_PUSH_REASON) == - HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) { - u8 rxdma_err = le32_get_bits(ent_desc->info1, - HAL_REO_ENTR_RING_INFO1_RXDMA_ERROR_CODE); - if (rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR || - rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR || - rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR) { - drop_mpdu = true; - pmon->rx_mon_stats.dest_mpdu_drop++; - } - } - - is_frag = false; - is_first_msdu = true; - rx_pkt_offset = sizeof(struct hal_rx_desc); - - do { - if (pmon->mon_last_linkdesc_paddr == paddr) { - pmon->rx_mon_stats.dup_mon_linkdesc_cnt++; - spin_unlock_bh(&pmon->mon_lock); - return rx_bufs_used; - } - - desc_bank = u32_get_bits(sw_cookie, DP_LINK_DESC_BANK_MASK); - msdu_link_desc = - dp->link_desc_banks[desc_bank].vaddr + - (paddr - dp->link_desc_banks[desc_bank].paddr); - - ath12k_hal_rx_msdu_list_get(&ar->ab->hal, ar, msdu_link_desc, &msdu_list, - &num_msdus); - desc_info = ath12k_dp_get_rx_desc(ar->ab->dp, - msdu_list.sw_cookie[num_msdus - 1]); - tail_rx_desc = (struct hal_rx_desc *)(desc_info->skb)->data; - - for (i = 0; i < num_msdus; i++) { - u32 l2_hdr_offset; - - if (pmon->mon_last_buf_cookie == msdu_list.sw_cookie[i]) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "i %d last_cookie %d is same\n", - i, pmon->mon_last_buf_cookie); - drop_mpdu = true; - pmon->rx_mon_stats.dup_mon_buf_cnt++; - continue; - } - - desc_info = - ath12k_dp_get_rx_desc(ar->ab->dp, msdu_list.sw_cookie[i]); - msdu = desc_info->skb; - - if (!msdu) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "msdu_pop: invalid msdu (%d/%d)\n", - i + 1, num_msdus); - goto next_msdu; - } - rxcb = ATH12K_SKB_RXCB(msdu); - if (rxcb->paddr != msdu_list.paddr[i]) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "i %d paddr %lx != %lx\n", - i, (unsigned long)rxcb->paddr, - (unsigned long)msdu_list.paddr[i]); - drop_mpdu = true; - continue; - } - if (!rxcb->unmapped) { - dma_unmap_single(ar->ab->dev, rxcb->paddr, - msdu->len + - skb_tailroom(msdu), - DMA_FROM_DEVICE); - rxcb->unmapped = 1; - } - if (drop_mpdu) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "i %d drop msdu %p *ppdu_id %x\n", - i, msdu, *ppdu_id); - dev_kfree_skb_any(msdu); - msdu = NULL; - goto next_msdu; - } - - rx_desc = (struct hal_rx_desc *)msdu->data; - l2_hdr_offset = ath12k_dp_rx_h_l3pad(ar->ab, tail_rx_desc); - if (is_first_msdu) { - if (!ath12k_dp_rxdesc_mpdu_valid(ar->ab, rx_desc)) { - drop_mpdu = true; - dev_kfree_skb_any(msdu); - msdu = NULL; - pmon->mon_last_linkdesc_paddr = paddr; - goto next_msdu; - } - msdu_ppdu_id = - ath12k_dp_rxdesc_get_ppduid(ar->ab, rx_desc); - - if (ath12k_dp_mon_comp_ppduid(msdu_ppdu_id, - ppdu_id)) { - spin_unlock_bh(&pmon->mon_lock); - return rx_bufs_used; - } - pmon->mon_last_linkdesc_paddr = paddr; - is_first_msdu = false; - } - ath12k_dp_mon_get_buf_len(&msdu_list.msdu_info[i], - &is_frag, &total_len, - &frag_len, &msdu_cnt); - rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len; - - if (ath12k_dp_pkt_set_pktlen(msdu, rx_buf_size)) { - dev_kfree_skb_any(msdu); - goto next_msdu; - } - - if (!(*head_msdu)) - *head_msdu = msdu; - else if (last) - last->next = msdu; - - last = msdu; -next_msdu: - pmon->mon_last_buf_cookie = msdu_list.sw_cookie[i]; - rx_bufs_used++; - desc_info->skb = NULL; - list_add_tail(&desc_info->list, used_list); - } - - ath12k_hal_rx_buf_addr_info_set(&ab->hal, &buf_info, paddr, - sw_cookie, rbm); - - ath12k_dp_mon_next_link_desc_get(ab, msdu_link_desc, &paddr, - &sw_cookie, &rbm, - &p_buf_addr_info); - - ath12k_dp_arch_rx_link_desc_return(ar->ab->dp, &buf_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); - - p_last_buf_addr_info = p_buf_addr_info; - - } while (paddr && msdu_cnt); - - spin_unlock_bh(&pmon->mon_lock); - - if (last) - last->next = NULL; - - *tail_msdu = msdu; - - if (msdu_cnt == 0) - *npackets = 1; - - return rx_bufs_used; -} -EXPORT_SYMBOL(ath12k_dp_rx_mon_mpdu_pop); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 726434ab74ac..425bec6f0f3c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -101,12 +101,6 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, struct hal_rx_mon_ppdu_info *ppdu_info); -u32 -ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, - void *ring_entry, struct sk_buff **head_msdu, - struct sk_buff **tail_msdu, - struct list_head *used_list, - u32 *npackets, u32 *ppdu_id); int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len); int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, @@ -125,4 +119,13 @@ struct sk_buff *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int *buf_id); +void +ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, + bool *is_frag, u32 *total_len, + u32 *frag_len, u32 *msdu_cnt); +void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, + struct hal_rx_msdu_link *msdu_link, + 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); #endif diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 071f4897e4cd..1d22173975f0 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -592,6 +592,11 @@ struct hal_rx_eht_info { u32 user_info[EHT_MAX_USER_INFO]; }; +struct hal_rx_msdu_desc_info { + u32 msdu_flags; + u16 msdu_len; /* 14 bits for length */ +}; + struct hal_rx_mon_ppdu_info { u32 ppdu_id; u32 last_ppdu_id; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index ffebeb1652e7..dae3f262cc50 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -19,6 +19,196 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static u32 +ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, + void *ring_entry, struct sk_buff **head_msdu, + struct sk_buff **tail_msdu, + struct list_head *used_list, + u32 *npackets, u32 *ppdu_id) +{ + struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_buffer_addr *p_buf_addr_info, *p_last_buf_addr_info; + u32 msdu_ppdu_id = 0, msdu_cnt = 0, total_len = 0, frag_len = 0; + u32 rx_buf_size, rx_pkt_offset, sw_cookie; + bool is_frag, is_first_msdu, drop_mpdu = false; + struct hal_reo_entrance_ring *ent_desc = + (struct hal_reo_entrance_ring *)ring_entry; + u32 rx_bufs_used = 0, i = 0, desc_bank = 0; + struct hal_rx_desc *rx_desc, *tail_rx_desc; + struct hal_rx_msdu_link *msdu_link_desc; + struct sk_buff *msdu = NULL, *last = NULL; + struct ath12k_rx_desc_info *desc_info; + struct ath12k_buffer_addr buf_info; + struct hal_rx_msdu_list msdu_list; + struct ath12k_skb_rxcb *rxcb; + u16 num_msdus = 0; + dma_addr_t paddr; + u8 rbm; + + ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get(ring_entry, &paddr, + &sw_cookie, + &p_last_buf_addr_info, + &rbm, + &msdu_cnt); + + spin_lock_bh(&pmon->mon_lock); + + if (le32_get_bits(ent_desc->info1, + HAL_REO_ENTR_RING_INFO1_RXDMA_PUSH_REASON) == + HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) { + u8 rxdma_err = le32_get_bits(ent_desc->info1, + HAL_REO_ENTR_RING_INFO1_RXDMA_ERROR_CODE); + if (rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR || + rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR || + rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR) { + drop_mpdu = true; + pmon->rx_mon_stats.dest_mpdu_drop++; + } + } + + is_frag = false; + is_first_msdu = true; + rx_pkt_offset = sizeof(struct hal_rx_desc); + + do { + if (pmon->mon_last_linkdesc_paddr == paddr) { + pmon->rx_mon_stats.dup_mon_linkdesc_cnt++; + spin_unlock_bh(&pmon->mon_lock); + return rx_bufs_used; + } + + desc_bank = u32_get_bits(sw_cookie, DP_LINK_DESC_BANK_MASK); + msdu_link_desc = + dp->link_desc_banks[desc_bank].vaddr + + (paddr - dp->link_desc_banks[desc_bank].paddr); + + ath12k_wifi7_hal_rx_msdu_list_get(ar, msdu_link_desc, &msdu_list, + &num_msdus); + desc_info = ath12k_dp_get_rx_desc(ar->ab->dp, + msdu_list.sw_cookie[num_msdus - 1]); + tail_rx_desc = (struct hal_rx_desc *)(desc_info->skb)->data; + + for (i = 0; i < num_msdus; i++) { + u32 l2_hdr_offset; + + if (pmon->mon_last_buf_cookie == msdu_list.sw_cookie[i]) { + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "i %d last_cookie %d is same\n", + i, pmon->mon_last_buf_cookie); + drop_mpdu = true; + pmon->rx_mon_stats.dup_mon_buf_cnt++; + continue; + } + + desc_info = + ath12k_dp_get_rx_desc(ar->ab->dp, msdu_list.sw_cookie[i]); + msdu = desc_info->skb; + + if (!msdu) { + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "msdu_pop: invalid msdu (%d/%d)\n", + i + 1, num_msdus); + goto next_msdu; + } + rxcb = ATH12K_SKB_RXCB(msdu); + if (rxcb->paddr != msdu_list.paddr[i]) { + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "i %d paddr %lx != %lx\n", + i, (unsigned long)rxcb->paddr, + (unsigned long)msdu_list.paddr[i]); + drop_mpdu = true; + continue; + } + if (!rxcb->unmapped) { + dma_unmap_single(ar->ab->dev, rxcb->paddr, + msdu->len + + skb_tailroom(msdu), + DMA_FROM_DEVICE); + rxcb->unmapped = 1; + } + if (drop_mpdu) { + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "i %d drop msdu %p *ppdu_id %x\n", + i, msdu, *ppdu_id); + dev_kfree_skb_any(msdu); + msdu = NULL; + goto next_msdu; + } + + rx_desc = (struct hal_rx_desc *)msdu->data; + l2_hdr_offset = ath12k_dp_rx_h_l3pad(ar->ab, tail_rx_desc); + if (is_first_msdu) { + if (!ath12k_wifi7_dp_rxdesc_mpdu_valid(ar->ab, + rx_desc)) { + drop_mpdu = true; + dev_kfree_skb_any(msdu); + msdu = NULL; + pmon->mon_last_linkdesc_paddr = paddr; + goto next_msdu; + } + msdu_ppdu_id = + ath12k_dp_rxdesc_get_ppduid(ar->ab, rx_desc); + + if (ath12k_dp_mon_comp_ppduid(msdu_ppdu_id, + ppdu_id)) { + spin_unlock_bh(&pmon->mon_lock); + return rx_bufs_used; + } + pmon->mon_last_linkdesc_paddr = paddr; + is_first_msdu = false; + } + ath12k_dp_mon_get_buf_len(&msdu_list.msdu_info[i], + &is_frag, &total_len, + &frag_len, &msdu_cnt); + rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len; + + if (ath12k_dp_pkt_set_pktlen(msdu, rx_buf_size)) { + dev_kfree_skb_any(msdu); + goto next_msdu; + } + + if (!(*head_msdu)) + *head_msdu = msdu; + else if (last) + last->next = msdu; + + last = msdu; +next_msdu: + pmon->mon_last_buf_cookie = msdu_list.sw_cookie[i]; + rx_bufs_used++; + desc_info->skb = NULL; + list_add_tail(&desc_info->list, used_list); + } + + ath12k_wifi7_hal_rx_buf_addr_info_set(&buf_info, paddr, + sw_cookie, rbm); + + ath12k_dp_mon_next_link_desc_get(ab, msdu_link_desc, &paddr, + &sw_cookie, &rbm, + &p_buf_addr_info); + + ath12k_dp_arch_rx_link_desc_return(ar->ab->dp, &buf_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + + p_last_buf_addr_info = p_buf_addr_info; + + } while (paddr && msdu_cnt); + + spin_unlock_bh(&pmon->mon_lock); + + if (last) + last->next = NULL; + + *tail_msdu = msdu; + + if (msdu_cnt == 0) + *npackets = 1; + + return rx_bufs_used; +} + /* The destination ring processing is stuck if the destination is not * moving while status ring moves 16 PPDU. The destination ring processing * skips this destination ring PPDU as a workaround. @@ -58,10 +248,13 @@ ath12k_wifi7_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, head_msdu = NULL; tail_msdu = NULL; - mpdu_rx_bufs_used = ath12k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry, - &head_msdu, &tail_msdu, - &rx_desc_used_list, - &npackets, &ppdu_id); + mpdu_rx_bufs_used = ath12k_wifi7_dp_rx_mon_mpdu_pop(ar, mac_id, + ring_entry, + &head_msdu, + &tail_msdu, + &rx_desc_used_list, + &npackets, + &ppdu_id); rx_bufs_used += mpdu_rx_bufs_used; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 2138b20a04d5..08dcf170b801 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -2141,3 +2141,14 @@ void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp) spin_unlock_bh(&srng->lock); } + +bool +ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc) +{ + u32 tlv_tag; + + tlv_tag = ab->hal.ops->rx_desc_get_mpdu_start_tag(rx_desc); + + return tlv_tag == HAL_RX_MPDU_START; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index b92f9cf173dc..2d3eb2313b2f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -49,6 +49,9 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, bool update_ssn); +bool +ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc); static inline void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_hal *hal, struct hal_rx_desc_data *rx_info, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index 2715b7d52cfc..c5a2125a04af 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -313,11 +313,6 @@ struct hal_rx_rxpcu_classification_overview { u32 rsvd0; } __packed; -struct hal_rx_msdu_desc_info { - u32 msdu_flags; - u16 msdu_len; /* 14 bits for length */ -}; - #define HAL_RX_NUM_MSDU_DESC 6 struct hal_rx_msdu_list { struct hal_rx_msdu_desc_info msdu_info[HAL_RX_NUM_MSDU_DESC]; -- 2.34.1 Split Wi-Fi 7-specific monitor code out of ath12k common code to improve modularity. Move following RX status TLV parsing functions to the new file wifi7/dp_mon.c and rename the helpers with the ath12k_wifi7_ prefix: - ath12k_dp_mon_rx_parse_status_tlv() - ath12k_dp_mon_parse_rx_dest_tlv() Export helper functions required by the Wi-Fi 7 module. Temporarily include wifi7/hal_rx.h from dp_mon.h to provide HAL structure definitions; remove this dependency in a later patch. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh --- drivers/net/wireless/ath/ath12k/dp_mon.c | 374 ++---------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 59 ++- .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 319 ++++++++++++++- 3 files changed, 405 insertions(+), 347 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 16361dd77a6a..dc4827771a64 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -17,7 +17,7 @@ #define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) -static void +void ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status) { @@ -26,6 +26,7 @@ ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->usr_resp_ref_ext); } +EXPORT_SYMBOL(ath12k_dp_mon_rx_handle_ofdma_info); static void ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats, @@ -40,7 +41,7 @@ ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *st HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_ERR_BYTE_COUNT); } -static void +void ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, struct hal_rx_mon_ppdu_info *ppdu_info, struct hal_rx_user_status *rx_user_status) @@ -78,9 +79,10 @@ ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats * ath12k_dp_mon_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); } +EXPORT_SYMBOL(ath12k_dp_mon_rx_populate_mu_user_info); -static void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 nsts, info0, info1; u8 gi_setting; @@ -118,9 +120,10 @@ static void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vh ppdu_info->vht_flag_values4 = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); } +EXPORT_SYMBOL(ath12k_dp_mon_parse_vht_sig_a); -static void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 info0 = __le32_to_cpu(ht_sig->info0); u32 info1 = __le32_to_cpu(ht_sig->info1); @@ -132,9 +135,10 @@ static void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI); ppdu_info->nss = (ppdu_info->mcs >> 3); } +EXPORT_SYMBOL(ath12k_dp_mon_parse_ht_sig); -static void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 info0 = __le32_to_cpu(lsigb->info0); u8 rate; @@ -163,9 +167,10 @@ static void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, ppdu_info->rate = rate; ppdu_info->cck_flag = 1; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_b); -static void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 info0 = __le32_to_cpu(lsiga->info0); u8 rate; @@ -202,8 +207,9 @@ static void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, ppdu_info->rate = rate; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_a); -static void +void ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -238,8 +244,9 @@ ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *of ppdu_info->beamformed = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF); } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b2_ofdma); -static void +void ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -264,8 +271,9 @@ ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS); } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b2_mu); -static void +void ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -277,8 +285,9 @@ ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); ppdu_info->he_RU[0] = ru_tones; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b1_mu); -static void +void ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -410,9 +419,10 @@ ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_ ppdu_info->is_stbc = info1 & HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_mu); -static void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 info0, info1, value; u32 dcm; @@ -557,6 +567,7 @@ static void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info * ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); ppdu_info->dcm = dcm; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_su); static void ath12k_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn, @@ -731,7 +742,7 @@ ath12k_dp_mon_hal_rx_parse_u_sig_mu(const struct hal_mon_usig_mu *usig_mu, usig->mask = cpu_to_le32(mask); } -static void +void ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -749,8 +760,9 @@ ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, else ath12k_dp_mon_hal_rx_parse_u_sig_mu(&usig->non_cmn.mu, ppdu_info); } +EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_u_sig_hdr); -static void +void ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, u16 tlv_len, const void *tlv_data) { @@ -760,6 +772,7 @@ ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, ppdu_info->tlv_aggr.cur_len += tlv_len; } } +EXPORT_SYMBOL(ath12k_dp_mon_hal_aggr_tlv); static inline bool ath12k_dp_mon_hal_rx_is_frame_type_ndp(const struct hal_rx_u_sig_info *usig_info) @@ -1117,7 +1130,7 @@ ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(const void *tlv, ppdu_info); } -static void +void ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, const void *tlv_data) { @@ -1130,6 +1143,7 @@ ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, else if (ath12k_dp_mon_hal_rx_is_ofdma(&ppdu_info->u_sig_info)) ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info); } +EXPORT_SYMBOL(ath12k_dp_mon_parse_eht_sig_hdr); static inline enum ath12k_eht_ru_size hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) @@ -1215,7 +1229,7 @@ hal_rx_ul_ofdma_ru_size_to_width(enum ath12k_eht_ru_size ru_size) } } -static void +void ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, u16 user_id, struct hal_rx_mon_ppdu_info *ppdu_info) @@ -1416,6 +1430,7 @@ ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_ mon_rx_user_status->ofdma_info_valid = 1; } } +EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_user_info); static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) { @@ -1441,7 +1456,7 @@ static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) *errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; } -static void +void ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, const struct hal_rx_msdu_end *msdu_end) { @@ -1450,280 +1465,7 @@ ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, pmon->decap_format = le32_get_bits(msdu_end->info1, RX_MSDU_END_INFO11_DECAP_FORMAT); } - -enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - const struct hal_tlv_64_hdr *tlv) -{ - struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - const void *tlv_data = tlv->value; - u32 info[7], userid; - u16 tlv_tag, tlv_len; - - tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG); - tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); - userid = le64_get_bits(tlv->tl, HAL_TLV_64_USR_ID); - - if (ppdu_info->tlv_aggr.in_progress && ppdu_info->tlv_aggr.tlv_tag != tlv_tag) { - ath12k_dp_mon_parse_eht_sig_hdr(ppdu_info, ppdu_info->tlv_aggr.buf); - - ppdu_info->tlv_aggr.in_progress = false; - ppdu_info->tlv_aggr.cur_len = 0; - } - - switch (tlv_tag) { - case HAL_RX_PPDU_START: { - const struct hal_rx_ppdu_start *ppdu_start = tlv_data; - - u64 ppdu_ts = ath12k_le32hilo_to_u64(ppdu_start->ppdu_start_ts_63_32, - ppdu_start->ppdu_start_ts_31_0); - - info[0] = __le32_to_cpu(ppdu_start->info0); - - ppdu_info->ppdu_id = u32_get_bits(info[0], - HAL_RX_PPDU_START_INFO0_PPDU_ID); - - info[1] = __le32_to_cpu(ppdu_start->info1); - ppdu_info->chan_num = u32_get_bits(info[1], - HAL_RX_PPDU_START_INFO1_CHAN_NUM); - ppdu_info->freq = u32_get_bits(info[1], - HAL_RX_PPDU_START_INFO1_CHAN_FREQ); - ppdu_info->ppdu_ts = ppdu_ts; - - if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) { - ppdu_info->last_ppdu_id = ppdu_info->ppdu_id; - ppdu_info->num_users = 0; - memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0, - HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * - sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); - } - break; - } - case HAL_RX_PPDU_END_USER_STATS: { - const struct hal_rx_ppdu_end_user_stats *eu_stats = tlv_data; - u32 tid_bitmap; - - info[0] = __le32_to_cpu(eu_stats->info0); - info[1] = __le32_to_cpu(eu_stats->info1); - info[2] = __le32_to_cpu(eu_stats->info2); - info[4] = __le32_to_cpu(eu_stats->info4); - info[5] = __le32_to_cpu(eu_stats->info5); - info[6] = __le32_to_cpu(eu_stats->info6); - - ppdu_info->ast_index = - u32_get_bits(info[2], HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX); - ppdu_info->fc_valid = - u32_get_bits(info[1], HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID); - tid_bitmap = u32_get_bits(info[6], - HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP); - ppdu_info->tid = ffs(tid_bitmap) - 1; - ppdu_info->tcp_msdu_count = - u32_get_bits(info[4], - HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT); - ppdu_info->udp_msdu_count = - u32_get_bits(info[4], - HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT); - ppdu_info->other_msdu_count = - u32_get_bits(info[5], - HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT); - ppdu_info->tcp_ack_msdu_count = - u32_get_bits(info[5], - HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT); - ppdu_info->preamble_type = - u32_get_bits(info[1], - HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE); - ppdu_info->num_mpdu_fcs_ok = - u32_get_bits(info[1], - HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK); - ppdu_info->num_mpdu_fcs_err = - u32_get_bits(info[0], - HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR); - ppdu_info->peer_id = - u32_get_bits(info[0], HAL_RX_PPDU_END_USER_STATS_INFO0_PEER_ID); - - switch (ppdu_info->preamble_type) { - case HAL_RX_PREAMBLE_11N: - ppdu_info->ht_flags = 1; - break; - case HAL_RX_PREAMBLE_11AC: - ppdu_info->vht_flags = 1; - break; - case HAL_RX_PREAMBLE_11AX: - ppdu_info->he_flags = 1; - break; - case HAL_RX_PREAMBLE_11BE: - ppdu_info->is_eht = true; - break; - default: - break; - } - - if (userid < HAL_MAX_UL_MU_USERS) { - struct hal_rx_user_status *rxuser_stats = - &ppdu_info->userstats[userid]; - - if (ppdu_info->num_mpdu_fcs_ok > 1 || - ppdu_info->num_mpdu_fcs_err > 1) - ppdu_info->userstats[userid].ampdu_present = true; - - ppdu_info->num_users += 1; - - ath12k_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats); - ath12k_dp_mon_rx_populate_mu_user_info(eu_stats, ppdu_info, - rxuser_stats); - } - ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]); - ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]); - break; - } - case HAL_RX_PPDU_END_USER_STATS_EXT: { - const struct hal_rx_ppdu_end_user_stats_ext *eu_stats = tlv_data; - - ppdu_info->mpdu_fcs_ok_bitmap[2] = __le32_to_cpu(eu_stats->info1); - ppdu_info->mpdu_fcs_ok_bitmap[3] = __le32_to_cpu(eu_stats->info2); - ppdu_info->mpdu_fcs_ok_bitmap[4] = __le32_to_cpu(eu_stats->info3); - ppdu_info->mpdu_fcs_ok_bitmap[5] = __le32_to_cpu(eu_stats->info4); - ppdu_info->mpdu_fcs_ok_bitmap[6] = __le32_to_cpu(eu_stats->info5); - ppdu_info->mpdu_fcs_ok_bitmap[7] = __le32_to_cpu(eu_stats->info6); - break; - } - case HAL_PHYRX_HT_SIG: - ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_L_SIG_B: - ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_L_SIG_A: - ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_VHT_SIG_A: - ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_A_SU: - ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_A_MU_DL: - ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_B1_MU: - ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_B2_MU: - ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_B2_OFDMA: - ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_RSSI_LEGACY: { - const struct hal_rx_phyrx_rssi_legacy_info *rssi = tlv_data; - - info[0] = __le32_to_cpu(rssi->info0); - info[1] = __le32_to_cpu(rssi->info1); - - /* TODO: Please note that the combined rssi will not be accurate - * in MU case. Rssi in MU needs to be retrieved from - * PHYRX_OTHER_RECEIVE_INFO TLV. - */ - ppdu_info->rssi_comb = - u32_get_bits(info[1], - HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB); - - ppdu_info->bw = u32_get_bits(info[0], - HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RX_BW); - break; - } - case HAL_PHYRX_OTHER_RECEIVE_INFO: { - const struct hal_phyrx_common_user_info *cmn_usr_info = tlv_data; - - ppdu_info->gi = le32_get_bits(cmn_usr_info->info0, - HAL_RX_PHY_CMN_USER_INFO0_GI); - break; - } - case HAL_RX_PPDU_START_USER_INFO: - ath12k_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info); - break; - - case HAL_RXPCU_PPDU_END_INFO: { - const struct hal_rx_ppdu_end_duration *ppdu_rx_duration = tlv_data; - - info[0] = __le32_to_cpu(ppdu_rx_duration->info0); - ppdu_info->rx_duration = - u32_get_bits(info[0], HAL_RX_PPDU_END_DURATION); - ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]); - ppdu_info->tsft = (ppdu_info->tsft << 32) | - __le32_to_cpu(ppdu_rx_duration->rsvd0[0]); - break; - } - case HAL_RX_MPDU_START: { - const struct hal_rx_mpdu_start *mpdu_start = tlv_data; - u16 peer_id; - - info[1] = __le32_to_cpu(mpdu_start->info1); - peer_id = u32_get_bits(info[1], HAL_RX_MPDU_START_INFO1_PEERID); - if (peer_id) - ppdu_info->peer_id = peer_id; - - ppdu_info->mpdu_len += u32_get_bits(info[1], - HAL_RX_MPDU_START_INFO2_MPDU_LEN); - if (userid < HAL_MAX_UL_MU_USERS) { - info[0] = __le32_to_cpu(mpdu_start->info0); - ppdu_info->userid = userid; - ppdu_info->userstats[userid].ampdu_id = - u32_get_bits(info[0], HAL_RX_MPDU_START_INFO0_PPDU_ID); - } - - return HAL_RX_MON_STATUS_MPDU_START; - } - case HAL_RX_MSDU_START: - /* TODO: add msdu start parsing logic */ - break; - case HAL_MON_BUF_ADDR: - return HAL_RX_MON_STATUS_BUF_ADDR; - case HAL_RX_MSDU_END: - ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data); - return HAL_RX_MON_STATUS_MSDU_END; - case HAL_RX_MPDU_END: - return HAL_RX_MON_STATUS_MPDU_END; - case HAL_PHYRX_GENERIC_U_SIG: - ath12k_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info); - break; - case HAL_PHYRX_GENERIC_EHT_SIG: - /* Handle the case where aggregation is in progress - * or the current TLV is one of the TLVs which should be - * aggregated - */ - if (!ppdu_info->tlv_aggr.in_progress) { - ppdu_info->tlv_aggr.in_progress = true; - ppdu_info->tlv_aggr.tlv_tag = tlv_tag; - ppdu_info->tlv_aggr.cur_len = 0; - } - - ppdu_info->is_eht = true; - - ath12k_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data); - break; - case HAL_DUMMY: - return HAL_RX_MON_STATUS_BUF_DONE; - case HAL_RX_PPDU_END_STATUS_DONE: - case 0: - return HAL_RX_MON_STATUS_PPDU_DONE; - default: - break; - } - - return HAL_RX_MON_STATUS_PPDU_NOT_DONE; -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_status_tlv); +EXPORT_SYMBOL(ath12k_dp_mon_parse_status_msdu_end); static void ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, @@ -2413,7 +2155,7 @@ ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, } EXPORT_SYMBOL(ath12k_dp_mon_get_buf_len); -static int +int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info) @@ -2458,45 +2200,7 @@ ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, 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, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 425bec6f0f3c..bfea7d4041cb 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -9,6 +9,7 @@ #include "core.h" #include "wifi7/hal_desc.h" +#include "wifi7/hal_rx.h" #define ATH12K_MON_RX_DOT11_OFFSET 5 #define ATH12K_MON_RX_PKT_OFFSET 8 @@ -106,15 +107,6 @@ int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, struct hal_rx_mon_ppdu_info *ppduinfo, struct napi_struct *napi); -int -ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - enum hal_rx_mon_status hal_status, - const void *tlv_data); -enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - const struct hal_tlv_64_hdr *tlv); struct sk_buff *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, @@ -128,4 +120,53 @@ void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, struct ath12k_buffer_addr **pp_buf_addr_info); u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id); +int +ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + const struct dp_mon_packet_info *packet_info); +void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, + const void *tlv_data); +void +ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, + struct hal_rx_user_status *rx_user_status); +void +ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, + struct hal_rx_mon_ppdu_info *ppdu_info, + struct hal_rx_user_status *rx_user_status); +void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, + struct hal_rx_mon_ppdu_info *ppdu_info); +void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, + struct hal_rx_mon_ppdu_info *ppdu_info); +void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info); +void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, + u16 user_id, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, + const struct hal_rx_msdu_end *msdu_end); +void +ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, + u16 tlv_len, const void *tlv_data); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index dae3f262cc50..076fb75a101f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -10,6 +10,7 @@ #include "../debug.h" #include "hal_qcn9274.h" #include "dp_rx.h" +#include "../dp_tx.h" #include "../peer.h" static void @@ -19,6 +20,317 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static enum hal_rx_mon_status +ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + const struct hal_tlv_64_hdr *tlv) +{ + struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; + const void *tlv_data = tlv->value; + u32 info[7], userid; + u16 tlv_tag, tlv_len; + + tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG); + tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); + userid = le64_get_bits(tlv->tl, HAL_TLV_64_USR_ID); + + if (ppdu_info->tlv_aggr.in_progress && ppdu_info->tlv_aggr.tlv_tag != tlv_tag) { + ath12k_dp_mon_parse_eht_sig_hdr(ppdu_info, ppdu_info->tlv_aggr.buf); + + ppdu_info->tlv_aggr.in_progress = false; + ppdu_info->tlv_aggr.cur_len = 0; + } + + switch (tlv_tag) { + case HAL_RX_PPDU_START: { + const struct hal_rx_ppdu_start *ppdu_start = tlv_data; + + u64 ppdu_ts = ath12k_le32hilo_to_u64(ppdu_start->ppdu_start_ts_63_32, + ppdu_start->ppdu_start_ts_31_0); + + info[0] = __le32_to_cpu(ppdu_start->info0); + + ppdu_info->ppdu_id = u32_get_bits(info[0], + HAL_RX_PPDU_START_INFO0_PPDU_ID); + + info[1] = __le32_to_cpu(ppdu_start->info1); + ppdu_info->chan_num = u32_get_bits(info[1], + HAL_RX_PPDU_START_INFO1_CHAN_NUM); + ppdu_info->freq = u32_get_bits(info[1], + HAL_RX_PPDU_START_INFO1_CHAN_FREQ); + ppdu_info->ppdu_ts = ppdu_ts; + + if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) { + ppdu_info->last_ppdu_id = ppdu_info->ppdu_id; + ppdu_info->num_users = 0; + memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0, + HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * + sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); + } + break; + } + case HAL_RX_PPDU_END_USER_STATS: { + const struct hal_rx_ppdu_end_user_stats *eu_stats = tlv_data; + u32 tid_bitmap; + + info[0] = __le32_to_cpu(eu_stats->info0); + info[1] = __le32_to_cpu(eu_stats->info1); + info[2] = __le32_to_cpu(eu_stats->info2); + info[4] = __le32_to_cpu(eu_stats->info4); + info[5] = __le32_to_cpu(eu_stats->info5); + info[6] = __le32_to_cpu(eu_stats->info6); + + ppdu_info->ast_index = + u32_get_bits(info[2], HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX); + ppdu_info->fc_valid = + u32_get_bits(info[1], HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID); + tid_bitmap = u32_get_bits(info[6], + HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP); + ppdu_info->tid = ffs(tid_bitmap) - 1; + ppdu_info->tcp_msdu_count = + u32_get_bits(info[4], + HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT); + ppdu_info->udp_msdu_count = + u32_get_bits(info[4], + HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT); + ppdu_info->other_msdu_count = + u32_get_bits(info[5], + HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT); + ppdu_info->tcp_ack_msdu_count = + u32_get_bits(info[5], + HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT); + ppdu_info->preamble_type = + u32_get_bits(info[1], + HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE); + ppdu_info->num_mpdu_fcs_ok = + u32_get_bits(info[1], + HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK); + ppdu_info->num_mpdu_fcs_err = + u32_get_bits(info[0], + HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR); + ppdu_info->peer_id = + u32_get_bits(info[0], HAL_RX_PPDU_END_USER_STATS_INFO0_PEER_ID); + + switch (ppdu_info->preamble_type) { + case HAL_RX_PREAMBLE_11N: + ppdu_info->ht_flags = 1; + break; + case HAL_RX_PREAMBLE_11AC: + ppdu_info->vht_flags = 1; + break; + case HAL_RX_PREAMBLE_11AX: + ppdu_info->he_flags = 1; + break; + case HAL_RX_PREAMBLE_11BE: + ppdu_info->is_eht = true; + break; + default: + break; + } + + if (userid < HAL_MAX_UL_MU_USERS) { + struct hal_rx_user_status *rxuser_stats = + &ppdu_info->userstats[userid]; + + if (ppdu_info->num_mpdu_fcs_ok > 1 || + ppdu_info->num_mpdu_fcs_err > 1) + ppdu_info->userstats[userid].ampdu_present = true; + + ppdu_info->num_users += 1; + + ath12k_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats); + ath12k_dp_mon_rx_populate_mu_user_info(eu_stats, ppdu_info, + rxuser_stats); + } + ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]); + ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]); + break; + } + case HAL_RX_PPDU_END_USER_STATS_EXT: { + const struct hal_rx_ppdu_end_user_stats_ext *eu_stats = tlv_data; + + ppdu_info->mpdu_fcs_ok_bitmap[2] = __le32_to_cpu(eu_stats->info1); + ppdu_info->mpdu_fcs_ok_bitmap[3] = __le32_to_cpu(eu_stats->info2); + ppdu_info->mpdu_fcs_ok_bitmap[4] = __le32_to_cpu(eu_stats->info3); + ppdu_info->mpdu_fcs_ok_bitmap[5] = __le32_to_cpu(eu_stats->info4); + ppdu_info->mpdu_fcs_ok_bitmap[6] = __le32_to_cpu(eu_stats->info5); + ppdu_info->mpdu_fcs_ok_bitmap[7] = __le32_to_cpu(eu_stats->info6); + break; + } + case HAL_PHYRX_HT_SIG: + ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_L_SIG_B: + ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_L_SIG_A: + ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_VHT_SIG_A: + ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_A_SU: + ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_A_MU_DL: + ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_B1_MU: + ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_B2_MU: + ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_B2_OFDMA: + ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_RSSI_LEGACY: { + const struct hal_rx_phyrx_rssi_legacy_info *rssi = tlv_data; + + info[0] = __le32_to_cpu(rssi->info0); + info[1] = __le32_to_cpu(rssi->info1); + + /* TODO: Please note that the combined rssi will not be accurate + * in MU case. Rssi in MU needs to be retrieved from + * PHYRX_OTHER_RECEIVE_INFO TLV. + */ + ppdu_info->rssi_comb = + u32_get_bits(info[1], + HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB); + + ppdu_info->bw = u32_get_bits(info[0], + HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RX_BW); + break; + } + case HAL_PHYRX_OTHER_RECEIVE_INFO: { + const struct hal_phyrx_common_user_info *cmn_usr_info = tlv_data; + + ppdu_info->gi = le32_get_bits(cmn_usr_info->info0, + HAL_RX_PHY_CMN_USER_INFO0_GI); + break; + } + case HAL_RX_PPDU_START_USER_INFO: + ath12k_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info); + break; + + case HAL_RXPCU_PPDU_END_INFO: { + const struct hal_rx_ppdu_end_duration *ppdu_rx_duration = tlv_data; + + info[0] = __le32_to_cpu(ppdu_rx_duration->info0); + ppdu_info->rx_duration = + u32_get_bits(info[0], HAL_RX_PPDU_END_DURATION); + ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]); + ppdu_info->tsft = (ppdu_info->tsft << 32) | + __le32_to_cpu(ppdu_rx_duration->rsvd0[0]); + break; + } + case HAL_RX_MPDU_START: { + const struct hal_rx_mpdu_start *mpdu_start = tlv_data; + u16 peer_id; + + info[1] = __le32_to_cpu(mpdu_start->info1); + peer_id = u32_get_bits(info[1], HAL_RX_MPDU_START_INFO1_PEERID); + if (peer_id) + ppdu_info->peer_id = peer_id; + + ppdu_info->mpdu_len += u32_get_bits(info[1], + HAL_RX_MPDU_START_INFO2_MPDU_LEN); + if (userid < HAL_MAX_UL_MU_USERS) { + info[0] = __le32_to_cpu(mpdu_start->info0); + ppdu_info->userid = userid; + ppdu_info->userstats[userid].ampdu_id = + u32_get_bits(info[0], HAL_RX_MPDU_START_INFO0_PPDU_ID); + } + + return HAL_RX_MON_STATUS_MPDU_START; + } + case HAL_RX_MSDU_START: + /* TODO: add msdu start parsing logic */ + break; + case HAL_MON_BUF_ADDR: + return HAL_RX_MON_STATUS_BUF_ADDR; + case HAL_RX_MSDU_END: + ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data); + return HAL_RX_MON_STATUS_MSDU_END; + case HAL_RX_MPDU_END: + return HAL_RX_MON_STATUS_MPDU_END; + case HAL_PHYRX_GENERIC_U_SIG: + ath12k_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info); + break; + case HAL_PHYRX_GENERIC_EHT_SIG: + /* Handle the case where aggregation is in progress + * or the current TLV is one of the TLVs which should be + * aggregated + */ + if (!ppdu_info->tlv_aggr.in_progress) { + ppdu_info->tlv_aggr.in_progress = true; + ppdu_info->tlv_aggr.tlv_tag = tlv_tag; + ppdu_info->tlv_aggr.cur_len = 0; + } + + ppdu_info->is_eht = true; + + ath12k_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data); + break; + case HAL_DUMMY: + return HAL_RX_MON_STATUS_BUF_DONE; + case HAL_RX_PPDU_END_STATUS_DONE: + case 0: + return HAL_RX_MON_STATUS_PPDU_DONE; + default: + break; + } + + return HAL_RX_MON_STATUS_PPDU_NOT_DONE; +} + +static int +ath12k_wifi7_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + enum hal_rx_mon_status hal_status, + const void *tlv_data) +{ + switch (hal_status) { + case HAL_RX_MON_STATUS_MPDU_START: + if (WARN_ON_ONCE(pmon->mon_mpdu)) + break; + + pmon->mon_mpdu = kzalloc(sizeof(*pmon->mon_mpdu), GFP_ATOMIC); + if (!pmon->mon_mpdu) + return -ENOMEM; + break; + case HAL_RX_MON_STATUS_BUF_ADDR: + return ath12k_dp_mon_parse_status_buf(dp_pdev, pmon, tlv_data); + case HAL_RX_MON_STATUS_MPDU_END: + /* If no MSDU then free empty MPDU */ + if (pmon->mon_mpdu->tail) { + pmon->mon_mpdu->tail->next = NULL; + list_add_tail(&pmon->mon_mpdu->list, &pmon->dp_rx_mon_mpdu_list); + } else { + kfree(pmon->mon_mpdu); + } + pmon->mon_mpdu = NULL; + break; + case HAL_RX_MON_STATUS_MSDU_END: + pmon->mon_mpdu->decap_format = pmon->decap_format; + pmon->mon_mpdu->err_bitmap = pmon->err_bitmap; + break; + default: + break; + } + + return 0; +} + static u32 ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, void *ring_entry, struct sk_buff **head_msdu, @@ -389,11 +701,12 @@ ath12k_wifi7_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, else tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); - hal_status = ath12k_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, tlv); + hal_status = ath12k_wifi7_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, + tlv); if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable && - ath12k_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status, - tlv->value)) + ath12k_wifi7_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status, + tlv->value)) return HAL_RX_MON_STATUS_PPDU_DONE; ptr += sizeof(*tlv) + tlv_len; -- 2.34.1 Separate Wi-Fi 7-specific TX monitor functionality from ath12k common code to improve modularity and maintainability. Move following TX monitor processing functions to wifi7/dp_mon.c and rename the functions with the ath12k_wifi7_ prefix: - ath12k_dp_mon_tx_get_ppdu_info() - ath12k_dp_mon_hal_tx_ppdu_info() - ath12k_dp_mon_tx_alloc_skb() - ath12k_dp_mon_tx_gen_cts2self_frame() - ath12k_dp_mon_tx_gen_rts_frame() - ath12k_dp_mon_tx_gen_3addr_qos_null_frame() - ath12k_dp_mon_tx_gen_4addr_qos_null_frame() - ath12k_dp_mon_tx_gen_ack_frame() - ath12k_dp_mon_tx_gen_prot_frame() - ath12k_dp_mon_tx_parse_status_tlv() - ath12k_dp_mon_tx_status_get_num_user() - ath12k_dp_mon_tx_process_ppdu_info() - ath12k_dp_mon_tx_parse_mon_status() Export helper functions required by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh --- drivers/net/wireless/ath/ath12k/dp_mon.c | 671 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 11 - .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 676 ++++++++++++++++++ .../net/wireless/ath/ath12k/wifi7/dp_mon.h | 6 + 4 files changed, 682 insertions(+), 682 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index dc4827771a64..d3e662399c31 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2366,677 +2366,6 @@ int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, return req_entries - num_remain; } -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) -{ - struct dp_mon_tx_ppdu_info *tx_ppdu_info; - - if (type == DP_MON_TX_PROT_PPDU_INFO) { - tx_ppdu_info = pmon->tx_prot_ppdu_info; - - if (tx_ppdu_info && !tx_ppdu_info->is_used) - return tx_ppdu_info; - kfree(tx_ppdu_info); - } else { - tx_ppdu_info = pmon->tx_data_ppdu_info; - - if (tx_ppdu_info && !tx_ppdu_info->is_used) - return tx_ppdu_info; - kfree(tx_ppdu_info); - } - - /* allocate new tx_ppdu_info */ - tx_ppdu_info = kzalloc(sizeof(*tx_ppdu_info), GFP_ATOMIC); - if (!tx_ppdu_info) - return NULL; - - tx_ppdu_info->is_used = 0; - tx_ppdu_info->ppdu_id = ppdu_id; - - if (type == DP_MON_TX_PROT_PPDU_INFO) - pmon->tx_prot_ppdu_info = tx_ppdu_info; - else - pmon->tx_data_ppdu_info = tx_ppdu_info; - - return tx_ppdu_info; -} - -static struct dp_mon_tx_ppdu_info * -ath12k_dp_mon_hal_tx_ppdu_info(struct ath12k_mon_data *pmon, - u16 tlv_tag) -{ - switch (tlv_tag) { - case HAL_TX_FES_SETUP: - case HAL_TX_FLUSH: - case HAL_PCU_PPDU_SETUP_INIT: - case HAL_TX_PEER_ENTRY: - case HAL_TX_QUEUE_EXTENSION: - case HAL_TX_MPDU_START: - case HAL_TX_MSDU_START: - case HAL_TX_DATA: - case HAL_MON_BUF_ADDR: - case HAL_TX_MPDU_END: - case HAL_TX_LAST_MPDU_FETCHED: - case HAL_TX_LAST_MPDU_END: - case HAL_COEX_TX_REQ: - case HAL_TX_RAW_OR_NATIVE_FRAME_SETUP: - case HAL_SCH_CRITICAL_TLV_REFERENCE: - case HAL_TX_FES_SETUP_COMPLETE: - case HAL_TQM_MPDU_GLOBAL_START: - case HAL_SCHEDULER_END: - case HAL_TX_FES_STATUS_USER_PPDU: - break; - case HAL_TX_FES_STATUS_PROT: { - if (!pmon->tx_prot_ppdu_info->is_used) - pmon->tx_prot_ppdu_info->is_used = true; - - return pmon->tx_prot_ppdu_info; - } - } - - if (!pmon->tx_data_ppdu_info->is_used) - pmon->tx_data_ppdu_info->is_used = true; - - return pmon->tx_data_ppdu_info; -} - -#define MAX_MONITOR_HEADER 512 -#define MAX_DUMMY_FRM_BODY 128 - -struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void) -{ - struct sk_buff *skb; - - skb = dev_alloc_skb(MAX_MONITOR_HEADER + MAX_DUMMY_FRM_BODY); - if (!skb) - return NULL; - - skb_reserve(skb, MAX_MONITOR_HEADER); - - if (!IS_ALIGNED((unsigned long)skb->data, 4)) - skb_pull(skb, PTR_ALIGN(skb->data, 4) - skb->data); - - return skb; -} - -static int -ath12k_dp_mon_tx_gen_cts2self_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct ieee80211_cts *cts; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - cts = (struct ieee80211_cts *)skb->data; - memset(cts, 0, MAX_DUMMY_FRM_BODY); - cts->frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); - cts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); - memcpy(cts->ra, tx_ppdu_info->rx_status.addr1, sizeof(cts->ra)); - - skb_put(skb, sizeof(*cts)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_rts_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct ieee80211_rts *rts; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - rts = (struct ieee80211_rts *)skb->data; - memset(rts, 0, MAX_DUMMY_FRM_BODY); - rts->frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - rts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); - memcpy(rts->ra, tx_ppdu_info->rx_status.addr1, sizeof(rts->ra)); - memcpy(rts->ta, tx_ppdu_info->rx_status.addr2, sizeof(rts->ta)); - - skb_put(skb, sizeof(*rts)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_3addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct ieee80211_qos_hdr *qhdr; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - qhdr = (struct ieee80211_qos_hdr *)skb->data; - memset(qhdr, 0, MAX_DUMMY_FRM_BODY); - qhdr->frame_control = - cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); - qhdr->duration_id = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); - memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); - memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); - memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); - - skb_put(skb, sizeof(*qhdr)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_4addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct dp_mon_qosframe_addr4 *qhdr; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - qhdr = (struct dp_mon_qosframe_addr4 *)skb->data; - memset(qhdr, 0, MAX_DUMMY_FRM_BODY); - qhdr->frame_control = - cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); - qhdr->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); - memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); - memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); - memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); - memcpy(qhdr->addr4, tx_ppdu_info->rx_status.addr4, ETH_ALEN); - - skb_put(skb, sizeof(*qhdr)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_ack_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct dp_mon_frame_min_one *fbmhdr; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - fbmhdr = (struct dp_mon_frame_min_one *)skb->data; - memset(fbmhdr, 0, MAX_DUMMY_FRM_BODY); - fbmhdr->frame_control = - cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_CFACK); - memcpy(fbmhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); - - /* set duration zero for ack frame */ - fbmhdr->duration = 0; - - skb_put(skb, sizeof(*fbmhdr)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_prot_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - int ret = 0; - - switch (tx_ppdu_info->rx_status.medium_prot_type) { - case DP_MON_TX_MEDIUM_RTS_LEGACY: - case DP_MON_TX_MEDIUM_RTS_11AC_STATIC_BW: - case DP_MON_TX_MEDIUM_RTS_11AC_DYNAMIC_BW: - ret = ath12k_dp_mon_tx_gen_rts_frame(tx_ppdu_info); - break; - case DP_MON_TX_MEDIUM_CTS2SELF: - ret = ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); - break; - case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_3ADDR: - ret = ath12k_dp_mon_tx_gen_3addr_qos_null_frame(tx_ppdu_info); - break; - case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_4ADDR: - ret = ath12k_dp_mon_tx_gen_4addr_qos_null_frame(tx_ppdu_info); - break; - } - - return ret; -} - -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, const void *tlv_data, u32 userid) -{ - struct dp_mon_tx_ppdu_info *tx_ppdu_info; - enum dp_mon_tx_tlv_status status = DP_MON_TX_STATUS_PPDU_NOT_DONE; - u32 info[7]; - - tx_ppdu_info = ath12k_dp_mon_hal_tx_ppdu_info(pmon, tlv_tag); - - switch (tlv_tag) { - case HAL_TX_FES_SETUP: { - const struct hal_tx_fes_setup *tx_fes_setup = tlv_data; - - info[0] = __le32_to_cpu(tx_fes_setup->info0); - tx_ppdu_info->ppdu_id = __le32_to_cpu(tx_fes_setup->schedule_id); - tx_ppdu_info->num_users = - u32_get_bits(info[0], HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); - status = DP_MON_TX_FES_SETUP; - break; - } - - case HAL_TX_FES_STATUS_END: { - const struct hal_tx_fes_status_end *tx_fes_status_end = tlv_data; - u32 tst_15_0, tst_31_16; - - info[0] = __le32_to_cpu(tx_fes_status_end->info0); - tst_15_0 = - u32_get_bits(info[0], - HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_15_0); - tst_31_16 = - u32_get_bits(info[0], - HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_31_16); - - tx_ppdu_info->rx_status.ppdu_ts = (tst_15_0 | (tst_31_16 << 16)); - status = DP_MON_TX_FES_STATUS_END; - break; - } - - case HAL_RX_RESPONSE_REQUIRED_INFO: { - const struct hal_rx_resp_req_info *rx_resp_req_info = tlv_data; - u32 addr_32; - u16 addr_16; - - info[0] = __le32_to_cpu(rx_resp_req_info->info0); - info[1] = __le32_to_cpu(rx_resp_req_info->info1); - info[2] = __le32_to_cpu(rx_resp_req_info->info2); - info[3] = __le32_to_cpu(rx_resp_req_info->info3); - info[4] = __le32_to_cpu(rx_resp_req_info->info4); - info[5] = __le32_to_cpu(rx_resp_req_info->info5); - - tx_ppdu_info->rx_status.ppdu_id = - u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_PPDU_ID); - tx_ppdu_info->rx_status.reception_type = - u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_RECEPTION_TYPE); - tx_ppdu_info->rx_status.rx_duration = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_DURATION); - tx_ppdu_info->rx_status.mcs = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_RATE_MCS); - tx_ppdu_info->rx_status.sgi = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_SGI); - tx_ppdu_info->rx_status.is_stbc = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_STBC); - tx_ppdu_info->rx_status.ldpc = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_LDPC); - tx_ppdu_info->rx_status.is_ampdu = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_IS_AMPDU); - tx_ppdu_info->rx_status.num_users = - u32_get_bits(info[2], HAL_RX_RESP_REQ_INFO2_NUM_USER); - - addr_32 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO3_ADDR1_31_0); - addr_16 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO4_ADDR1_47_32); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); - - addr_16 = u32_get_bits(info[4], HAL_RX_RESP_REQ_INFO4_ADDR1_15_0); - addr_32 = u32_get_bits(info[5], HAL_RX_RESP_REQ_INFO5_ADDR1_47_16); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2); - - if (tx_ppdu_info->rx_status.reception_type == 0) - ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); - status = DP_MON_RX_RESPONSE_REQUIRED_INFO; - break; - } - - case HAL_PCU_PPDU_SETUP_INIT: { - const struct hal_tx_pcu_ppdu_setup_init *ppdu_setup = tlv_data; - u32 addr_32; - u16 addr_16; - - info[0] = __le32_to_cpu(ppdu_setup->info0); - info[1] = __le32_to_cpu(ppdu_setup->info1); - info[2] = __le32_to_cpu(ppdu_setup->info2); - info[3] = __le32_to_cpu(ppdu_setup->info3); - info[4] = __le32_to_cpu(ppdu_setup->info4); - info[5] = __le32_to_cpu(ppdu_setup->info5); - info[6] = __le32_to_cpu(ppdu_setup->info6); - - /* protection frame address 1 */ - addr_32 = u32_get_bits(info[1], - HAL_TX_PPDU_SETUP_INFO1_PROT_FRAME_ADDR1_31_0); - addr_16 = u32_get_bits(info[2], - HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR1_47_32); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); - - /* protection frame address 2 */ - addr_16 = u32_get_bits(info[2], - HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR2_15_0); - addr_32 = u32_get_bits(info[3], - HAL_TX_PPDU_SETUP_INFO3_PROT_FRAME_ADDR2_47_16); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2); - - /* protection frame address 3 */ - addr_32 = u32_get_bits(info[4], - HAL_TX_PPDU_SETUP_INFO4_PROT_FRAME_ADDR3_31_0); - addr_16 = u32_get_bits(info[5], - HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR3_47_32); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr3); - - /* protection frame address 4 */ - addr_16 = u32_get_bits(info[5], - HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR4_15_0); - addr_32 = u32_get_bits(info[6], - HAL_TX_PPDU_SETUP_INFO6_PROT_FRAME_ADDR4_47_16); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr4); - - status = u32_get_bits(info[0], - HAL_TX_PPDU_SETUP_INFO0_MEDIUM_PROT_TYPE); - break; - } - - case HAL_TX_QUEUE_EXTENSION: { - const struct hal_tx_queue_exten *tx_q_exten = tlv_data; - - info[0] = __le32_to_cpu(tx_q_exten->info0); - - tx_ppdu_info->rx_status.frame_control = - u32_get_bits(info[0], - HAL_TX_Q_EXT_INFO0_FRAME_CTRL); - tx_ppdu_info->rx_status.fc_valid = true; - break; - } - - case HAL_TX_FES_STATUS_START: { - const struct hal_tx_fes_status_start *tx_fes_start = tlv_data; - - info[0] = __le32_to_cpu(tx_fes_start->info0); - - tx_ppdu_info->rx_status.medium_prot_type = - u32_get_bits(info[0], - HAL_TX_FES_STATUS_START_INFO0_MEDIUM_PROT_TYPE); - break; - } - - case HAL_TX_FES_STATUS_PROT: { - const struct hal_tx_fes_status_prot *tx_fes_status = tlv_data; - u32 start_timestamp; - u32 end_timestamp; - - info[0] = __le32_to_cpu(tx_fes_status->info0); - info[1] = __le32_to_cpu(tx_fes_status->info1); - - start_timestamp = - u32_get_bits(info[0], - HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_15_0); - start_timestamp |= - u32_get_bits(info[0], - HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_31_16) << 15; - end_timestamp = - u32_get_bits(info[1], - HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_15_0); - end_timestamp |= - u32_get_bits(info[1], - HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_31_16) << 15; - tx_ppdu_info->rx_status.rx_duration = end_timestamp - start_timestamp; - - ath12k_dp_mon_tx_gen_prot_frame(tx_ppdu_info); - break; - } - - case HAL_TX_FES_STATUS_START_PPDU: - case HAL_TX_FES_STATUS_START_PROT: { - const struct hal_tx_fes_status_start_prot *tx_fes_stat_start = tlv_data; - u64 ppdu_ts; - - info[0] = __le32_to_cpu(tx_fes_stat_start->info0); - - tx_ppdu_info->rx_status.ppdu_ts = - u32_get_bits(info[0], - HAL_TX_FES_STAT_STRT_INFO0_PROT_TS_LOWER_32); - ppdu_ts = (u32_get_bits(info[1], - HAL_TX_FES_STAT_STRT_INFO1_PROT_TS_UPPER_32)); - tx_ppdu_info->rx_status.ppdu_ts |= ppdu_ts << 32; - break; - } - - case HAL_TX_FES_STATUS_USER_PPDU: { - const struct hal_tx_fes_status_user_ppdu *tx_fes_usr_ppdu = tlv_data; - - info[0] = __le32_to_cpu(tx_fes_usr_ppdu->info0); - - tx_ppdu_info->rx_status.rx_duration = - u32_get_bits(info[0], - HAL_TX_FES_STAT_USR_PPDU_INFO0_DURATION); - break; - } - - case HAL_MACTX_HE_SIG_A_SU: - ath12k_dp_mon_parse_he_sig_su(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_HE_SIG_A_MU_DL: - ath12k_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_HE_SIG_B1_MU: - ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_HE_SIG_B2_MU: - ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_HE_SIG_B2_OFDMA: - ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_VHT_SIG_A: - ath12k_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_L_SIG_A: - ath12k_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_L_SIG_B: - ath12k_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_RX_FRAME_BITMAP_ACK: { - const struct hal_rx_frame_bitmap_ack *fbm_ack = tlv_data; - u32 addr_32; - u16 addr_16; - - info[0] = __le32_to_cpu(fbm_ack->info0); - info[1] = __le32_to_cpu(fbm_ack->info1); - - addr_32 = u32_get_bits(info[0], - HAL_RX_FBM_ACK_INFO0_ADDR1_31_0); - addr_16 = u32_get_bits(info[1], - HAL_RX_FBM_ACK_INFO1_ADDR1_47_32); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); - - ath12k_dp_mon_tx_gen_ack_frame(tx_ppdu_info); - break; - } - - case HAL_MACTX_PHY_DESC: { - const struct hal_tx_phy_desc *tx_phy_desc = tlv_data; - - info[0] = __le32_to_cpu(tx_phy_desc->info0); - info[1] = __le32_to_cpu(tx_phy_desc->info1); - info[2] = __le32_to_cpu(tx_phy_desc->info2); - info[3] = __le32_to_cpu(tx_phy_desc->info3); - - tx_ppdu_info->rx_status.beamformed = - u32_get_bits(info[0], - HAL_TX_PHY_DESC_INFO0_BF_TYPE); - tx_ppdu_info->rx_status.preamble_type = - u32_get_bits(info[0], - HAL_TX_PHY_DESC_INFO0_PREAMBLE_11B); - tx_ppdu_info->rx_status.mcs = - u32_get_bits(info[1], - HAL_TX_PHY_DESC_INFO1_MCS); - tx_ppdu_info->rx_status.ltf_size = - u32_get_bits(info[3], - HAL_TX_PHY_DESC_INFO3_LTF_SIZE); - tx_ppdu_info->rx_status.nss = - u32_get_bits(info[2], - HAL_TX_PHY_DESC_INFO2_NSS); - tx_ppdu_info->rx_status.chan_num = - u32_get_bits(info[3], - HAL_TX_PHY_DESC_INFO3_ACTIVE_CHANNEL); - tx_ppdu_info->rx_status.bw = - u32_get_bits(info[0], - HAL_TX_PHY_DESC_INFO0_BANDWIDTH); - break; - } - - case HAL_TX_MPDU_START: { - struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu; - - mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC); - if (!mon_mpdu) - return DP_MON_TX_STATUS_PPDU_NOT_DONE; - status = DP_MON_TX_MPDU_START; - break; - } - - case HAL_TX_MPDU_END: - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - break; - } - - return status; -} - -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) -{ - u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; - u32 info0; - - switch (tlv_tag) { - case HAL_TX_FES_SETUP: { - struct hal_tx_fes_setup *tx_fes_setup = - (struct hal_tx_fes_setup *)tx_tlv; - - info0 = __le32_to_cpu(tx_fes_setup->info0); - - *num_users = u32_get_bits(info0, HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); - tlv_status = DP_MON_TX_FES_SETUP; - break; - } - - case HAL_RX_RESPONSE_REQUIRED_INFO: { - /* TODO: need to update *num_users */ - tlv_status = DP_MON_RX_RESPONSE_REQUIRED_INFO; - break; - } - } - - return tlv_status; -} - -static void -ath12k_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, - struct napi_struct *napi, - struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct dp_mon_mpdu *tmp, *mon_mpdu; - - list_for_each_entry_safe(mon_mpdu, tmp, - &tx_ppdu_info->dp_tx_mon_mpdu_list, list) { - list_del(&mon_mpdu->list); - - if (mon_mpdu->head) - ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, - &tx_ppdu_info->rx_status, napi); - - kfree(mon_mpdu); - } -} - -enum hal_rx_mon_status -ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - struct sk_buff *skb, - struct napi_struct *napi, - u32 ppdu_id) -{ - struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; - struct dp_mon_tx_ppdu_info *tx_prot_ppdu_info, *tx_data_ppdu_info; - struct hal_tlv_hdr *tlv; - u8 *ptr = skb->data; - u16 tlv_tag; - u16 tlv_len; - u32 tlv_userid = 0; - u8 num_user; - u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; - - tx_prot_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, - DP_MON_TX_PROT_PPDU_INFO); - if (!tx_prot_ppdu_info) - return -ENOMEM; - - tlv = (struct hal_tlv_hdr *)ptr; - tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG); - - tlv_status = ath12k_dp_mon_tx_status_get_num_user(tlv_tag, tlv, &num_user); - if (tlv_status == DP_MON_TX_STATUS_PPDU_NOT_DONE || !num_user) - return -EINVAL; - - tx_data_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, - DP_MON_TX_DATA_PPDU_INFO); - if (!tx_data_ppdu_info) - return -ENOMEM; - - do { - tlv = (struct hal_tlv_hdr *)ptr; - tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG); - tlv_len = le32_get_bits(tlv->tl, HAL_TLV_HDR_LEN); - tlv_userid = le32_get_bits(tlv->tl, HAL_TLV_USR_ID); - - tlv_status = ath12k_dp_mon_tx_parse_status_tlv(ab, pmon, - tlv_tag, ptr, - tlv_userid); - ptr += tlv_len; - ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN); - if ((ptr - skb->data) >= DP_TX_MONITOR_BUF_SIZE) - break; - } while (tlv_status != DP_MON_TX_FES_STATUS_END); - - ath12k_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_data_ppdu_info); - ath12k_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_prot_ppdu_info); - - return tlv_status; -} - 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, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index bfea7d4041cb..1d2ec4072a83 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -85,17 +85,6 @@ int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int req_entries); -struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void); -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); -enum hal_rx_mon_status -ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - struct sk_buff *skb, - struct napi_struct *napi, - u32 ppdu_id); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 076fb75a101f..abdfd3cfd0e4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -331,6 +331,682 @@ ath12k_wifi7_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, return 0; } +static struct dp_mon_tx_ppdu_info * +ath12k_wifi7_dp_mon_tx_get_ppdu_info(struct ath12k_mon_data *pmon, + unsigned int ppdu_id, + enum dp_mon_tx_ppdu_info_type type) +{ + struct dp_mon_tx_ppdu_info *tx_ppdu_info; + + if (type == DP_MON_TX_PROT_PPDU_INFO) { + tx_ppdu_info = pmon->tx_prot_ppdu_info; + + if (tx_ppdu_info && !tx_ppdu_info->is_used) + return tx_ppdu_info; + kfree(tx_ppdu_info); + } else { + tx_ppdu_info = pmon->tx_data_ppdu_info; + + if (tx_ppdu_info && !tx_ppdu_info->is_used) + return tx_ppdu_info; + kfree(tx_ppdu_info); + } + + /* allocate new tx_ppdu_info */ + tx_ppdu_info = kzalloc(sizeof(*tx_ppdu_info), GFP_ATOMIC); + if (!tx_ppdu_info) + return NULL; + + tx_ppdu_info->is_used = 0; + tx_ppdu_info->ppdu_id = ppdu_id; + + if (type == DP_MON_TX_PROT_PPDU_INFO) + pmon->tx_prot_ppdu_info = tx_ppdu_info; + else + pmon->tx_data_ppdu_info = tx_ppdu_info; + + return tx_ppdu_info; +} + +static struct dp_mon_tx_ppdu_info * +ath12k_wifi7_dp_mon_hal_tx_ppdu_info(struct ath12k_mon_data *pmon, + u16 tlv_tag) +{ + switch (tlv_tag) { + case HAL_TX_FES_SETUP: + case HAL_TX_FLUSH: + case HAL_PCU_PPDU_SETUP_INIT: + case HAL_TX_PEER_ENTRY: + case HAL_TX_QUEUE_EXTENSION: + case HAL_TX_MPDU_START: + case HAL_TX_MSDU_START: + case HAL_TX_DATA: + case HAL_MON_BUF_ADDR: + case HAL_TX_MPDU_END: + case HAL_TX_LAST_MPDU_FETCHED: + case HAL_TX_LAST_MPDU_END: + case HAL_COEX_TX_REQ: + case HAL_TX_RAW_OR_NATIVE_FRAME_SETUP: + case HAL_SCH_CRITICAL_TLV_REFERENCE: + case HAL_TX_FES_SETUP_COMPLETE: + case HAL_TQM_MPDU_GLOBAL_START: + case HAL_SCHEDULER_END: + case HAL_TX_FES_STATUS_USER_PPDU: + break; + case HAL_TX_FES_STATUS_PROT: { + if (!pmon->tx_prot_ppdu_info->is_used) + pmon->tx_prot_ppdu_info->is_used = true; + + return pmon->tx_prot_ppdu_info; + } + } + + if (!pmon->tx_data_ppdu_info->is_used) + pmon->tx_data_ppdu_info->is_used = true; + + return pmon->tx_data_ppdu_info; +} + +#define MAX_MONITOR_HEADER 512 +#define MAX_DUMMY_FRM_BODY 128 + +static struct +sk_buff *ath12k_wifi7_dp_mon_tx_alloc_skb(void) +{ + struct sk_buff *skb; + + skb = dev_alloc_skb(MAX_MONITOR_HEADER + MAX_DUMMY_FRM_BODY); + if (!skb) + return NULL; + + skb_reserve(skb, MAX_MONITOR_HEADER); + + if (!IS_ALIGNED((unsigned long)skb->data, 4)) + skb_pull(skb, PTR_ALIGN(skb->data, 4) - skb->data); + + return skb; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_cts2self_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct ieee80211_cts *cts; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + cts = (struct ieee80211_cts *)skb->data; + memset(cts, 0, MAX_DUMMY_FRM_BODY); + cts->frame_control = + cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); + cts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); + memcpy(cts->ra, tx_ppdu_info->rx_status.addr1, sizeof(cts->ra)); + + skb_put(skb, sizeof(*cts)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_rts_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct ieee80211_rts *rts; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + rts = (struct ieee80211_rts *)skb->data; + memset(rts, 0, MAX_DUMMY_FRM_BODY); + rts->frame_control = + cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); + rts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); + memcpy(rts->ra, tx_ppdu_info->rx_status.addr1, sizeof(rts->ra)); + memcpy(rts->ta, tx_ppdu_info->rx_status.addr2, sizeof(rts->ta)); + + skb_put(skb, sizeof(*rts)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_3addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct ieee80211_qos_hdr *qhdr; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + qhdr = (struct ieee80211_qos_hdr *)skb->data; + memset(qhdr, 0, MAX_DUMMY_FRM_BODY); + qhdr->frame_control = + cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); + qhdr->duration_id = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); + memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); + memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); + memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); + + skb_put(skb, sizeof(*qhdr)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_4addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct dp_mon_qosframe_addr4 *qhdr; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + qhdr = (struct dp_mon_qosframe_addr4 *)skb->data; + memset(qhdr, 0, MAX_DUMMY_FRM_BODY); + qhdr->frame_control = + cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); + qhdr->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); + memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); + memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); + memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); + memcpy(qhdr->addr4, tx_ppdu_info->rx_status.addr4, ETH_ALEN); + + skb_put(skb, sizeof(*qhdr)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_ack_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct dp_mon_frame_min_one *fbmhdr; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + fbmhdr = (struct dp_mon_frame_min_one *)skb->data; + memset(fbmhdr, 0, MAX_DUMMY_FRM_BODY); + fbmhdr->frame_control = + cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_CFACK); + memcpy(fbmhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); + + /* set duration zero for ack frame */ + fbmhdr->duration = 0; + + skb_put(skb, sizeof(*fbmhdr)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_prot_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + int ret = 0; + + switch (tx_ppdu_info->rx_status.medium_prot_type) { + case DP_MON_TX_MEDIUM_RTS_LEGACY: + case DP_MON_TX_MEDIUM_RTS_11AC_STATIC_BW: + case DP_MON_TX_MEDIUM_RTS_11AC_DYNAMIC_BW: + ret = ath12k_wifi7_dp_mon_tx_gen_rts_frame(tx_ppdu_info); + break; + case DP_MON_TX_MEDIUM_CTS2SELF: + ret = ath12k_wifi7_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); + break; + case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_3ADDR: + ret = ath12k_wifi7_dp_mon_tx_gen_3addr_qos_null_frame(tx_ppdu_info); + break; + case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_4ADDR: + ret = ath12k_wifi7_dp_mon_tx_gen_4addr_qos_null_frame(tx_ppdu_info); + break; + } + + return ret; +} + +static enum dp_mon_tx_tlv_status +ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, + struct ath12k_mon_data *pmon, + u16 tlv_tag, const void *tlv_data, + u32 userid) +{ + struct dp_mon_tx_ppdu_info *tx_ppdu_info; + enum dp_mon_tx_tlv_status status = DP_MON_TX_STATUS_PPDU_NOT_DONE; + u32 info[7]; + + tx_ppdu_info = ath12k_wifi7_dp_mon_hal_tx_ppdu_info(pmon, tlv_tag); + + switch (tlv_tag) { + case HAL_TX_FES_SETUP: { + const struct hal_tx_fes_setup *tx_fes_setup = tlv_data; + + info[0] = __le32_to_cpu(tx_fes_setup->info0); + tx_ppdu_info->ppdu_id = __le32_to_cpu(tx_fes_setup->schedule_id); + tx_ppdu_info->num_users = + u32_get_bits(info[0], HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); + status = DP_MON_TX_FES_SETUP; + break; + } + + case HAL_TX_FES_STATUS_END: { + const struct hal_tx_fes_status_end *tx_fes_status_end = tlv_data; + u32 tst_15_0, tst_31_16; + + info[0] = __le32_to_cpu(tx_fes_status_end->info0); + tst_15_0 = + u32_get_bits(info[0], + HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_15_0); + tst_31_16 = + u32_get_bits(info[0], + HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_31_16); + + tx_ppdu_info->rx_status.ppdu_ts = (tst_15_0 | (tst_31_16 << 16)); + status = DP_MON_TX_FES_STATUS_END; + break; + } + + case HAL_RX_RESPONSE_REQUIRED_INFO: { + const struct hal_rx_resp_req_info *rx_resp_req_info = tlv_data; + u32 addr_32; + u16 addr_16; + + info[0] = __le32_to_cpu(rx_resp_req_info->info0); + info[1] = __le32_to_cpu(rx_resp_req_info->info1); + info[2] = __le32_to_cpu(rx_resp_req_info->info2); + info[3] = __le32_to_cpu(rx_resp_req_info->info3); + info[4] = __le32_to_cpu(rx_resp_req_info->info4); + info[5] = __le32_to_cpu(rx_resp_req_info->info5); + + tx_ppdu_info->rx_status.ppdu_id = + u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_PPDU_ID); + tx_ppdu_info->rx_status.reception_type = + u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_RECEPTION_TYPE); + tx_ppdu_info->rx_status.rx_duration = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_DURATION); + tx_ppdu_info->rx_status.mcs = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_RATE_MCS); + tx_ppdu_info->rx_status.sgi = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_SGI); + tx_ppdu_info->rx_status.is_stbc = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_STBC); + tx_ppdu_info->rx_status.ldpc = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_LDPC); + tx_ppdu_info->rx_status.is_ampdu = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_IS_AMPDU); + tx_ppdu_info->rx_status.num_users = + u32_get_bits(info[2], HAL_RX_RESP_REQ_INFO2_NUM_USER); + + addr_32 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO3_ADDR1_31_0); + addr_16 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO4_ADDR1_47_32); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); + + addr_16 = u32_get_bits(info[4], HAL_RX_RESP_REQ_INFO4_ADDR1_15_0); + addr_32 = u32_get_bits(info[5], HAL_RX_RESP_REQ_INFO5_ADDR1_47_16); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2); + + if (tx_ppdu_info->rx_status.reception_type == 0) + ath12k_wifi7_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); + status = DP_MON_RX_RESPONSE_REQUIRED_INFO; + break; + } + + case HAL_PCU_PPDU_SETUP_INIT: { + const struct hal_tx_pcu_ppdu_setup_init *ppdu_setup = tlv_data; + u32 addr_32; + u16 addr_16; + + info[0] = __le32_to_cpu(ppdu_setup->info0); + info[1] = __le32_to_cpu(ppdu_setup->info1); + info[2] = __le32_to_cpu(ppdu_setup->info2); + info[3] = __le32_to_cpu(ppdu_setup->info3); + info[4] = __le32_to_cpu(ppdu_setup->info4); + info[5] = __le32_to_cpu(ppdu_setup->info5); + info[6] = __le32_to_cpu(ppdu_setup->info6); + + /* protection frame address 1 */ + addr_32 = u32_get_bits(info[1], + HAL_TX_PPDU_SETUP_INFO1_PROT_FRAME_ADDR1_31_0); + addr_16 = u32_get_bits(info[2], + HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR1_47_32); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); + + /* protection frame address 2 */ + addr_16 = u32_get_bits(info[2], + HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR2_15_0); + addr_32 = u32_get_bits(info[3], + HAL_TX_PPDU_SETUP_INFO3_PROT_FRAME_ADDR2_47_16); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2); + + /* protection frame address 3 */ + addr_32 = u32_get_bits(info[4], + HAL_TX_PPDU_SETUP_INFO4_PROT_FRAME_ADDR3_31_0); + addr_16 = u32_get_bits(info[5], + HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR3_47_32); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr3); + + /* protection frame address 4 */ + addr_16 = u32_get_bits(info[5], + HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR4_15_0); + addr_32 = u32_get_bits(info[6], + HAL_TX_PPDU_SETUP_INFO6_PROT_FRAME_ADDR4_47_16); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr4); + + status = u32_get_bits(info[0], + HAL_TX_PPDU_SETUP_INFO0_MEDIUM_PROT_TYPE); + break; + } + + case HAL_TX_QUEUE_EXTENSION: { + const struct hal_tx_queue_exten *tx_q_exten = tlv_data; + + info[0] = __le32_to_cpu(tx_q_exten->info0); + + tx_ppdu_info->rx_status.frame_control = + u32_get_bits(info[0], + HAL_TX_Q_EXT_INFO0_FRAME_CTRL); + tx_ppdu_info->rx_status.fc_valid = true; + break; + } + + case HAL_TX_FES_STATUS_START: { + const struct hal_tx_fes_status_start *tx_fes_start = tlv_data; + + info[0] = __le32_to_cpu(tx_fes_start->info0); + + tx_ppdu_info->rx_status.medium_prot_type = + u32_get_bits(info[0], + HAL_TX_FES_STATUS_START_INFO0_MEDIUM_PROT_TYPE); + break; + } + + case HAL_TX_FES_STATUS_PROT: { + const struct hal_tx_fes_status_prot *tx_fes_status = tlv_data; + u32 start_timestamp; + u32 end_timestamp; + + info[0] = __le32_to_cpu(tx_fes_status->info0); + info[1] = __le32_to_cpu(tx_fes_status->info1); + + start_timestamp = + u32_get_bits(info[0], + HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_15_0); + start_timestamp |= + u32_get_bits(info[0], + HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_31_16) << 15; + end_timestamp = + u32_get_bits(info[1], + HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_15_0); + end_timestamp |= + u32_get_bits(info[1], + HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_31_16) << 15; + tx_ppdu_info->rx_status.rx_duration = end_timestamp - start_timestamp; + + ath12k_wifi7_dp_mon_tx_gen_prot_frame(tx_ppdu_info); + break; + } + + case HAL_TX_FES_STATUS_START_PPDU: + case HAL_TX_FES_STATUS_START_PROT: { + const struct hal_tx_fes_status_start_prot *tx_fes_stat_start = tlv_data; + u64 ppdu_ts; + + info[0] = __le32_to_cpu(tx_fes_stat_start->info0); + + tx_ppdu_info->rx_status.ppdu_ts = + u32_get_bits(info[0], + HAL_TX_FES_STAT_STRT_INFO0_PROT_TS_LOWER_32); + ppdu_ts = (u32_get_bits(info[1], + HAL_TX_FES_STAT_STRT_INFO1_PROT_TS_UPPER_32)); + tx_ppdu_info->rx_status.ppdu_ts |= ppdu_ts << 32; + break; + } + + case HAL_TX_FES_STATUS_USER_PPDU: { + const struct hal_tx_fes_status_user_ppdu *tx_fes_usr_ppdu = tlv_data; + + info[0] = __le32_to_cpu(tx_fes_usr_ppdu->info0); + + tx_ppdu_info->rx_status.rx_duration = + u32_get_bits(info[0], + HAL_TX_FES_STAT_USR_PPDU_INFO0_DURATION); + break; + } + + case HAL_MACTX_HE_SIG_A_SU: + ath12k_dp_mon_parse_he_sig_su(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_HE_SIG_A_MU_DL: + ath12k_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_HE_SIG_B1_MU: + ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_HE_SIG_B2_MU: + ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_HE_SIG_B2_OFDMA: + ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_VHT_SIG_A: + ath12k_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_L_SIG_A: + ath12k_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_L_SIG_B: + ath12k_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_RX_FRAME_BITMAP_ACK: { + const struct hal_rx_frame_bitmap_ack *fbm_ack = tlv_data; + u32 addr_32; + u16 addr_16; + + info[0] = __le32_to_cpu(fbm_ack->info0); + info[1] = __le32_to_cpu(fbm_ack->info1); + + addr_32 = u32_get_bits(info[0], + HAL_RX_FBM_ACK_INFO0_ADDR1_31_0); + addr_16 = u32_get_bits(info[1], + HAL_RX_FBM_ACK_INFO1_ADDR1_47_32); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); + + ath12k_wifi7_dp_mon_tx_gen_ack_frame(tx_ppdu_info); + break; + } + + case HAL_MACTX_PHY_DESC: { + const struct hal_tx_phy_desc *tx_phy_desc = tlv_data; + + info[0] = __le32_to_cpu(tx_phy_desc->info0); + info[1] = __le32_to_cpu(tx_phy_desc->info1); + info[2] = __le32_to_cpu(tx_phy_desc->info2); + info[3] = __le32_to_cpu(tx_phy_desc->info3); + + tx_ppdu_info->rx_status.beamformed = + u32_get_bits(info[0], + HAL_TX_PHY_DESC_INFO0_BF_TYPE); + tx_ppdu_info->rx_status.preamble_type = + u32_get_bits(info[0], + HAL_TX_PHY_DESC_INFO0_PREAMBLE_11B); + tx_ppdu_info->rx_status.mcs = + u32_get_bits(info[1], + HAL_TX_PHY_DESC_INFO1_MCS); + tx_ppdu_info->rx_status.ltf_size = + u32_get_bits(info[3], + HAL_TX_PHY_DESC_INFO3_LTF_SIZE); + tx_ppdu_info->rx_status.nss = + u32_get_bits(info[2], + HAL_TX_PHY_DESC_INFO2_NSS); + tx_ppdu_info->rx_status.chan_num = + u32_get_bits(info[3], + HAL_TX_PHY_DESC_INFO3_ACTIVE_CHANNEL); + tx_ppdu_info->rx_status.bw = + u32_get_bits(info[0], + HAL_TX_PHY_DESC_INFO0_BANDWIDTH); + break; + } + + case HAL_TX_MPDU_START: { + struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu; + + mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC); + if (!mon_mpdu) + return DP_MON_TX_STATUS_PPDU_NOT_DONE; + status = DP_MON_TX_MPDU_START; + break; + } + + case HAL_TX_MPDU_END: + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + break; + } + + return status; +} + +static enum dp_mon_tx_tlv_status +ath12k_wifi7_dp_mon_tx_status_get_num_user(u16 tlv_tag, + struct hal_tlv_hdr *tx_tlv, + u8 *num_users) +{ + u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; + u32 info0; + + switch (tlv_tag) { + case HAL_TX_FES_SETUP: { + struct hal_tx_fes_setup *tx_fes_setup = + (struct hal_tx_fes_setup *)tx_tlv; + + info0 = __le32_to_cpu(tx_fes_setup->info0); + + *num_users = u32_get_bits(info0, HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); + tlv_status = DP_MON_TX_FES_SETUP; + break; + } + + case HAL_RX_RESPONSE_REQUIRED_INFO: { + /* TODO: need to update *num_users */ + tlv_status = DP_MON_RX_RESPONSE_REQUIRED_INFO; + break; + } + } + + return tlv_status; +} + +static void +ath12k_wifi7_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, + struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct dp_mon_mpdu *tmp, *mon_mpdu; + + list_for_each_entry_safe(mon_mpdu, tmp, + &tx_ppdu_info->dp_tx_mon_mpdu_list, list) { + list_del(&mon_mpdu->list); + + if (mon_mpdu->head) + ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, + &tx_ppdu_info->rx_status, napi); + + kfree(mon_mpdu); + } +} + +enum hal_rx_mon_status +ath12k_wifi7_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + struct sk_buff *skb, + struct napi_struct *napi, + u32 ppdu_id) +{ + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; + struct dp_mon_tx_ppdu_info *tx_prot_ppdu_info, *tx_data_ppdu_info; + struct hal_tlv_hdr *tlv; + u8 *ptr = skb->data; + u16 tlv_tag; + u16 tlv_len; + u32 tlv_userid = 0; + u8 num_user; + u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; + + tx_prot_ppdu_info = + ath12k_wifi7_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, + DP_MON_TX_PROT_PPDU_INFO); + if (!tx_prot_ppdu_info) + return -ENOMEM; + + tlv = (struct hal_tlv_hdr *)ptr; + tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG); + + tlv_status = ath12k_wifi7_dp_mon_tx_status_get_num_user(tlv_tag, tlv, + &num_user); + if (tlv_status == DP_MON_TX_STATUS_PPDU_NOT_DONE || !num_user) + return -EINVAL; + + tx_data_ppdu_info = + ath12k_wifi7_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, + DP_MON_TX_DATA_PPDU_INFO); + if (!tx_data_ppdu_info) + return -ENOMEM; + + do { + tlv = (struct hal_tlv_hdr *)ptr; + tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG); + tlv_len = le32_get_bits(tlv->tl, HAL_TLV_HDR_LEN); + tlv_userid = le32_get_bits(tlv->tl, HAL_TLV_USR_ID); + + tlv_status = ath12k_wifi7_dp_mon_tx_parse_status_tlv(ab, pmon, + tlv_tag, ptr, + tlv_userid); + ptr += tlv_len; + ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN); + if ((ptr - skb->data) >= DP_TX_MONITOR_BUF_SIZE) + break; + } while (tlv_status != DP_MON_TX_FES_STATUS_END); + + ath12k_wifi7_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_data_ppdu_info); + ath12k_wifi7_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_prot_ppdu_info); + + return tlv_status; +} + static u32 ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, void *ring_entry, struct sk_buff **head_msdu, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h index 3cf82864c41c..148d1e0b70fe 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h @@ -14,4 +14,10 @@ enum dp_monitor_mode; int ath12k_wifi7_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, struct napi_struct *napi, int budget, enum dp_monitor_mode monitor_mode); +enum hal_rx_mon_status +ath12k_wifi7_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + struct sk_buff *skb, + struct napi_struct *napi, + u32 ppdu_id); #endif -- 2.34.1 Separate Wi-Fi 7-specific monitor parsing from ath12k common code to improve modularity and keep Wi-Fi 7 logic within the Wi-Fi 7 module. Move following HT/VHT SIG parsing functions to wifi7/dp_mon.c and rename the functions with the ath12k_wifi7 prefix: - ath12k_dp_mon_parse_vht_sig_a() - ath12k_dp_mon_parse_ht_sig() Export helper functions required by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh --- drivers/net/wireless/ath/ath12k/dp_mon.c | 56 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 4 -- .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 62 ++++++++++++++++++- 3 files changed, 59 insertions(+), 63 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index d3e662399c31..879dc86fcdb7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -81,62 +81,6 @@ ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats * } EXPORT_SYMBOL(ath12k_dp_mon_rx_populate_mu_user_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; - - info0 = __le32_to_cpu(vht_sig->info0); - info1 = __le32_to_cpu(vht_sig->info1); - - ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); - ppdu_info->mcs = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_MCS); - gi_setting = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING); - switch (gi_setting) { - case HAL_RX_VHT_SIG_A_NORMAL_GI: - ppdu_info->gi = HAL_RX_GI_0_8_US; - break; - case HAL_RX_VHT_SIG_A_SHORT_GI: - case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY: - ppdu_info->gi = HAL_RX_GI_0_4_US; - break; - } - - ppdu_info->is_stbc = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_STBC); - nsts = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS); - if (ppdu_info->is_stbc && nsts > 0) - nsts = ((nsts + 1) >> 1) - 1; - - ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK); - ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW); - ppdu_info->beamformed = u32_get_bits(info1, - HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED); - ppdu_info->vht_flag_values5 = u32_get_bits(info0, - HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID); - ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) | - ppdu_info->nss); - ppdu_info->vht_flag_values2 = ppdu_info->bw; - 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); - -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->mcs = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_MCS); - ppdu_info->bw = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_BW); - ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC); - ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING); - 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); - void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, struct hal_rx_mon_ppdu_info *ppdu_info) { diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 1d2ec4072a83..86d0c18d8c07 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -113,8 +113,6 @@ 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); @@ -135,8 +133,6 @@ ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *of 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 diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index abdfd3cfd0e4..0c83df4be9da 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -20,6 +20,62 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static void +ath12k_wifi7_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; + + info0 = __le32_to_cpu(vht_sig->info0); + info1 = __le32_to_cpu(vht_sig->info1); + + ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); + ppdu_info->mcs = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_MCS); + gi_setting = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING); + switch (gi_setting) { + case HAL_RX_VHT_SIG_A_NORMAL_GI: + ppdu_info->gi = HAL_RX_GI_0_8_US; + break; + case HAL_RX_VHT_SIG_A_SHORT_GI: + case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY: + ppdu_info->gi = HAL_RX_GI_0_4_US; + break; + } + + ppdu_info->is_stbc = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_STBC); + nsts = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS); + if (ppdu_info->is_stbc && nsts > 0) + nsts = ((nsts + 1) >> 1) - 1; + + ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK); + ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW); + ppdu_info->beamformed = u32_get_bits(info1, + HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED); + ppdu_info->vht_flag_values5 = u32_get_bits(info0, + HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID); + ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) | + ppdu_info->nss); + ppdu_info->vht_flag_values2 = ppdu_info->bw; + ppdu_info->vht_flag_values4 = + u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); +} + +static void +ath12k_wifi7_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->mcs = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_MCS); + ppdu_info->bw = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_BW); + ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC); + ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING); + ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI); + ppdu_info->nss = (ppdu_info->mcs >> 3); +} + 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, @@ -158,7 +214,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; } case HAL_PHYRX_HT_SIG: - ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_ht_sig(tlv_data, ppdu_info); break; case HAL_PHYRX_L_SIG_B: @@ -170,7 +226,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; case HAL_PHYRX_VHT_SIG_A: - ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); break; case HAL_PHYRX_HE_SIG_A_SU: @@ -819,7 +875,7 @@ ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, break; case HAL_MACTX_VHT_SIG_A: - ath12k_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status); break; case HAL_MACTX_L_SIG_A: -- 2.34.1 Separate Wi-Fi 7-specific monitor code from ath12k common code to improve modularity. Move following HE SIG processing functions to the wifi7/dp_mon.c and rename the relocated functions with the ath12k_wifi7 prefix: - ath12k_dp_mon_parse_he_sig_b2_ofdma() - ath12k_dp_mon_parse_he_sig_b2_mu() - ath12k_dp_mon_parse_he_sig_b1_mu() - ath12k_dp_mon_parse_he_sig_mu() - ath12k_dp_mon_parse_he_sig_su() Export helper functions required by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh --- drivers/net/wireless/ath/ath12k/dp_mon.c | 360 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 14 - .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 380 +++++++++++++++++- 3 files changed, 370 insertions(+), 384 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 879dc86fcdb7..df9203d90f00 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -153,366 +153,6 @@ void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, } EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_a); -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) -{ - u32 info0, value; - - info0 = __le32_to_cpu(ofdma->info0); - - ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_DCM_KNOWN | HE_CODING_KNOWN; - - /* HE-data2 */ - ppdu_info->he_data2 |= HE_TXBF_KNOWN; - - ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS); - value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM); - value = value << HE_DCM_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING); - ppdu_info->ldpc = value; - value = value << HE_CODING_SHIFT; - ppdu_info->he_data3 |= value; - - /* HE-data4 */ - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID); - value = value << HE_STA_ID_SHIFT; - ppdu_info->he_data4 |= value; - - ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS); - 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); - -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) -{ - u32 info0, value; - - info0 = __le32_to_cpu(he_sig_b2_mu->info0); - - ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_CODING_KNOWN; - - ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS); - value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING); - ppdu_info->ldpc = value; - value = value << HE_CODING_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID); - value = value << HE_STA_ID_SHIFT; - ppdu_info->he_data4 |= value; - - 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); - -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) -{ - u32 info0 = __le32_to_cpu(he_sig_b1_mu->info0); - u16 ru_tones; - - ru_tones = u32_get_bits(info0, - HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION); - 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); - -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) -{ - u32 info0, info1, value; - u16 he_gi = 0, he_ltf = 0; - - info0 = __le32_to_cpu(he_sig_a_mu_dl->info0); - info1 = __le32_to_cpu(he_sig_a_mu_dl->info1); - - ppdu_info->he_mu_flags = 1; - - ppdu_info->he_data1 = HE_MU_FORMAT_TYPE; - ppdu_info->he_data1 |= - HE_BSS_COLOR_KNOWN | - HE_DL_UL_KNOWN | - HE_LDPC_EXTRA_SYMBOL_KNOWN | - HE_STBC_KNOWN | - HE_DATA_BW_RU_KNOWN | - HE_DOPPLER_KNOWN; - - ppdu_info->he_data2 = - HE_GI_KNOWN | - HE_LTF_SYMBOLS_KNOWN | - HE_PRE_FEC_PADDING_KNOWN | - HE_PE_DISAMBIGUITY_KNOWN | - HE_TXOP_KNOWN | - HE_MIDABLE_PERIODICITY_KNOWN; - - /* data3 */ - ppdu_info->he_data3 = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_BSS_COLOR); - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_UL_FLAG); - value = value << HE_DL_UL_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_LDPC_EXTRA); - value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC); - value = value << HE_STBC_SHIFT; - ppdu_info->he_data3 |= value; - - /* data4 */ - ppdu_info->he_data4 = u32_get_bits(info0, - HAL_RX_HE_SIG_A_MU_DL_INFO0_SPATIAL_REUSE); - ppdu_info->he_data4 = value; - - /* data5 */ - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); - ppdu_info->he_data5 = value; - ppdu_info->bw = value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_CP_LTF_SIZE); - switch (value) { - case 0: - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_4_X; - break; - case 1: - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_2_X; - break; - case 2: - he_gi = HE_GI_1_6; - he_ltf = HE_LTF_2_X; - break; - case 3: - he_gi = HE_GI_3_2; - he_ltf = HE_LTF_4_X; - break; - } - - ppdu_info->gi = he_gi; - value = he_gi << HE_GI_SHIFT; - ppdu_info->he_data5 |= value; - - value = he_ltf << HE_LTF_SIZE_SHIFT; - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_NUM_LTF_SYMB); - value = (value << HE_LTF_SYM_SHIFT); - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_FACTOR); - value = value << HE_PRE_FEC_PAD_SHIFT; - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_PE_DISAM); - value = value << HE_PE_DISAMBIGUITY_SHIFT; - ppdu_info->he_data5 |= value; - - /*data6*/ - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DOPPLER_INDICATION); - value = value << HE_DOPPLER_SHIFT; - ppdu_info->he_data6 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_TXOP_DURATION); - value = value << HE_TXOP_SHIFT; - ppdu_info->he_data6 |= value; - - /* HE-MU Flags */ - /* HE-MU-flags1 */ - ppdu_info->he_flags1 = - HE_SIG_B_MCS_KNOWN | - HE_SIG_B_DCM_KNOWN | - HE_SIG_B_COMPRESSION_FLAG_1_KNOWN | - HE_SIG_B_SYM_NUM_KNOWN | - HE_RU_0_KNOWN; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_MCS_OF_SIGB); - ppdu_info->he_flags1 |= value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DCM_OF_SIGB); - value = value << HE_DCM_FLAG_1_SHIFT; - ppdu_info->he_flags1 |= value; - - /* HE-MU-flags2 */ - ppdu_info->he_flags2 = HE_BW_KNOWN; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); - ppdu_info->he_flags2 |= value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_COMP_MODE_SIGB); - value = value << HE_SIG_B_COMPRESSION_FLAG_2_SHIFT; - ppdu_info->he_flags2 |= value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_NUM_SIGB_SYMB); - value = value - 1; - value = value << HE_NUM_SIG_B_SYMBOLS_SHIFT; - ppdu_info->he_flags2 |= value; - - ppdu_info->is_stbc = info1 & - HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_mu); - -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; - u8 he_dcm = 0, he_stbc = 0; - u16 he_gi = 0, he_ltf = 0; - - ppdu_info->he_flags = 1; - - info0 = __le32_to_cpu(he_sig_a->info0); - info1 = __le32_to_cpu(he_sig_a->info1); - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND); - if (value == 0) - ppdu_info->he_data1 = HE_TRIG_FORMAT_TYPE; - else - ppdu_info->he_data1 = HE_SU_FORMAT_TYPE; - - ppdu_info->he_data1 |= - HE_BSS_COLOR_KNOWN | - HE_BEAM_CHANGE_KNOWN | - HE_DL_UL_KNOWN | - HE_MCS_KNOWN | - HE_DCM_KNOWN | - HE_CODING_KNOWN | - HE_LDPC_EXTRA_SYMBOL_KNOWN | - HE_STBC_KNOWN | - HE_DATA_BW_RU_KNOWN | - HE_DOPPLER_KNOWN; - - ppdu_info->he_data2 |= - HE_GI_KNOWN | - HE_TXBF_KNOWN | - HE_PE_DISAMBIGUITY_KNOWN | - HE_TXOP_KNOWN | - HE_LTF_SYMBOLS_KNOWN | - HE_PRE_FEC_PADDING_KNOWN | - HE_MIDABLE_PERIODICITY_KNOWN; - - ppdu_info->he_data3 = u32_get_bits(info0, - HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR); - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE); - value = value << HE_BEAM_CHANGE_SHIFT; - ppdu_info->he_data3 |= value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG); - value = value << HE_DL_UL_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); - ppdu_info->mcs = value; - value = value << HE_TRANSMIT_MCS_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); - he_dcm = value; - value = value << HE_DCM_SHIFT; - ppdu_info->he_data3 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); - value = value << HE_CODING_SHIFT; - ppdu_info->he_data3 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA); - value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; - ppdu_info->he_data3 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); - he_stbc = value; - value = value << HE_STBC_SHIFT; - ppdu_info->he_data3 |= value; - - /* data4 */ - ppdu_info->he_data4 = u32_get_bits(info0, - HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE); - - /* data5 */ - value = u32_get_bits(info0, - HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); - ppdu_info->he_data5 = value; - ppdu_info->bw = value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE); - switch (value) { - case 0: - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_1_X; - break; - case 1: - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_2_X; - break; - case 2: - he_gi = HE_GI_1_6; - he_ltf = HE_LTF_2_X; - break; - case 3: - if (he_dcm && he_stbc) { - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_4_X; - } else { - he_gi = HE_GI_3_2; - he_ltf = HE_LTF_4_X; - } - break; - } - ppdu_info->gi = he_gi; - value = he_gi << HE_GI_SHIFT; - ppdu_info->he_data5 |= value; - value = he_ltf << HE_LTF_SIZE_SHIFT; - ppdu_info->ltf_size = he_ltf; - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); - value = (value << HE_LTF_SYM_SHIFT); - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR); - value = value << HE_PRE_FEC_PAD_SHIFT; - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); - value = value << HE_TXBF_SHIFT; - ppdu_info->he_data5 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM); - value = value << HE_PE_DISAMBIGUITY_SHIFT; - ppdu_info->he_data5 |= value; - - /* data6 */ - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); - value++; - ppdu_info->he_data6 = value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND); - value = value << HE_DOPPLER_SHIFT; - ppdu_info->he_data6 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION); - value = value << HE_TXOP_SHIFT; - ppdu_info->he_data6 |= value; - - ppdu_info->mcs = - u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); - ppdu_info->bw = - u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); - ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); - ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); - ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); - dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_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, struct hal_rx_mon_ppdu_info *ppdu_info) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 86d0c18d8c07..90811a2f75a7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -128,20 +128,6 @@ void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, 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_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); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 0c83df4be9da..f6d41ded5715 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -76,6 +76,362 @@ ath12k_wifi7_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, ppdu_info->nss = (ppdu_info->mcs >> 3); } +static void +ath12k_wifi7_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) +{ + u32 info0, value; + + info0 = __le32_to_cpu(ofdma->info0); + + ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_DCM_KNOWN | HE_CODING_KNOWN; + + /* HE-data2 */ + ppdu_info->he_data2 |= HE_TXBF_KNOWN; + + ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS); + value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM); + value = value << HE_DCM_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING); + ppdu_info->ldpc = value; + value = value << HE_CODING_SHIFT; + ppdu_info->he_data3 |= value; + + /* HE-data4 */ + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID); + value = value << HE_STA_ID_SHIFT; + ppdu_info->he_data4 |= value; + + ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS); + ppdu_info->beamformed = u32_get_bits(info0, + HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF); +} + +static void +ath12k_wifi7_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) +{ + u32 info0, value; + + info0 = __le32_to_cpu(he_sig_b2_mu->info0); + + ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_CODING_KNOWN; + + ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS); + value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING); + ppdu_info->ldpc = value; + value = value << HE_CODING_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID); + value = value << HE_STA_ID_SHIFT; + ppdu_info->he_data4 |= value; + + ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS); +} + +static void +ath12k_wifi7_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) +{ + u32 info0 = __le32_to_cpu(he_sig_b1_mu->info0); + u16 ru_tones; + + ru_tones = u32_get_bits(info0, + HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION); + ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); + ppdu_info->he_RU[0] = ru_tones; +} + +static void +ath12k_wifi7_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) +{ + u32 info0, info1, value; + u16 he_gi = 0, he_ltf = 0; + + info0 = __le32_to_cpu(he_sig_a_mu_dl->info0); + info1 = __le32_to_cpu(he_sig_a_mu_dl->info1); + + ppdu_info->he_mu_flags = 1; + + ppdu_info->he_data1 = HE_MU_FORMAT_TYPE; + ppdu_info->he_data1 |= + HE_BSS_COLOR_KNOWN | + HE_DL_UL_KNOWN | + HE_LDPC_EXTRA_SYMBOL_KNOWN | + HE_STBC_KNOWN | + HE_DATA_BW_RU_KNOWN | + HE_DOPPLER_KNOWN; + + ppdu_info->he_data2 = + HE_GI_KNOWN | + HE_LTF_SYMBOLS_KNOWN | + HE_PRE_FEC_PADDING_KNOWN | + HE_PE_DISAMBIGUITY_KNOWN | + HE_TXOP_KNOWN | + HE_MIDABLE_PERIODICITY_KNOWN; + + /* data3 */ + ppdu_info->he_data3 = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_BSS_COLOR); + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_UL_FLAG); + value = value << HE_DL_UL_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_LDPC_EXTRA); + value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC); + value = value << HE_STBC_SHIFT; + ppdu_info->he_data3 |= value; + + /* data4 */ + ppdu_info->he_data4 = u32_get_bits(info0, + HAL_RX_HE_SIG_A_MU_DL_INFO0_SPATIAL_REUSE); + ppdu_info->he_data4 = value; + + /* data5 */ + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); + ppdu_info->he_data5 = value; + ppdu_info->bw = value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_CP_LTF_SIZE); + switch (value) { + case 0: + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_4_X; + break; + case 1: + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_2_X; + break; + case 2: + he_gi = HE_GI_1_6; + he_ltf = HE_LTF_2_X; + break; + case 3: + he_gi = HE_GI_3_2; + he_ltf = HE_LTF_4_X; + break; + } + + ppdu_info->gi = he_gi; + value = he_gi << HE_GI_SHIFT; + ppdu_info->he_data5 |= value; + + value = he_ltf << HE_LTF_SIZE_SHIFT; + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_NUM_LTF_SYMB); + value = (value << HE_LTF_SYM_SHIFT); + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_FACTOR); + value = value << HE_PRE_FEC_PAD_SHIFT; + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_PE_DISAM); + value = value << HE_PE_DISAMBIGUITY_SHIFT; + ppdu_info->he_data5 |= value; + + /*data6*/ + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DOPPLER_INDICATION); + value = value << HE_DOPPLER_SHIFT; + ppdu_info->he_data6 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_TXOP_DURATION); + value = value << HE_TXOP_SHIFT; + ppdu_info->he_data6 |= value; + + /* HE-MU Flags */ + /* HE-MU-flags1 */ + ppdu_info->he_flags1 = + HE_SIG_B_MCS_KNOWN | + HE_SIG_B_DCM_KNOWN | + HE_SIG_B_COMPRESSION_FLAG_1_KNOWN | + HE_SIG_B_SYM_NUM_KNOWN | + HE_RU_0_KNOWN; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_MCS_OF_SIGB); + ppdu_info->he_flags1 |= value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DCM_OF_SIGB); + value = value << HE_DCM_FLAG_1_SHIFT; + ppdu_info->he_flags1 |= value; + + /* HE-MU-flags2 */ + ppdu_info->he_flags2 = HE_BW_KNOWN; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); + ppdu_info->he_flags2 |= value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_COMP_MODE_SIGB); + value = value << HE_SIG_B_COMPRESSION_FLAG_2_SHIFT; + ppdu_info->he_flags2 |= value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_NUM_SIGB_SYMB); + value = value - 1; + value = value << HE_NUM_SIG_B_SYMBOLS_SHIFT; + ppdu_info->he_flags2 |= value; + + ppdu_info->is_stbc = info1 & + HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC; +} + +static void +ath12k_wifi7_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; + u8 he_dcm = 0, he_stbc = 0; + u16 he_gi = 0, he_ltf = 0; + + ppdu_info->he_flags = 1; + + info0 = __le32_to_cpu(he_sig_a->info0); + info1 = __le32_to_cpu(he_sig_a->info1); + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND); + if (value == 0) + ppdu_info->he_data1 = HE_TRIG_FORMAT_TYPE; + else + ppdu_info->he_data1 = HE_SU_FORMAT_TYPE; + + ppdu_info->he_data1 |= + HE_BSS_COLOR_KNOWN | + HE_BEAM_CHANGE_KNOWN | + HE_DL_UL_KNOWN | + HE_MCS_KNOWN | + HE_DCM_KNOWN | + HE_CODING_KNOWN | + HE_LDPC_EXTRA_SYMBOL_KNOWN | + HE_STBC_KNOWN | + HE_DATA_BW_RU_KNOWN | + HE_DOPPLER_KNOWN; + + ppdu_info->he_data2 |= + HE_GI_KNOWN | + HE_TXBF_KNOWN | + HE_PE_DISAMBIGUITY_KNOWN | + HE_TXOP_KNOWN | + HE_LTF_SYMBOLS_KNOWN | + HE_PRE_FEC_PADDING_KNOWN | + HE_MIDABLE_PERIODICITY_KNOWN; + + ppdu_info->he_data3 = u32_get_bits(info0, + HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR); + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE); + value = value << HE_BEAM_CHANGE_SHIFT; + ppdu_info->he_data3 |= value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG); + value = value << HE_DL_UL_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); + ppdu_info->mcs = value; + value = value << HE_TRANSMIT_MCS_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); + he_dcm = value; + value = value << HE_DCM_SHIFT; + ppdu_info->he_data3 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); + value = value << HE_CODING_SHIFT; + ppdu_info->he_data3 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA); + value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; + ppdu_info->he_data3 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); + he_stbc = value; + value = value << HE_STBC_SHIFT; + ppdu_info->he_data3 |= value; + + /* data4 */ + ppdu_info->he_data4 = u32_get_bits(info0, + HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE); + + /* data5 */ + value = u32_get_bits(info0, + HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); + ppdu_info->he_data5 = value; + ppdu_info->bw = value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE); + switch (value) { + case 0: + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_1_X; + break; + case 1: + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_2_X; + break; + case 2: + he_gi = HE_GI_1_6; + he_ltf = HE_LTF_2_X; + break; + case 3: + if (he_dcm && he_stbc) { + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_4_X; + } else { + he_gi = HE_GI_3_2; + he_ltf = HE_LTF_4_X; + } + break; + } + ppdu_info->gi = he_gi; + value = he_gi << HE_GI_SHIFT; + ppdu_info->he_data5 |= value; + value = he_ltf << HE_LTF_SIZE_SHIFT; + ppdu_info->ltf_size = he_ltf; + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); + value = (value << HE_LTF_SYM_SHIFT); + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR); + value = value << HE_PRE_FEC_PAD_SHIFT; + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); + value = value << HE_TXBF_SHIFT; + ppdu_info->he_data5 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM); + value = value << HE_PE_DISAMBIGUITY_SHIFT; + ppdu_info->he_data5 |= value; + + /* data6 */ + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); + value++; + ppdu_info->he_data6 = value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND); + value = value << HE_DOPPLER_SHIFT; + ppdu_info->he_data6 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION); + value = value << HE_TXOP_SHIFT; + ppdu_info->he_data6 |= value; + + ppdu_info->mcs = + u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); + ppdu_info->bw = + u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); + ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); + ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); + ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); + dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); + ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); + ppdu_info->dcm = dcm; +} + 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, @@ -230,23 +586,23 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; case HAL_PHYRX_HE_SIG_A_SU: - ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info); + ath12k_wifi7_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); + ath12k_wifi7_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); + ath12k_wifi7_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); + ath12k_wifi7_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); + ath12k_wifi7_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info); break; case HAL_PHYRX_RSSI_LEGACY: { @@ -855,23 +1211,27 @@ ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, } case HAL_MACTX_HE_SIG_A_SU: - ath12k_dp_mon_parse_he_sig_su(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_su(tlv_data, + &tx_ppdu_info->rx_status); break; case HAL_MACTX_HE_SIG_A_MU_DL: - ath12k_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status); break; case HAL_MACTX_HE_SIG_B1_MU: - ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_b1_mu(tlv_data, + &tx_ppdu_info->rx_status); break; case HAL_MACTX_HE_SIG_B2_MU: - ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_b2_mu(tlv_data, + &tx_ppdu_info->rx_status); break; case HAL_MACTX_HE_SIG_B2_OFDMA: - ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_b2_ofdma(tlv_data, + &tx_ppdu_info->rx_status); break; case HAL_MACTX_VHT_SIG_A: -- 2.34.1 Split Wi-Fi 7 specific EHT SIG parsing out of ath12k common code into the Wi-Fi 7 module to improve modularity. Move the following EHT SIG processing functions to wifi7/dp_mon.c and add the ath12k_wifi7 prefix to each relocated function. - ath12k_dp_mon_hal_aggr_tlv() - ath12k_dp_mon_hal_rx_is_frame_type_ndp() - ath12k_dp_mon_hal_rx_is_non_ofdma() - ath12k_dp_mon_hal_rx_is_ofdma() - ath12k_dp_mon_hal_rx_parse_eht_sig_ndp() - ath12k_dp_mon_hal_rx_parse_usig_overflow() - ath12k_dp_mon_hal_rx_parse_non_ofdma_users() - ath12k_dp_mon_hal_rx_parse_eht_mumimo_user() - ath12k_dp_mon_hal_rx_parse_eht_non_mumimo_user() - ath12k_dp_mon_hal_rx_is_mu_mimo_user() - ath12k_dp_mon_hal_rx_parse_eht_sig_non_ofdma() - ath12k_dp_mon_hal_rx_parse_ru_allocation() - ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma() - ath12k_dp_mon_parse_eht_sig_hdr() Export helper functions needed by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh --- drivers/net/wireless/ath/ath12k/dp_mon.c | 389 ------------------ drivers/net/wireless/ath/ath12k/dp_mon.h | 12 +- .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 386 ++++++++++++++++- 3 files changed, 390 insertions(+), 397 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index df9203d90f00..1ad984cd561e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -11,12 +11,6 @@ #include "dp_tx.h" #include "peer.h" -#define ATH12K_LE32_DEC_ENC(value, dec_bits, enc_bits) \ - u32_encode_bits(le32_get_bits(value, dec_bits), enc_bits) - -#define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ - u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) - 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) @@ -346,389 +340,6 @@ ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, } EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_u_sig_hdr); -void -ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, - u16 tlv_len, const void *tlv_data) -{ - if (tlv_len <= HAL_RX_MON_MAX_AGGR_SIZE - ppdu_info->tlv_aggr.cur_len) { - memcpy(ppdu_info->tlv_aggr.buf + ppdu_info->tlv_aggr.cur_len, - tlv_data, tlv_len); - 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) -{ - if (usig_info->ppdu_type_comp_mode == 1 && - usig_info->eht_sig_mcs == 0 && - usig_info->num_eht_sig_sym == 0) - return true; - - return false; -} - -static inline bool -ath12k_dp_mon_hal_rx_is_non_ofdma(const struct hal_rx_u_sig_info *usig_info) -{ - u32 ppdu_type_comp_mode = usig_info->ppdu_type_comp_mode; - u32 ul_dl = usig_info->ul_dl; - - if ((ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_MIMO && ul_dl == 0) || - (ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_OFDMA && ul_dl == 0) || - (ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_MIMO && ul_dl == 1)) - return true; - - return false; -} - -static inline bool -ath12k_dp_mon_hal_rx_is_ofdma(const struct hal_rx_u_sig_info *usig_info) -{ - if (usig_info->ppdu_type_comp_mode == 0 && usig_info->ul_dl == 0) - return true; - - return false; -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_sig_ndp(const struct hal_eht_sig_ndp_cmn_eb *eht_sig_ndp, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | - IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | - IEEE80211_RADIOTAP_EHT_KNOWN_NSS_S | - IEEE80211_RADIOTAP_EHT_KNOWN_BEAMFORMED_S | - IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_S | - IEEE80211_RADIOTAP_EHT_KNOWN_CRC1 | - IEEE80211_RADIOTAP_EHT_KNOWN_TAIL1; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[0]); - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_SPATIAL_REUSE, - IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); - /* GI and LTF size are separately indicated in radiotap header - * and hence will be parsed from other TLV - */ - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_NUM_LTF_SYM, - IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); - - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_CRC, - IEEE80211_RADIOTAP_EHT_DATA0_CRC1_O); - - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_DISREGARD, - IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_S); - eht->data[0] = cpu_to_le32(data); - - data = __le32_to_cpu(eht->data[7]); - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_NSS, - IEEE80211_RADIOTAP_EHT_DATA7_NSS_S); - - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_BEAMFORMED, - IEEE80211_RADIOTAP_EHT_DATA7_BEAMFORMED_S); - eht->data[7] = cpu_to_le32(data); -} - -static void -ath12k_dp_mon_hal_rx_parse_usig_overflow(const struct hal_eht_sig_usig_overflow *ovflow, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | - IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | - IEEE80211_RADIOTAP_EHT_KNOWN_LDPC_EXTRA_SYM_OM | - IEEE80211_RADIOTAP_EHT_KNOWN_PRE_PADD_FACOR_OM | - IEEE80211_RADIOTAP_EHT_KNOWN_PE_DISAMBIGUITY_OM | - IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_O; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[0]); - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_SPATIAL_REUSE, - IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); - - /* GI and LTF size are separately indicated in radiotap header - * and hence will be parsed from other TLV - */ - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_NUM_LTF_SYM, - IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); - - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_LDPC_EXTA_SYM, - IEEE80211_RADIOTAP_EHT_DATA0_LDPC_EXTRA_SYM_OM); - - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_PRE_FEC_PAD_FACTOR, - IEEE80211_RADIOTAP_EHT_DATA0_PRE_PADD_FACOR_OM); - - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_DISAMBIGUITY, - IEEE80211_RADIOTAP_EHT_DATA0_PE_DISAMBIGUITY_OM); - - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_DISREGARD, - IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_O); - eht->data[0] = cpu_to_le32(data); -} - -static void -ath12k_dp_mon_hal_rx_parse_non_ofdma_users(const struct hal_eht_sig_non_ofdma_cmn_eb *eb, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_NR_NON_OFDMA_USERS_M; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[7]); - data |= ATH12K_LE32_DEC_ENC(eb->info0, - HAL_RX_EHT_SIG_NON_OFDMA_INFO0_NUM_USERS, - IEEE80211_RADIOTAP_EHT_DATA7_NUM_OF_NON_OFDMA_USERS); - eht->data[7] = cpu_to_le32(data); -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_mumimo_user(const struct hal_eht_sig_mu_mimo *user, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_eht_info *eht_info = &ppdu_info->eht_info; - u32 user_idx; - - if (eht_info->num_user_info >= ARRAY_SIZE(eht_info->user_info)) - return; - - user_idx = eht_info->num_user_info++; - - eht_info->user_info[user_idx] |= - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_KNOWN_M | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_STA_ID, - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_CODING, - IEEE80211_RADIOTAP_EHT_USER_INFO_CODING) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_MCS, - IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_SPATIAL_CODING, - IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_M); - - ppdu_info->mcs = le32_get_bits(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_MCS); -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_non_mumimo_user(const struct hal_eht_sig_non_mu_mimo *user, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_eht_info *eht_info = &ppdu_info->eht_info; - u32 user_idx; - - if (eht_info->num_user_info >= ARRAY_SIZE(eht_info->user_info)) - return; - - user_idx = eht_info->num_user_info++; - - eht_info->user_info[user_idx] |= - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O | - IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_KNOWN_O | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_STA_ID, - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_CODING, - IEEE80211_RADIOTAP_EHT_USER_INFO_CODING) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_MCS, - IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_NSS, - IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_BEAMFORMED, - IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_O); - - ppdu_info->mcs = le32_get_bits(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_MCS); - - ppdu_info->nss = le32_get_bits(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_NSS) + 1; -} - -static inline bool -ath12k_dp_mon_hal_rx_is_mu_mimo_user(const struct hal_rx_u_sig_info *usig_info) -{ - if (usig_info->ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_SU && - usig_info->ul_dl == 1) - return true; - - return false; -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_sig_non_ofdma(const void *tlv, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - const struct hal_eht_sig_non_ofdma_cmn_eb *eb = tlv; - - ath12k_dp_mon_hal_rx_parse_usig_overflow(tlv, ppdu_info); - ath12k_dp_mon_hal_rx_parse_non_ofdma_users(eb, ppdu_info); - - if (ath12k_dp_mon_hal_rx_is_mu_mimo_user(&ppdu_info->u_sig_info)) - ath12k_dp_mon_hal_rx_parse_eht_mumimo_user(&eb->user_field.mu_mimo, - ppdu_info); - else - ath12k_dp_mon_hal_rx_parse_eht_non_mumimo_user(&eb->user_field.n_mu_mimo, - ppdu_info); -} - -static void -ath12k_dp_mon_hal_rx_parse_ru_allocation(const struct hal_eht_sig_ofdma_cmn_eb *eb, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - const struct hal_eht_sig_ofdma_cmn_eb1 *ofdma_cmn_eb1 = &eb->eb1; - const struct hal_eht_sig_ofdma_cmn_eb2 *ofdma_cmn_eb2 = &eb->eb2; - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - enum ieee80211_radiotap_eht_data ru_123, ru_124, ru_125, ru_126; - enum ieee80211_radiotap_eht_data ru_121, ru_122, ru_112, ru_111; - u32 data; - - ru_123 = IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3; - ru_124 = IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4; - ru_125 = IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5; - ru_126 = IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6; - ru_121 = IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1; - ru_122 = IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2; - ru_112 = IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2; - ru_111 = IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1; - - switch (ppdu_info->u_sig_info.bw) { - case HAL_EHT_BW_320_2: - case HAL_EHT_BW_320_1: - data = __le32_to_cpu(eht->data[4]); - /* CC1 2::3 */ - data |= IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_3, - ru_123); - eht->data[4] = cpu_to_le32(data); - - data = __le32_to_cpu(eht->data[5]); - /* CC1 2::4 */ - data |= IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_4, - ru_124); - - /* CC1 2::5 */ - data |= IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_5, - ru_125); - eht->data[5] = cpu_to_le32(data); - - data = __le32_to_cpu(eht->data[6]); - /* CC1 2::6 */ - data |= IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_6, - ru_126); - eht->data[6] = cpu_to_le32(data); - - fallthrough; - case HAL_EHT_BW_160: - data = __le32_to_cpu(eht->data[3]); - /* CC1 2::1 */ - data |= IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_1, - ru_121); - /* CC1 2::2 */ - data |= IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_2, - ru_122); - eht->data[3] = cpu_to_le32(data); - - fallthrough; - case HAL_EHT_BW_80: - data = __le32_to_cpu(eht->data[2]); - /* CC1 1::2 */ - data |= IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb1->info0, - HAL_RX_EHT_SIG_OFDMA_EB1_RU_ALLOC_1_2, - ru_112); - eht->data[2] = cpu_to_le32(data); - - fallthrough; - case HAL_EHT_BW_40: - fallthrough; - case HAL_EHT_BW_20: - data = __le32_to_cpu(eht->data[1]); - /* CC1 1::1 */ - data |= IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb1->info0, - HAL_RX_EHT_SIG_OFDMA_EB1_RU_ALLOC_1_1, - ru_111); - eht->data[1] = cpu_to_le32(data); - break; - default: - break; - } -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(const void *tlv, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - const struct hal_eht_sig_ofdma_cmn_eb *ofdma = tlv; - - ath12k_dp_mon_hal_rx_parse_usig_overflow(tlv, ppdu_info); - ath12k_dp_mon_hal_rx_parse_ru_allocation(ofdma, ppdu_info); - - ath12k_dp_mon_hal_rx_parse_eht_non_mumimo_user(&ofdma->user_field.n_mu_mimo, - ppdu_info); -} - -void -ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, - const void *tlv_data) -{ - ppdu_info->is_eht = true; - - if (ath12k_dp_mon_hal_rx_is_frame_type_ndp(&ppdu_info->u_sig_info)) - ath12k_dp_mon_hal_rx_parse_eht_sig_ndp(tlv_data, ppdu_info); - else if (ath12k_dp_mon_hal_rx_is_non_ofdma(&ppdu_info->u_sig_info)) - ath12k_dp_mon_hal_rx_parse_eht_sig_non_ofdma(tlv_data, ppdu_info); - else if (ath12k_dp_mon_hal_rx_is_ofdma(&ppdu_info->u_sig_info)) - ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info); -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_eht_sig_hdr); - static inline enum ath12k_eht_ru_size hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) { diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 90811a2f75a7..d2bee88f561f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -14,6 +14,12 @@ #define ATH12K_MON_RX_DOT11_OFFSET 5 #define ATH12K_MON_RX_PKT_OFFSET 8 +#define ATH12K_LE32_DEC_ENC(value, dec_bits, enc_bits) \ + u32_encode_bits(le32_get_bits(value, dec_bits), enc_bits) + +#define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ + u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) + enum dp_monitor_mode { ATH12K_DP_TX_MONITOR_MODE, ATH12K_DP_RX_MONITOR_MODE @@ -114,9 +120,6 @@ 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_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 @@ -137,7 +140,4 @@ ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, 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 diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index f6d41ded5715..b924180007c5 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -13,6 +13,17 @@ #include "../dp_tx.h" #include "../peer.h" +static void +ath12k_wifi7_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, + u16 tlv_len, const void *tlv_data) +{ + if (tlv_len <= HAL_RX_MON_MAX_AGGR_SIZE - ppdu_info->tlv_aggr.cur_len) { + memcpy(ppdu_info->tlv_aggr.buf + ppdu_info->tlv_aggr.cur_len, + tlv_data, tlv_len); + ppdu_info->tlv_aggr.cur_len += tlv_len; + } +} + static void ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -432,6 +443,376 @@ ath12k_wifi7_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig ppdu_info->dcm = dcm; } +static inline bool +ath12k_wifi7_dp_mon_hal_rx_is_non_ofdma(const struct hal_rx_u_sig_info *usig_info) +{ + u32 ppdu_type_comp_mode = usig_info->ppdu_type_comp_mode; + u32 ul_dl = usig_info->ul_dl; + + if ((ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_MIMO && ul_dl == 0) || + (ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_OFDMA && ul_dl == 0) || + (ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_MIMO && ul_dl == 1)) + return true; + + return false; +} + +static inline bool +ath12k_wifi7_dp_mon_hal_rx_is_ofdma(const struct hal_rx_u_sig_info *usig_info) +{ + if (usig_info->ppdu_type_comp_mode == 0 && usig_info->ul_dl == 0) + return true; + + return false; +} + +static inline bool +ath12k_wifi7_dp_mon_hal_rx_is_frame_type_ndp(const struct hal_rx_u_sig_info *usig_info) +{ + if (usig_info->ppdu_type_comp_mode == 1 && + usig_info->eht_sig_mcs == 0 && + usig_info->num_eht_sig_sym == 0) + return true; + + return false; +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ndp(const struct hal_eht_sig_ndp_cmn_eb *eht_sig_ndp, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | + IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | + IEEE80211_RADIOTAP_EHT_KNOWN_NSS_S | + IEEE80211_RADIOTAP_EHT_KNOWN_BEAMFORMED_S | + IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_S | + IEEE80211_RADIOTAP_EHT_KNOWN_CRC1 | + IEEE80211_RADIOTAP_EHT_KNOWN_TAIL1; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[0]); + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_SPATIAL_REUSE, + IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); + /* GI and LTF size are separately indicated in radiotap header + * and hence will be parsed from other TLV + */ + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_NUM_LTF_SYM, + IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); + + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_CRC, + IEEE80211_RADIOTAP_EHT_DATA0_CRC1_O); + + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_DISREGARD, + IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_S); + eht->data[0] = cpu_to_le32(data); + + data = __le32_to_cpu(eht->data[7]); + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_NSS, + IEEE80211_RADIOTAP_EHT_DATA7_NSS_S); + + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_BEAMFORMED, + IEEE80211_RADIOTAP_EHT_DATA7_BEAMFORMED_S); + eht->data[7] = cpu_to_le32(data); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_usig_overflow(const struct hal_eht_sig_usig_overflow *ovflow, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | + IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | + IEEE80211_RADIOTAP_EHT_KNOWN_LDPC_EXTRA_SYM_OM | + IEEE80211_RADIOTAP_EHT_KNOWN_PRE_PADD_FACOR_OM | + IEEE80211_RADIOTAP_EHT_KNOWN_PE_DISAMBIGUITY_OM | + IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_O; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[0]); + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_SPATIAL_REUSE, + IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); + + /* GI and LTF size are separately indicated in radiotap header + * and hence will be parsed from other TLV + */ + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_NUM_LTF_SYM, + IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); + + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_LDPC_EXTA_SYM, + IEEE80211_RADIOTAP_EHT_DATA0_LDPC_EXTRA_SYM_OM); + + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_PRE_FEC_PAD_FACTOR, + IEEE80211_RADIOTAP_EHT_DATA0_PRE_PADD_FACOR_OM); + + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_DISAMBIGUITY, + IEEE80211_RADIOTAP_EHT_DATA0_PE_DISAMBIGUITY_OM); + + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_DISREGARD, + IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_O); + eht->data[0] = cpu_to_le32(data); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_non_ofdma_users(const struct hal_eht_sig_non_ofdma_cmn_eb *eb, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_NR_NON_OFDMA_USERS_M; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[7]); + data |= ATH12K_LE32_DEC_ENC(eb->info0, + HAL_RX_EHT_SIG_NON_OFDMA_INFO0_NUM_USERS, + IEEE80211_RADIOTAP_EHT_DATA7_NUM_OF_NON_OFDMA_USERS); + eht->data[7] = cpu_to_le32(data); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_mumimo_user(const struct hal_eht_sig_mu_mimo *user, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_eht_info *eht_info = &ppdu_info->eht_info; + u32 user_idx; + + if (eht_info->num_user_info >= ARRAY_SIZE(eht_info->user_info)) + return; + + user_idx = eht_info->num_user_info++; + + eht_info->user_info[user_idx] |= + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_KNOWN_M | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_STA_ID, + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_CODING, + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_MCS, + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_SPATIAL_CODING, + IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_M); + + ppdu_info->mcs = le32_get_bits(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_MCS); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_non_mumimo_user(const struct hal_eht_sig_non_mu_mimo *user, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_eht_info *eht_info = &ppdu_info->eht_info; + u32 user_idx; + + if (eht_info->num_user_info >= ARRAY_SIZE(eht_info->user_info)) + return; + + user_idx = eht_info->num_user_info++; + + eht_info->user_info[user_idx] |= + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O | + IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_KNOWN_O | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_STA_ID, + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_CODING, + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_MCS, + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_NSS, + IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_BEAMFORMED, + IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_O); + + ppdu_info->mcs = le32_get_bits(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_MCS); + + ppdu_info->nss = le32_get_bits(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_NSS) + 1; +} + +static inline bool +ath12k_wifi7_dp_mon_hal_rx_is_mu_mimo_user(const struct hal_rx_u_sig_info *usig_info) +{ + if (usig_info->ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_SU && + usig_info->ul_dl == 1) + return true; + + return false; +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_non_ofdma(const void *tlv, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + const struct hal_eht_sig_non_ofdma_cmn_eb *eb = tlv; + + ath12k_wifi7_dp_mon_hal_rx_parse_usig_overflow(tlv, ppdu_info); + ath12k_wifi7_dp_mon_hal_rx_parse_non_ofdma_users(eb, ppdu_info); + + if (ath12k_wifi7_dp_mon_hal_rx_is_mu_mimo_user(&ppdu_info->u_sig_info)) + ath12k_wifi7_dp_mon_hal_rx_parse_eht_mumimo_user(&eb->user_field.mu_mimo, + ppdu_info); + else + ath12k_wifi7_dp_mon_hal_rx_parse_eht_non_mumimo_user(&eb->user_field.n_mu_mimo, + ppdu_info); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_ru_allocation(const struct hal_eht_sig_ofdma_cmn_eb *eb, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + const struct hal_eht_sig_ofdma_cmn_eb1 *ofdma_cmn_eb1 = &eb->eb1; + const struct hal_eht_sig_ofdma_cmn_eb2 *ofdma_cmn_eb2 = &eb->eb2; + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + enum ieee80211_radiotap_eht_data ru_123, ru_124, ru_125, ru_126; + enum ieee80211_radiotap_eht_data ru_121, ru_122, ru_112, ru_111; + u32 data; + + ru_123 = IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3; + ru_124 = IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4; + ru_125 = IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5; + ru_126 = IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6; + ru_121 = IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1; + ru_122 = IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2; + ru_112 = IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2; + ru_111 = IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1; + + switch (ppdu_info->u_sig_info.bw) { + case HAL_EHT_BW_320_2: + case HAL_EHT_BW_320_1: + data = __le32_to_cpu(eht->data[4]); + /* CC1 2::3 */ + data |= IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_3, + ru_123); + eht->data[4] = cpu_to_le32(data); + + data = __le32_to_cpu(eht->data[5]); + /* CC1 2::4 */ + data |= IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_4, + ru_124); + + /* CC1 2::5 */ + data |= IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_5, + ru_125); + eht->data[5] = cpu_to_le32(data); + + data = __le32_to_cpu(eht->data[6]); + /* CC1 2::6 */ + data |= IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_6, + ru_126); + eht->data[6] = cpu_to_le32(data); + + fallthrough; + case HAL_EHT_BW_160: + data = __le32_to_cpu(eht->data[3]); + /* CC1 2::1 */ + data |= IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_1, + ru_121); + /* CC1 2::2 */ + data |= IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_2, + ru_122); + eht->data[3] = cpu_to_le32(data); + + fallthrough; + case HAL_EHT_BW_80: + data = __le32_to_cpu(eht->data[2]); + /* CC1 1::2 */ + data |= IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb1->info0, + HAL_RX_EHT_SIG_OFDMA_EB1_RU_ALLOC_1_2, + ru_112); + eht->data[2] = cpu_to_le32(data); + + fallthrough; + case HAL_EHT_BW_40: + fallthrough; + case HAL_EHT_BW_20: + data = __le32_to_cpu(eht->data[1]); + /* CC1 1::1 */ + data |= IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb1->info0, + HAL_RX_EHT_SIG_OFDMA_EB1_RU_ALLOC_1_1, + ru_111); + eht->data[1] = cpu_to_le32(data); + break; + default: + break; + } +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ofdma(const void *tlv, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + const struct hal_eht_sig_ofdma_cmn_eb *ofdma = tlv; + + ath12k_wifi7_dp_mon_hal_rx_parse_usig_overflow(tlv, ppdu_info); + ath12k_wifi7_dp_mon_hal_rx_parse_ru_allocation(ofdma, ppdu_info); + + ath12k_wifi7_dp_mon_hal_rx_parse_eht_non_mumimo_user(&ofdma->user_field.n_mu_mimo, + ppdu_info); +} + +static void +ath12k_wifi7_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, + const void *tlv_data) +{ + ppdu_info->is_eht = true; + + if (ath12k_wifi7_dp_mon_hal_rx_is_frame_type_ndp(&ppdu_info->u_sig_info)) + ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ndp(tlv_data, ppdu_info); + else if (ath12k_wifi7_dp_mon_hal_rx_is_non_ofdma(&ppdu_info->u_sig_info)) + ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_non_ofdma(tlv_data, ppdu_info); + else if (ath12k_wifi7_dp_mon_hal_rx_is_ofdma(&ppdu_info->u_sig_info)) + ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info); +} + 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, @@ -447,7 +828,8 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, 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); + ath12k_wifi7_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; @@ -691,7 +1073,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, ppdu_info->is_eht = true; - ath12k_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data); + ath12k_wifi7_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data); break; case HAL_DUMMY: return HAL_RX_MON_STATUS_BUF_DONE; -- 2.34.1 The ath12k common monitor path still contains Wi-Fi 7 specific SIG TLV parsing. Move these SIG TLV parsing to the Wi-Fi 7 module to improve modularity. Relocate the following functions into wifi7/dp_mon.c and rename them with the ath12k_wifi7_ prefix: - ath12k_dp_mon_parse_l_sig_b() - ath12k_dp_mon_parse_l_sig_a() - ath12k_dp_mon_hal_rx_parse_u_sig_cmn() - ath12k_dp_mon_hal_rx_parse_u_sig_tb() - ath12k_dp_mon_hal_rx_parse_u_sig_mu() - ath12k_dp_mon_hal_rx_parse_u_sig_hdr() Export the helper symbols needed by the Wi-Fi 7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh --- drivers/net/wireless/ath/ath12k/dp_mon.c | 265 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 7 - .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 274 +++++++++++++++++- 3 files changed, 269 insertions(+), 277 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 1ad984cd561e..9b04a9505ea0 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -75,271 +75,6 @@ ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats * } EXPORT_SYMBOL(ath12k_dp_mon_rx_populate_mu_user_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; - - rate = u32_get_bits(info0, HAL_RX_LSIG_B_INFO_INFO0_RATE); - switch (rate) { - case 1: - rate = HAL_RX_LEGACY_RATE_1_MBPS; - break; - case 2: - case 5: - rate = HAL_RX_LEGACY_RATE_2_MBPS; - break; - case 3: - case 6: - rate = HAL_RX_LEGACY_RATE_5_5_MBPS; - break; - case 4: - case 7: - rate = HAL_RX_LEGACY_RATE_11_MBPS; - break; - default: - rate = HAL_RX_LEGACY_RATE_INVALID; - } - - ppdu_info->rate = rate; - ppdu_info->cck_flag = 1; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_b); - -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; - - rate = u32_get_bits(info0, HAL_RX_LSIG_A_INFO_INFO0_RATE); - switch (rate) { - case 8: - rate = HAL_RX_LEGACY_RATE_48_MBPS; - break; - case 9: - rate = HAL_RX_LEGACY_RATE_24_MBPS; - break; - case 10: - rate = HAL_RX_LEGACY_RATE_12_MBPS; - break; - case 11: - rate = HAL_RX_LEGACY_RATE_6_MBPS; - break; - case 12: - rate = HAL_RX_LEGACY_RATE_54_MBPS; - break; - case 13: - rate = HAL_RX_LEGACY_RATE_36_MBPS; - break; - case 14: - rate = HAL_RX_LEGACY_RATE_18_MBPS; - break; - case 15: - rate = HAL_RX_LEGACY_RATE_9_MBPS; - break; - default: - rate = HAL_RX_LEGACY_RATE_INVALID; - } - - ppdu_info->rate = rate; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_a); - -static void -ath12k_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 common; - - ppdu_info->u_sig_info.bw = le32_get_bits(cmn->info0, - HAL_RX_USIG_CMN_INFO0_BW); - ppdu_info->u_sig_info.ul_dl = le32_get_bits(cmn->info0, - HAL_RX_USIG_CMN_INFO0_UL_DL); - - common = __le32_to_cpu(ppdu_info->u_sig_info.usig.common); - common |= IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER_KNOWN | - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN | - IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL_KNOWN | - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR_KNOWN | - IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN | - ATH12K_LE32_DEC_ENC(cmn->info0, - HAL_RX_USIG_CMN_INFO0_PHY_VERSION, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER) | - u32_encode_bits(ppdu_info->u_sig_info.bw, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW) | - u32_encode_bits(ppdu_info->u_sig_info.ul_dl, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL) | - ATH12K_LE32_DEC_ENC(cmn->info0, - HAL_RX_USIG_CMN_INFO0_BSS_COLOR, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR) | - ATH12K_LE32_DEC_ENC(cmn->info0, - HAL_RX_USIG_CMN_INFO0_TXOP, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP); - ppdu_info->u_sig_info.usig.common = cpu_to_le32(common); - - switch (ppdu_info->u_sig_info.bw) { - default: - fallthrough; - case HAL_EHT_BW_20: - ppdu_info->bw = HAL_RX_BW_20MHZ; - break; - case HAL_EHT_BW_40: - ppdu_info->bw = HAL_RX_BW_40MHZ; - break; - case HAL_EHT_BW_80: - ppdu_info->bw = HAL_RX_BW_80MHZ; - break; - case HAL_EHT_BW_160: - ppdu_info->bw = HAL_RX_BW_160MHZ; - break; - case HAL_EHT_BW_320_1: - case HAL_EHT_BW_320_2: - ppdu_info->bw = HAL_RX_BW_320MHZ; - break; - } -} - -static void -ath12k_dp_mon_hal_rx_parse_u_sig_tb(const struct hal_mon_usig_tb *usig_tb, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct ieee80211_radiotap_eht_usig *usig = &ppdu_info->u_sig_info.usig; - enum ieee80211_radiotap_eht_usig_tb spatial_reuse1, spatial_reuse2; - u32 common, value, mask; - - spatial_reuse1 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1; - spatial_reuse2 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2; - - common = __le32_to_cpu(usig->common); - value = __le32_to_cpu(usig->value); - mask = __le32_to_cpu(usig->mask); - - ppdu_info->u_sig_info.ppdu_type_comp_mode = - le32_get_bits(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_PPDU_TYPE_COMP_MODE); - - common |= ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_RX_INTEG_CHECK_PASS, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); - - value |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD | - u32_encode_bits(ppdu_info->u_sig_info.ppdu_type_comp_mode, - IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE) | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE | - ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_1, - spatial_reuse1) | - ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_2, - spatial_reuse2) | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD | - ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_CRC, - IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC) | - ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_TAIL, - IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL); - - mask |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE | - spatial_reuse1 | spatial_reuse2 | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL; - - usig->common = cpu_to_le32(common); - usig->value = cpu_to_le32(value); - usig->mask = cpu_to_le32(mask); -} - -static void -ath12k_dp_mon_hal_rx_parse_u_sig_mu(const struct hal_mon_usig_mu *usig_mu, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct ieee80211_radiotap_eht_usig *usig = &ppdu_info->u_sig_info.usig; - enum ieee80211_radiotap_eht_usig_mu sig_symb, punc; - u32 common, value, mask; - - sig_symb = IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS; - punc = IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO; - - common = __le32_to_cpu(usig->common); - value = __le32_to_cpu(usig->value); - mask = __le32_to_cpu(usig->mask); - - ppdu_info->u_sig_info.ppdu_type_comp_mode = - le32_get_bits(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE); - ppdu_info->u_sig_info.eht_sig_mcs = - le32_get_bits(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_EHT_SIG_MCS); - ppdu_info->u_sig_info.num_eht_sig_sym = - le32_get_bits(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_NUM_EHT_SIG_SYM); - - common |= ATH12K_LE32_DEC_ENC(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_RX_INTEG_CHECK_PASS, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); - - value |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD | - IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE | - u32_encode_bits(ppdu_info->u_sig_info.ppdu_type_comp_mode, - IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE) | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE | - ATH12K_LE32_DEC_ENC(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_PUNC_CH_INFO, - punc) | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE | - u32_encode_bits(ppdu_info->u_sig_info.eht_sig_mcs, - IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS) | - u32_encode_bits(ppdu_info->u_sig_info.num_eht_sig_sym, - sig_symb) | - ATH12K_LE32_DEC_ENC(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_CRC, - IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC) | - ATH12K_LE32_DEC_ENC(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_TAIL, - IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL); - - mask |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD | - IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE | - punc | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS | - sig_symb | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL; - - usig->common = cpu_to_le32(common); - usig->value = cpu_to_le32(value); - usig->mask = cpu_to_le32(mask); -} - -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) -{ - u8 comp_mode; - - ppdu_info->eht_usig = true; - - ath12k_dp_mon_hal_rx_parse_u_sig_cmn(&usig->cmn, ppdu_info); - - comp_mode = le32_get_bits(usig->non_cmn.mu.info0, - HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE); - - if (comp_mode == 0 && ppdu_info->u_sig_info.ul_dl) - ath12k_dp_mon_hal_rx_parse_u_sig_tb(&usig->non_cmn.tb, 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 inline enum ath12k_eht_ru_size hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) { diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index d2bee88f561f..063d57512db7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -126,10 +126,6 @@ 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_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, u16 user_id, @@ -137,7 +133,4 @@ ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_ 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); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index b924180007c5..2d67fd553776 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -31,6 +31,270 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static void +ath12k_wifi7_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; + + rate = u32_get_bits(info0, HAL_RX_LSIG_B_INFO_INFO0_RATE); + switch (rate) { + case 1: + rate = HAL_RX_LEGACY_RATE_1_MBPS; + break; + case 2: + case 5: + rate = HAL_RX_LEGACY_RATE_2_MBPS; + break; + case 3: + case 6: + rate = HAL_RX_LEGACY_RATE_5_5_MBPS; + break; + case 4: + case 7: + rate = HAL_RX_LEGACY_RATE_11_MBPS; + break; + default: + rate = HAL_RX_LEGACY_RATE_INVALID; + } + + ppdu_info->rate = rate; + ppdu_info->cck_flag = 1; +} + +static void +ath12k_wifi7_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; + + rate = u32_get_bits(info0, HAL_RX_LSIG_A_INFO_INFO0_RATE); + switch (rate) { + case 8: + rate = HAL_RX_LEGACY_RATE_48_MBPS; + break; + case 9: + rate = HAL_RX_LEGACY_RATE_24_MBPS; + break; + case 10: + rate = HAL_RX_LEGACY_RATE_12_MBPS; + break; + case 11: + rate = HAL_RX_LEGACY_RATE_6_MBPS; + break; + case 12: + rate = HAL_RX_LEGACY_RATE_54_MBPS; + break; + case 13: + rate = HAL_RX_LEGACY_RATE_36_MBPS; + break; + case 14: + rate = HAL_RX_LEGACY_RATE_18_MBPS; + break; + case 15: + rate = HAL_RX_LEGACY_RATE_9_MBPS; + break; + default: + rate = HAL_RX_LEGACY_RATE_INVALID; + } + + ppdu_info->rate = rate; +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 common; + + ppdu_info->u_sig_info.bw = le32_get_bits(cmn->info0, + HAL_RX_USIG_CMN_INFO0_BW); + ppdu_info->u_sig_info.ul_dl = le32_get_bits(cmn->info0, + HAL_RX_USIG_CMN_INFO0_UL_DL); + + common = __le32_to_cpu(ppdu_info->u_sig_info.usig.common); + common |= IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER_KNOWN | + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN | + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL_KNOWN | + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR_KNOWN | + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN | + ATH12K_LE32_DEC_ENC(cmn->info0, + HAL_RX_USIG_CMN_INFO0_PHY_VERSION, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER) | + u32_encode_bits(ppdu_info->u_sig_info.bw, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW) | + u32_encode_bits(ppdu_info->u_sig_info.ul_dl, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL) | + ATH12K_LE32_DEC_ENC(cmn->info0, + HAL_RX_USIG_CMN_INFO0_BSS_COLOR, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR) | + ATH12K_LE32_DEC_ENC(cmn->info0, + HAL_RX_USIG_CMN_INFO0_TXOP, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP); + ppdu_info->u_sig_info.usig.common = cpu_to_le32(common); + + switch (ppdu_info->u_sig_info.bw) { + default: + fallthrough; + case HAL_EHT_BW_20: + ppdu_info->bw = HAL_RX_BW_20MHZ; + break; + case HAL_EHT_BW_40: + ppdu_info->bw = HAL_RX_BW_40MHZ; + break; + case HAL_EHT_BW_80: + ppdu_info->bw = HAL_RX_BW_80MHZ; + break; + case HAL_EHT_BW_160: + ppdu_info->bw = HAL_RX_BW_160MHZ; + break; + case HAL_EHT_BW_320_1: + case HAL_EHT_BW_320_2: + ppdu_info->bw = HAL_RX_BW_320MHZ; + break; + } +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_tb(const struct hal_mon_usig_tb *usig_tb, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct ieee80211_radiotap_eht_usig *usig = &ppdu_info->u_sig_info.usig; + enum ieee80211_radiotap_eht_usig_tb spatial_reuse1, spatial_reuse2; + u32 common, value, mask; + + spatial_reuse1 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1; + spatial_reuse2 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2; + + common = __le32_to_cpu(usig->common); + value = __le32_to_cpu(usig->value); + mask = __le32_to_cpu(usig->mask); + + ppdu_info->u_sig_info.ppdu_type_comp_mode = + le32_get_bits(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_PPDU_TYPE_COMP_MODE); + + common |= ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_RX_INTEG_CHECK_PASS, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); + + value |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD | + u32_encode_bits(ppdu_info->u_sig_info.ppdu_type_comp_mode, + IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE) | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE | + ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_1, + spatial_reuse1) | + ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_2, + spatial_reuse2) | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD | + ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_CRC, + IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC) | + ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_TAIL, + IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL); + + mask |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE | + spatial_reuse1 | spatial_reuse2 | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL; + + usig->common = cpu_to_le32(common); + usig->value = cpu_to_le32(value); + usig->mask = cpu_to_le32(mask); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_mu(const struct hal_mon_usig_mu *usig_mu, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct ieee80211_radiotap_eht_usig *usig = &ppdu_info->u_sig_info.usig; + enum ieee80211_radiotap_eht_usig_mu sig_symb, punc; + u32 common, value, mask; + + sig_symb = IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS; + punc = IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO; + + common = __le32_to_cpu(usig->common); + value = __le32_to_cpu(usig->value); + mask = __le32_to_cpu(usig->mask); + + ppdu_info->u_sig_info.ppdu_type_comp_mode = + le32_get_bits(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE); + ppdu_info->u_sig_info.eht_sig_mcs = + le32_get_bits(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_EHT_SIG_MCS); + ppdu_info->u_sig_info.num_eht_sig_sym = + le32_get_bits(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_NUM_EHT_SIG_SYM); + + common |= ATH12K_LE32_DEC_ENC(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_RX_INTEG_CHECK_PASS, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); + + value |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD | + IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE | + u32_encode_bits(ppdu_info->u_sig_info.ppdu_type_comp_mode, + IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE) | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE | + ATH12K_LE32_DEC_ENC(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_PUNC_CH_INFO, + punc) | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE | + u32_encode_bits(ppdu_info->u_sig_info.eht_sig_mcs, + IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS) | + u32_encode_bits(ppdu_info->u_sig_info.num_eht_sig_sym, + sig_symb) | + ATH12K_LE32_DEC_ENC(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_CRC, + IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC) | + ATH12K_LE32_DEC_ENC(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_TAIL, + IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL); + + mask |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD | + IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE | + punc | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS | + sig_symb | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL; + + usig->common = cpu_to_le32(common); + usig->value = cpu_to_le32(value); + usig->mask = cpu_to_le32(mask); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u8 comp_mode; + + ppdu_info->eht_usig = true; + + ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_cmn(&usig->cmn, ppdu_info); + + comp_mode = le32_get_bits(usig->non_cmn.mu.info0, + HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE); + + if (comp_mode == 0 && ppdu_info->u_sig_info.ul_dl) + ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_tb(&usig->non_cmn.tb, ppdu_info); + else + ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_mu(&usig->non_cmn.mu, ppdu_info); +} + static void ath12k_wifi7_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, struct hal_rx_mon_ppdu_info *ppdu_info) @@ -956,11 +1220,11 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; case HAL_PHYRX_L_SIG_B: - ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info); + ath12k_wifi7_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); + ath12k_wifi7_dp_mon_parse_l_sig_a(tlv_data, ppdu_info); break; case HAL_PHYRX_VHT_SIG_A: @@ -1058,7 +1322,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, 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); + ath12k_wifi7_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 @@ -1621,11 +1885,11 @@ ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, break; case HAL_MACTX_L_SIG_A: - ath12k_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status); break; case HAL_MACTX_L_SIG_B: - ath12k_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status); break; case HAL_RX_FRAME_BITMAP_ACK: { -- 2.34.1 Move Wi-Fi 7-specific monitor functionality out of ath12k common code into the Wi-Fi 7 module to improve modularity. Move and rename the following MU user processing functions to wifi7/dp_mon.c with the ath12k_wifi7_ prefix: - ath12k_dp_mon_rx_handle_ofdma_info() - ath12k_dp_mon_rx_populate_mu_user_info() - ath12k_dp_mon_hal_rx_parse_user_info() Move the helper functions hal_rx_mon_hal_ru_size_to_ath12k_ru_size and hal_rx_ul_ofdma_ru_size_to_width to the Wi-Fi 7 module, and export the helpers required by the ath12k_wifi7 code. Isolate the parsing of MU-specific user information within the Wi-Fi 7 module to keep common code generic. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh --- drivers/net/wireless/ath/ath12k/dp_mon.c | 351 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 11 - .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 356 +++++++++++++++++- 3 files changed, 352 insertions(+), 366 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 9b04a9505ea0..db67d81d557f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -11,357 +11,6 @@ #include "dp_tx.h" #include "peer.h" -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_word0 = - __le32_to_cpu(ppdu_end_user->usr_resp_ref); - 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, - void *ppduinfo, - struct hal_rx_user_status *rx_user_status) -{ - rx_user_status->mpdu_ok_byte_count = - le32_get_bits(stats->info7, - HAL_RX_PPDU_END_USER_STATS_INFO7_MPDU_OK_BYTE_COUNT); - rx_user_status->mpdu_err_byte_count = - le32_get_bits(stats->info8, - HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_ERR_BYTE_COUNT); -} - -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) -{ - rx_user_status->ast_index = ppdu_info->ast_index; - rx_user_status->tid = ppdu_info->tid; - rx_user_status->tcp_ack_msdu_count = - ppdu_info->tcp_ack_msdu_count; - rx_user_status->tcp_msdu_count = - ppdu_info->tcp_msdu_count; - rx_user_status->udp_msdu_count = - ppdu_info->udp_msdu_count; - rx_user_status->other_msdu_count = - ppdu_info->other_msdu_count; - rx_user_status->frame_control = ppdu_info->frame_control; - rx_user_status->frame_control_info_valid = - ppdu_info->frame_control_info_valid; - rx_user_status->data_sequence_control_info_valid = - ppdu_info->data_sequence_control_info_valid; - rx_user_status->first_data_seq_ctrl = - ppdu_info->first_data_seq_ctrl; - rx_user_status->preamble_type = ppdu_info->preamble_type; - rx_user_status->ht_flags = ppdu_info->ht_flags; - rx_user_status->vht_flags = ppdu_info->vht_flags; - rx_user_status->he_flags = ppdu_info->he_flags; - rx_user_status->rs_flags = ppdu_info->rs_flags; - - rx_user_status->mpdu_cnt_fcs_ok = - ppdu_info->num_mpdu_fcs_ok; - rx_user_status->mpdu_cnt_fcs_err = - ppdu_info->num_mpdu_fcs_err; - memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0], - HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * - sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); - - 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 inline enum ath12k_eht_ru_size -hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) -{ - switch (hal_ru_size) { - case HAL_EHT_RU_26: - return ATH12K_EHT_RU_26; - case HAL_EHT_RU_52: - return ATH12K_EHT_RU_52; - case HAL_EHT_RU_78: - return ATH12K_EHT_RU_52_26; - case HAL_EHT_RU_106: - return ATH12K_EHT_RU_106; - case HAL_EHT_RU_132: - return ATH12K_EHT_RU_106_26; - case HAL_EHT_RU_242: - return ATH12K_EHT_RU_242; - case HAL_EHT_RU_484: - return ATH12K_EHT_RU_484; - case HAL_EHT_RU_726: - return ATH12K_EHT_RU_484_242; - case HAL_EHT_RU_996: - return ATH12K_EHT_RU_996; - case HAL_EHT_RU_996x2: - return ATH12K_EHT_RU_996x2; - case HAL_EHT_RU_996x3: - return ATH12K_EHT_RU_996x3; - case HAL_EHT_RU_996x4: - return ATH12K_EHT_RU_996x4; - case HAL_EHT_RU_NONE: - return ATH12K_EHT_RU_INVALID; - case HAL_EHT_RU_996_484: - return ATH12K_EHT_RU_996_484; - case HAL_EHT_RU_996x2_484: - return ATH12K_EHT_RU_996x2_484; - case HAL_EHT_RU_996x3_484: - return ATH12K_EHT_RU_996x3_484; - case HAL_EHT_RU_996_484_242: - return ATH12K_EHT_RU_996_484_242; - default: - return ATH12K_EHT_RU_INVALID; - } -} - -static inline u32 -hal_rx_ul_ofdma_ru_size_to_width(enum ath12k_eht_ru_size ru_size) -{ - switch (ru_size) { - case ATH12K_EHT_RU_26: - return RU_26; - case ATH12K_EHT_RU_52: - return RU_52; - case ATH12K_EHT_RU_52_26: - return RU_52_26; - case ATH12K_EHT_RU_106: - return RU_106; - case ATH12K_EHT_RU_106_26: - return RU_106_26; - case ATH12K_EHT_RU_242: - return RU_242; - case ATH12K_EHT_RU_484: - return RU_484; - case ATH12K_EHT_RU_484_242: - return RU_484_242; - case ATH12K_EHT_RU_996: - return RU_996; - case ATH12K_EHT_RU_996_484: - return RU_996_484; - case ATH12K_EHT_RU_996_484_242: - return RU_996_484_242; - case ATH12K_EHT_RU_996x2: - return RU_2X996; - case ATH12K_EHT_RU_996x2_484: - return RU_2X996_484; - case ATH12K_EHT_RU_996x3: - return RU_3X996; - case ATH12K_EHT_RU_996x3_484: - return RU_3X996_484; - case ATH12K_EHT_RU_996x4: - return RU_4X996; - default: - return RU_INVALID; - } -} - -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) -{ - struct hal_rx_user_status *mon_rx_user_status = NULL; - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - enum ath12k_eht_ru_size rtap_ru_size = ATH12K_EHT_RU_INVALID; - u32 ru_width, reception_type, ru_index = HAL_EHT_RU_INVALID; - u32 ru_type_80_0, ru_start_index_80_0; - u32 ru_type_80_1, ru_start_index_80_1; - u32 ru_type_80_2, ru_start_index_80_2; - u32 ru_type_80_3, ru_start_index_80_3; - u32 ru_size = 0, num_80mhz_with_ru = 0; - u64 ru_index_320mhz = 0; - u32 ru_index_per80mhz; - - reception_type = le32_get_bits(rx_usr_info->info0, - HAL_RX_USR_INFO0_RECEPTION_TYPE); - - switch (reception_type) { - case HAL_RECEPTION_TYPE_SU: - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; - break; - case HAL_RECEPTION_TYPE_DL_MU_MIMO: - case HAL_RECEPTION_TYPE_UL_MU_MIMO: - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; - break; - case HAL_RECEPTION_TYPE_DL_MU_OFMA: - case HAL_RECEPTION_TYPE_UL_MU_OFDMA: - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; - break; - case HAL_RECEPTION_TYPE_DL_MU_OFDMA_MIMO: - case HAL_RECEPTION_TYPE_UL_MU_OFDMA_MIMO: - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO; - } - - ppdu_info->is_stbc = le32_get_bits(rx_usr_info->info0, HAL_RX_USR_INFO0_STBC); - ppdu_info->ldpc = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_LDPC); - ppdu_info->dcm = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_STA_DCM); - ppdu_info->bw = le32_get_bits(rx_usr_info->info1, HAL_RX_USR_INFO1_RX_BW); - ppdu_info->mcs = le32_get_bits(rx_usr_info->info1, HAL_RX_USR_INFO1_MCS); - ppdu_info->nss = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_NSS) + 1; - - if (user_id < HAL_MAX_UL_MU_USERS) { - mon_rx_user_status = &ppdu_info->userstats[user_id]; - mon_rx_user_status->mcs = ppdu_info->mcs; - mon_rx_user_status->nss = ppdu_info->nss; - } - - if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_MIMO || - ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || - ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)) - return; - - /* RU allocation present only for OFDMA reception */ - ru_type_80_0 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_0); - ru_start_index_80_0 = le32_get_bits(rx_usr_info->info3, - HAL_RX_USR_INFO3_RU_START_IDX_80_0); - if (ru_type_80_0 != HAL_EHT_RU_NONE) { - ru_size += ru_type_80_0; - ru_index_per80mhz = ru_start_index_80_0; - ru_index = ru_index_per80mhz; - ru_index_320mhz |= HAL_RU_PER80(ru_type_80_0, 0, ru_index_per80mhz); - num_80mhz_with_ru++; - } - - ru_type_80_1 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_1); - ru_start_index_80_1 = le32_get_bits(rx_usr_info->info3, - HAL_RX_USR_INFO3_RU_START_IDX_80_1); - if (ru_type_80_1 != HAL_EHT_RU_NONE) { - ru_size += ru_type_80_1; - ru_index_per80mhz = ru_start_index_80_1; - ru_index = ru_index_per80mhz; - ru_index_320mhz |= HAL_RU_PER80(ru_type_80_1, 1, ru_index_per80mhz); - num_80mhz_with_ru++; - } - - ru_type_80_2 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_2); - ru_start_index_80_2 = le32_get_bits(rx_usr_info->info3, - HAL_RX_USR_INFO3_RU_START_IDX_80_2); - if (ru_type_80_2 != HAL_EHT_RU_NONE) { - ru_size += ru_type_80_2; - ru_index_per80mhz = ru_start_index_80_2; - ru_index = ru_index_per80mhz; - ru_index_320mhz |= HAL_RU_PER80(ru_type_80_2, 2, ru_index_per80mhz); - num_80mhz_with_ru++; - } - - ru_type_80_3 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_3); - ru_start_index_80_3 = le32_get_bits(rx_usr_info->info2, - HAL_RX_USR_INFO3_RU_START_IDX_80_3); - if (ru_type_80_3 != HAL_EHT_RU_NONE) { - ru_size += ru_type_80_3; - ru_index_per80mhz = ru_start_index_80_3; - ru_index = ru_index_per80mhz; - ru_index_320mhz |= HAL_RU_PER80(ru_type_80_3, 3, ru_index_per80mhz); - num_80mhz_with_ru++; - } - - if (num_80mhz_with_ru > 1) { - /* Calculate the MRU index */ - switch (ru_index_320mhz) { - case HAL_EHT_RU_996_484_0: - case HAL_EHT_RU_996x2_484_0: - case HAL_EHT_RU_996x3_484_0: - ru_index = 0; - break; - case HAL_EHT_RU_996_484_1: - case HAL_EHT_RU_996x2_484_1: - case HAL_EHT_RU_996x3_484_1: - ru_index = 1; - break; - case HAL_EHT_RU_996_484_2: - case HAL_EHT_RU_996x2_484_2: - case HAL_EHT_RU_996x3_484_2: - ru_index = 2; - break; - case HAL_EHT_RU_996_484_3: - case HAL_EHT_RU_996x2_484_3: - case HAL_EHT_RU_996x3_484_3: - ru_index = 3; - break; - case HAL_EHT_RU_996_484_4: - case HAL_EHT_RU_996x2_484_4: - case HAL_EHT_RU_996x3_484_4: - ru_index = 4; - break; - case HAL_EHT_RU_996_484_5: - case HAL_EHT_RU_996x2_484_5: - case HAL_EHT_RU_996x3_484_5: - ru_index = 5; - break; - case HAL_EHT_RU_996_484_6: - case HAL_EHT_RU_996x2_484_6: - case HAL_EHT_RU_996x3_484_6: - ru_index = 6; - break; - case HAL_EHT_RU_996_484_7: - case HAL_EHT_RU_996x2_484_7: - case HAL_EHT_RU_996x3_484_7: - ru_index = 7; - break; - case HAL_EHT_RU_996x2_484_8: - ru_index = 8; - break; - case HAL_EHT_RU_996x2_484_9: - ru_index = 9; - break; - case HAL_EHT_RU_996x2_484_10: - ru_index = 10; - break; - case HAL_EHT_RU_996x2_484_11: - ru_index = 11; - break; - default: - ru_index = HAL_EHT_RU_INVALID; - break; - } - - ru_size += 4; - } - - rtap_ru_size = hal_rx_mon_hal_ru_size_to_ath12k_ru_size(ru_size); - if (rtap_ru_size != ATH12K_EHT_RU_INVALID) { - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_SIZE_OM; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[1]); - data |= u32_encode_bits(rtap_ru_size, - IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE); - eht->data[1] = cpu_to_le32(data); - } - - if (ru_index != HAL_EHT_RU_INVALID) { - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_INDEX_OM; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[1]); - data |= u32_encode_bits(rtap_ru_size, - IEEE80211_RADIOTAP_EHT_DATA1_RU_INDEX); - eht->data[1] = cpu_to_le32(data); - } - - if (mon_rx_user_status && ru_index != HAL_EHT_RU_INVALID && - rtap_ru_size != ATH12K_EHT_RU_INVALID) { - mon_rx_user_status->ul_ofdma_ru_start_index = ru_index; - mon_rx_user_status->ul_ofdma_ru_size = rtap_ru_size; - - ru_width = hal_rx_ul_ofdma_ru_size_to_width(rtap_ru_size); - - mon_rx_user_status->ul_ofdma_ru_width = ru_width; - 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) { if (info & RX_MSDU_END_INFO13_FCS_ERR) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 063d57512db7..6dac4e9569b6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -120,17 +120,6 @@ 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_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_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); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 2d67fd553776..8d913d09f882 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -31,6 +31,354 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static void +ath12k_wifi7_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_word0 = + __le32_to_cpu(ppdu_end_user->usr_resp_ref); + rx_user_status->ul_ofdma_user_v0_word1 = + __le32_to_cpu(ppdu_end_user->usr_resp_ref_ext); +} + +static void +ath12k_wifi7_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats, + void *ppduinfo, + struct hal_rx_user_status *rx_user_status) +{ + rx_user_status->mpdu_ok_byte_count = + le32_get_bits(stats->info7, + HAL_RX_PPDU_END_USER_STATS_INFO7_MPDU_OK_BYTE_COUNT); + rx_user_status->mpdu_err_byte_count = + le32_get_bits(stats->info8, + HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_ERR_BYTE_COUNT); +} + +static void +ath12k_wifi7_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) +{ + rx_user_status->ast_index = ppdu_info->ast_index; + rx_user_status->tid = ppdu_info->tid; + rx_user_status->tcp_ack_msdu_count = + ppdu_info->tcp_ack_msdu_count; + rx_user_status->tcp_msdu_count = + ppdu_info->tcp_msdu_count; + rx_user_status->udp_msdu_count = + ppdu_info->udp_msdu_count; + rx_user_status->other_msdu_count = + ppdu_info->other_msdu_count; + rx_user_status->frame_control = ppdu_info->frame_control; + rx_user_status->frame_control_info_valid = + ppdu_info->frame_control_info_valid; + rx_user_status->data_sequence_control_info_valid = + ppdu_info->data_sequence_control_info_valid; + rx_user_status->first_data_seq_ctrl = + ppdu_info->first_data_seq_ctrl; + rx_user_status->preamble_type = ppdu_info->preamble_type; + rx_user_status->ht_flags = ppdu_info->ht_flags; + rx_user_status->vht_flags = ppdu_info->vht_flags; + rx_user_status->he_flags = ppdu_info->he_flags; + rx_user_status->rs_flags = ppdu_info->rs_flags; + + rx_user_status->mpdu_cnt_fcs_ok = + ppdu_info->num_mpdu_fcs_ok; + rx_user_status->mpdu_cnt_fcs_err = + ppdu_info->num_mpdu_fcs_err; + memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0], + HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * + sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); + + ath12k_wifi7_dp_mon_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); +} + +static inline enum ath12k_eht_ru_size +hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) +{ + switch (hal_ru_size) { + case HAL_EHT_RU_26: + return ATH12K_EHT_RU_26; + case HAL_EHT_RU_52: + return ATH12K_EHT_RU_52; + case HAL_EHT_RU_78: + return ATH12K_EHT_RU_52_26; + case HAL_EHT_RU_106: + return ATH12K_EHT_RU_106; + case HAL_EHT_RU_132: + return ATH12K_EHT_RU_106_26; + case HAL_EHT_RU_242: + return ATH12K_EHT_RU_242; + case HAL_EHT_RU_484: + return ATH12K_EHT_RU_484; + case HAL_EHT_RU_726: + return ATH12K_EHT_RU_484_242; + case HAL_EHT_RU_996: + return ATH12K_EHT_RU_996; + case HAL_EHT_RU_996x2: + return ATH12K_EHT_RU_996x2; + case HAL_EHT_RU_996x3: + return ATH12K_EHT_RU_996x3; + case HAL_EHT_RU_996x4: + return ATH12K_EHT_RU_996x4; + case HAL_EHT_RU_NONE: + return ATH12K_EHT_RU_INVALID; + case HAL_EHT_RU_996_484: + return ATH12K_EHT_RU_996_484; + case HAL_EHT_RU_996x2_484: + return ATH12K_EHT_RU_996x2_484; + case HAL_EHT_RU_996x3_484: + return ATH12K_EHT_RU_996x3_484; + case HAL_EHT_RU_996_484_242: + return ATH12K_EHT_RU_996_484_242; + default: + return ATH12K_EHT_RU_INVALID; + } +} + +static inline u32 +hal_rx_ul_ofdma_ru_size_to_width(enum ath12k_eht_ru_size ru_size) +{ + switch (ru_size) { + case ATH12K_EHT_RU_26: + return RU_26; + case ATH12K_EHT_RU_52: + return RU_52; + case ATH12K_EHT_RU_52_26: + return RU_52_26; + case ATH12K_EHT_RU_106: + return RU_106; + case ATH12K_EHT_RU_106_26: + return RU_106_26; + case ATH12K_EHT_RU_242: + return RU_242; + case ATH12K_EHT_RU_484: + return RU_484; + case ATH12K_EHT_RU_484_242: + return RU_484_242; + case ATH12K_EHT_RU_996: + return RU_996; + case ATH12K_EHT_RU_996_484: + return RU_996_484; + case ATH12K_EHT_RU_996_484_242: + return RU_996_484_242; + case ATH12K_EHT_RU_996x2: + return RU_2X996; + case ATH12K_EHT_RU_996x2_484: + return RU_2X996_484; + case ATH12K_EHT_RU_996x3: + return RU_3X996; + case ATH12K_EHT_RU_996x3_484: + return RU_3X996_484; + case ATH12K_EHT_RU_996x4: + return RU_4X996; + default: + return RU_INVALID; + } +} + +static void +ath12k_wifi7_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) +{ + struct hal_rx_user_status *mon_rx_user_status = NULL; + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + enum ath12k_eht_ru_size rtap_ru_size = ATH12K_EHT_RU_INVALID; + u32 ru_width, reception_type, ru_index = HAL_EHT_RU_INVALID; + u32 ru_type_80_0, ru_start_index_80_0; + u32 ru_type_80_1, ru_start_index_80_1; + u32 ru_type_80_2, ru_start_index_80_2; + u32 ru_type_80_3, ru_start_index_80_3; + u32 ru_size = 0, num_80mhz_with_ru = 0; + u64 ru_index_320mhz = 0; + u32 ru_index_per80mhz; + + reception_type = le32_get_bits(rx_usr_info->info0, + HAL_RX_USR_INFO0_RECEPTION_TYPE); + + switch (reception_type) { + case HAL_RECEPTION_TYPE_SU: + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + case HAL_RECEPTION_TYPE_DL_MU_MIMO: + case HAL_RECEPTION_TYPE_UL_MU_MIMO: + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; + break; + case HAL_RECEPTION_TYPE_DL_MU_OFMA: + case HAL_RECEPTION_TYPE_UL_MU_OFDMA: + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; + break; + case HAL_RECEPTION_TYPE_DL_MU_OFDMA_MIMO: + case HAL_RECEPTION_TYPE_UL_MU_OFDMA_MIMO: + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO; + } + + ppdu_info->is_stbc = le32_get_bits(rx_usr_info->info0, HAL_RX_USR_INFO0_STBC); + ppdu_info->ldpc = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_LDPC); + ppdu_info->dcm = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_STA_DCM); + ppdu_info->bw = le32_get_bits(rx_usr_info->info1, HAL_RX_USR_INFO1_RX_BW); + ppdu_info->mcs = le32_get_bits(rx_usr_info->info1, HAL_RX_USR_INFO1_MCS); + ppdu_info->nss = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_NSS) + 1; + + if (user_id < HAL_MAX_UL_MU_USERS) { + mon_rx_user_status = &ppdu_info->userstats[user_id]; + mon_rx_user_status->mcs = ppdu_info->mcs; + mon_rx_user_status->nss = ppdu_info->nss; + } + + if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_MIMO || + ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || + ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)) + return; + + /* RU allocation present only for OFDMA reception */ + ru_type_80_0 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_0); + ru_start_index_80_0 = le32_get_bits(rx_usr_info->info3, + HAL_RX_USR_INFO3_RU_START_IDX_80_0); + if (ru_type_80_0 != HAL_EHT_RU_NONE) { + ru_size += ru_type_80_0; + ru_index_per80mhz = ru_start_index_80_0; + ru_index = ru_index_per80mhz; + ru_index_320mhz |= HAL_RU_PER80(ru_type_80_0, 0, ru_index_per80mhz); + num_80mhz_with_ru++; + } + + ru_type_80_1 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_1); + ru_start_index_80_1 = le32_get_bits(rx_usr_info->info3, + HAL_RX_USR_INFO3_RU_START_IDX_80_1); + if (ru_type_80_1 != HAL_EHT_RU_NONE) { + ru_size += ru_type_80_1; + ru_index_per80mhz = ru_start_index_80_1; + ru_index = ru_index_per80mhz; + ru_index_320mhz |= HAL_RU_PER80(ru_type_80_1, 1, ru_index_per80mhz); + num_80mhz_with_ru++; + } + + ru_type_80_2 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_2); + ru_start_index_80_2 = le32_get_bits(rx_usr_info->info3, + HAL_RX_USR_INFO3_RU_START_IDX_80_2); + if (ru_type_80_2 != HAL_EHT_RU_NONE) { + ru_size += ru_type_80_2; + ru_index_per80mhz = ru_start_index_80_2; + ru_index = ru_index_per80mhz; + ru_index_320mhz |= HAL_RU_PER80(ru_type_80_2, 2, ru_index_per80mhz); + num_80mhz_with_ru++; + } + + ru_type_80_3 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_3); + ru_start_index_80_3 = le32_get_bits(rx_usr_info->info2, + HAL_RX_USR_INFO3_RU_START_IDX_80_3); + if (ru_type_80_3 != HAL_EHT_RU_NONE) { + ru_size += ru_type_80_3; + ru_index_per80mhz = ru_start_index_80_3; + ru_index = ru_index_per80mhz; + ru_index_320mhz |= HAL_RU_PER80(ru_type_80_3, 3, ru_index_per80mhz); + num_80mhz_with_ru++; + } + + if (num_80mhz_with_ru > 1) { + /* Calculate the MRU index */ + switch (ru_index_320mhz) { + case HAL_EHT_RU_996_484_0: + case HAL_EHT_RU_996x2_484_0: + case HAL_EHT_RU_996x3_484_0: + ru_index = 0; + break; + case HAL_EHT_RU_996_484_1: + case HAL_EHT_RU_996x2_484_1: + case HAL_EHT_RU_996x3_484_1: + ru_index = 1; + break; + case HAL_EHT_RU_996_484_2: + case HAL_EHT_RU_996x2_484_2: + case HAL_EHT_RU_996x3_484_2: + ru_index = 2; + break; + case HAL_EHT_RU_996_484_3: + case HAL_EHT_RU_996x2_484_3: + case HAL_EHT_RU_996x3_484_3: + ru_index = 3; + break; + case HAL_EHT_RU_996_484_4: + case HAL_EHT_RU_996x2_484_4: + case HAL_EHT_RU_996x3_484_4: + ru_index = 4; + break; + case HAL_EHT_RU_996_484_5: + case HAL_EHT_RU_996x2_484_5: + case HAL_EHT_RU_996x3_484_5: + ru_index = 5; + break; + case HAL_EHT_RU_996_484_6: + case HAL_EHT_RU_996x2_484_6: + case HAL_EHT_RU_996x3_484_6: + ru_index = 6; + break; + case HAL_EHT_RU_996_484_7: + case HAL_EHT_RU_996x2_484_7: + case HAL_EHT_RU_996x3_484_7: + ru_index = 7; + break; + case HAL_EHT_RU_996x2_484_8: + ru_index = 8; + break; + case HAL_EHT_RU_996x2_484_9: + ru_index = 9; + break; + case HAL_EHT_RU_996x2_484_10: + ru_index = 10; + break; + case HAL_EHT_RU_996x2_484_11: + ru_index = 11; + break; + default: + ru_index = HAL_EHT_RU_INVALID; + break; + } + + ru_size += 4; + } + + rtap_ru_size = hal_rx_mon_hal_ru_size_to_ath12k_ru_size(ru_size); + if (rtap_ru_size != ATH12K_EHT_RU_INVALID) { + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_SIZE_OM; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[1]); + data |= u32_encode_bits(rtap_ru_size, + IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE); + eht->data[1] = cpu_to_le32(data); + } + + if (ru_index != HAL_EHT_RU_INVALID) { + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_INDEX_OM; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[1]); + data |= u32_encode_bits(rtap_ru_size, + IEEE80211_RADIOTAP_EHT_DATA1_RU_INDEX); + eht->data[1] = cpu_to_le32(data); + } + + if (mon_rx_user_status && ru_index != HAL_EHT_RU_INVALID && + rtap_ru_size != ATH12K_EHT_RU_INVALID) { + mon_rx_user_status->ul_ofdma_ru_start_index = ru_index; + mon_rx_user_status->ul_ofdma_ru_size = rtap_ru_size; + + ru_width = hal_rx_ul_ofdma_ru_size_to_width(rtap_ru_size); + + mon_rx_user_status->ul_ofdma_ru_width = ru_width; + mon_rx_user_status->ofdma_info_valid = 1; + } +} + static void ath12k_wifi7_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, struct hal_rx_mon_ppdu_info *ppdu_info) @@ -1196,9 +1544,9 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, 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); + ath12k_wifi7_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats); + ath12k_wifi7_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]); @@ -1277,7 +1625,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; } case HAL_RX_PPDU_START_USER_INFO: - ath12k_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info); + ath12k_wifi7_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info); break; case HAL_RXPCU_PPDU_END_INFO: { -- 2.34.1 Separate Wi-Fi 7-specific monitor handling from ath12k common code to improve modularity. Move the following MSDU END TLV processing functions into wifi7/dp_mon.c and rename them with the ath12k_wifi7_ prefix: - ath12k_dp_mon_parse_rx_msdu_end_err() - ath12k_dp_mon_parse_status_msdu_end() - ath12k_dp_mon_next_link_desc_get() Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh --- drivers/net/wireless/ath/ath12k/dp_mon.c | 50 ---------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 9 --- .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 58 +++++++++++++++++-- 3 files changed, 54 insertions(+), 63 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index db67d81d557f..4f7c7748be6c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -11,41 +11,6 @@ #include "dp_tx.h" #include "peer.h" -static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) -{ - if (info & RX_MSDU_END_INFO13_FCS_ERR) - *errmap |= HAL_RX_MPDU_ERR_FCS; - - if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) - *errmap |= HAL_RX_MPDU_ERR_DECRYPT; - - if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) - *errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; - - if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) - *errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; - - if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) - *errmap |= HAL_RX_MPDU_ERR_OVERFLOW; - - if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) - *errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; - - if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) - *errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; -} - -void -ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, - const struct hal_rx_msdu_end *msdu_end) -{ - ath12k_dp_mon_parse_rx_msdu_end_err(__le32_to_cpu(msdu_end->info2), - &pmon->err_bitmap); - pmon->decap_format = le32_get_bits(msdu_end->info1, - RX_MSDU_END_INFO11_DECAP_FORMAT); -} -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, struct ieee80211_rx_status *rx_status) @@ -139,21 +104,6 @@ u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) } EXPORT_SYMBOL(ath12k_dp_mon_comp_ppduid); -void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, - struct hal_rx_msdu_link *msdu_link, - dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, - struct ath12k_buffer_addr **pp_buf_addr_info) -{ - struct ath12k_buffer_addr *buf_addr_info; - - buf_addr_info = &msdu_link->buf_addr_info; - - ath12k_hal_rx_buf_addr_info_get(&ab->hal, buf_addr_info, paddr, sw_cookie, rbm); - - *pp_buf_addr_info = buf_addr_info; -} -EXPORT_SYMBOL(ath12k_dp_mon_next_link_desc_get); - static void ath12k_dp_mon_fill_rx_rate(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_mon_ppdu_info *ppdu_info, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 6dac4e9569b6..f5debe947ad6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -8,8 +8,6 @@ #define ATH12K_DP_MON_H #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 @@ -110,16 +108,9 @@ void ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, bool *is_frag, u32 *total_len, u32 *frag_len, u32 *msdu_cnt); -void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, - struct hal_rx_msdu_link *msdu_link, - 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_status_msdu_end(struct ath12k_mon_data *pmon, - const struct hal_rx_msdu_end *msdu_end); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 8d913d09f882..6d829d3e1b0c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -1425,6 +1425,40 @@ ath12k_wifi7_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info); } +static void ath12k_wifi7_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) +{ + if (info & RX_MSDU_END_INFO13_FCS_ERR) + *errmap |= HAL_RX_MPDU_ERR_FCS; + + if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) + *errmap |= HAL_RX_MPDU_ERR_DECRYPT; + + if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) + *errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; + + if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) + *errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; + + if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) + *errmap |= HAL_RX_MPDU_ERR_OVERFLOW; + + if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) + *errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; + + if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) + *errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; +} + +static void +ath12k_wifi7_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, + const struct hal_rx_msdu_end *msdu_end) +{ + ath12k_wifi7_dp_mon_parse_rx_msdu_end_err(__le32_to_cpu(msdu_end->info2), + &pmon->err_bitmap); + pmon->decap_format = le32_get_bits(msdu_end->info1, + RX_MSDU_END_INFO11_DECAP_FORMAT); +} + 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, @@ -1665,7 +1699,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, 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); + ath12k_wifi7_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; @@ -2417,6 +2451,21 @@ ath12k_wifi7_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, return tlv_status; } +static void +ath12k_wifi7_dp_mon_next_link_desc_get(struct ath12k_base *ab, + struct hal_rx_msdu_link *msdu_link, + dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, + struct ath12k_buffer_addr **pp_buf_addr_info) +{ + struct ath12k_buffer_addr *buf_addr_info; + + buf_addr_info = &msdu_link->buf_addr_info; + + ath12k_wifi7_hal_rx_buf_addr_info_get(buf_addr_info, paddr, sw_cookie, rbm); + + *pp_buf_addr_info = buf_addr_info; +} + static u32 ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, void *ring_entry, struct sk_buff **head_msdu, @@ -2583,9 +2632,10 @@ ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, ath12k_wifi7_hal_rx_buf_addr_info_set(&buf_info, paddr, sw_cookie, rbm); - ath12k_dp_mon_next_link_desc_get(ab, msdu_link_desc, &paddr, - &sw_cookie, &rbm, - &p_buf_addr_info); + ath12k_wifi7_dp_mon_next_link_desc_get(ab, + msdu_link_desc, &paddr, + &sw_cookie, &rbm, + &p_buf_addr_info); ath12k_dp_arch_rx_link_desc_return(ar->ab->dp, &buf_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); -- 2.34.1 Remove all remaining Wi-Fi 7 header dependencies from dp_mon.c to finalize separation of Wi-Fi 7 specific monitor mode functionality. Remove these includes from dp_mon.c: - wifi7/hal_desc.h - wifi7/hal_qcn9274.h - wifi7/dp_rx.h Relocate hal_mon_buf_ring from wifi7/hal_desc.h to hal.h. Relocate HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID and HAL_RX_FCS_LEN macros from wifi7/hal_rx.h to hal.h or dp_rx.h as appropriate. Move the following functions to the new file wifi7/dp_mon.c and add the ath12k_wifi7 prefix: - ath12k_dp_mon_rx_merg_msdus() - ath12k_dp_mon_update_radiotap() - ath12k_dp_mon_rx_deliver_msdu() - ath12k_dp_mon_get_buf_len() - ath12k_dp_mon_rx_deliver() Export several helper functions needed by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh --- drivers/net/wireless/ath/ath12k/dp_mon.c | 110 +++--------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 27 +++-- drivers/net/wireless/ath/ath12k/dp_rx.h | 9 ++ drivers/net/wireless/ath/ath12k/hal.h | 28 +++++ .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 99 ++++++++++++++-- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 8 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 8 -- .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 19 --- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 10 -- 9 files changed, 165 insertions(+), 153 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 4f7c7748be6c..23ddba557001 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -6,8 +6,6 @@ #include "dp_mon.h" #include "debug.h" -#include "wifi7/hal_qcn9274.h" -#include "wifi7/dp_rx.h" #include "dp_tx.h" #include "peer.h" @@ -205,7 +203,7 @@ static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k_base *ab, skb_pull(head_msdu, total_offset); } -static struct sk_buff * +struct sk_buff * ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, struct hal_rx_mon_ppdu_info *ppdu_info, @@ -333,6 +331,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, } return NULL; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_merg_msdus); static void ath12k_dp_mon_rx_update_radiotap_he(struct hal_rx_mon_ppdu_info *rx_status, @@ -382,10 +381,10 @@ ath12k_dp_mon_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info *rx_status, rtap_buf[rtap_len] = rx_status->he_RU[3]; } -static void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, - struct hal_rx_mon_ppdu_info *ppduinfo, - struct sk_buff *mon_skb, - struct ieee80211_rx_status *rxs) +void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct sk_buff *mon_skb, + struct ieee80211_rx_status *rxs) { struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); struct ieee80211_supported_band *sband; @@ -487,12 +486,13 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, rxs->mactime = ppduinfo->tsft; } +EXPORT_SYMBOL(ath12k_dp_mon_update_radiotap); -static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, - struct napi_struct *napi, - struct sk_buff *msdu, - struct ieee80211_rx_status *status, - u8 decap) +void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + u8 decap) { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; @@ -521,7 +521,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, status->flag |= RX_FLAG_RADIOTAP_HE; } - ath12k_wifi7_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); + ath12k_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); rcu_read_lock(); spin_lock_bh(&dp->dp_lock); @@ -581,62 +581,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } - -int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, - struct dp_mon_mpdu *mon_mpdu, - struct hal_rx_mon_ppdu_info *ppduinfo, - struct napi_struct *napi) -{ - struct sk_buff *mon_skb, *skb_next, *header; - struct ieee80211_rx_status *rxs = &dp_pdev->rx_status; - u8 decap = DP_RX_DECAP_TYPE_RAW; - - mon_skb = ath12k_dp_mon_rx_merg_msdus(dp_pdev, mon_mpdu, ppduinfo, rxs); - if (!mon_skb) - goto mon_deliver_fail; - - header = mon_skb; - rxs->flag = 0; - - if (mon_mpdu->err_bitmap & HAL_RX_MPDU_ERR_FCS) - rxs->flag = RX_FLAG_FAILED_FCS_CRC; - - do { - skb_next = mon_skb->next; - if (!skb_next) - rxs->flag &= ~RX_FLAG_AMSDU_MORE; - else - rxs->flag |= RX_FLAG_AMSDU_MORE; - - if (mon_skb == header) { - header = NULL; - rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN; - } else { - rxs->flag |= RX_FLAG_ALLOW_SAME_PN; - } - rxs->flag |= RX_FLAG_ONLY_MONITOR; - - if (!(rxs->flag & RX_FLAG_ONLY_MONITOR)) - decap = mon_mpdu->decap_format; - - ath12k_dp_mon_update_radiotap(dp_pdev, ppduinfo, mon_skb, rxs); - ath12k_dp_mon_rx_deliver_msdu(dp_pdev, napi, mon_skb, rxs, decap); - mon_skb = skb_next; - } while (mon_skb); - rxs->flag = 0; - - return 0; - -mon_deliver_fail: - mon_skb = mon_mpdu->head; - while (mon_skb) { - skb_next = mon_skb->next; - dev_kfree_skb_any(mon_skb); - mon_skb = skb_next; - } - return -EINVAL; -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_deliver); +EXPORT_SYMBOL(ath12k_dp_mon_rx_deliver_msdu); int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) { @@ -657,33 +602,6 @@ int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) } EXPORT_SYMBOL(ath12k_dp_pkt_set_pktlen); -/* Hardware fill buffer with 128 bytes aligned. So need to reap it - * with 128 bytes aligned. - */ -#define RXDMA_DATA_DMA_BLOCK_SIZE 128 - -void -ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, - bool *is_frag, u32 *total_len, - u32 *frag_len, u32 *msdu_cnt) -{ - if (info->msdu_flags & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) { - *is_frag = true; - *frag_len = (RX_MON_STATUS_BASE_BUF_SIZE - - sizeof(struct hal_rx_desc)) & - ~(RXDMA_DATA_DMA_BLOCK_SIZE - 1); - *total_len += *frag_len; - } else { - if (*is_frag) - *frag_len = info->msdu_len - *total_len; - else - *frag_len = info->msdu_len; - - *msdu_cnt -= 1; - } -} -EXPORT_SYMBOL(ath12k_dp_mon_get_buf_len); - int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index f5debe947ad6..394463ea19e0 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -96,21 +96,32 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, struct hal_rx_mon_ppdu_info *ppdu_info); int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len); -int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, - struct dp_mon_mpdu *mon_mpdu, - struct hal_rx_mon_ppdu_info *ppduinfo, - struct napi_struct *napi); struct sk_buff *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int *buf_id); -void -ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, - bool *is_frag, u32 *total_len, - u32 *frag_len, u32 *msdu_cnt); 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_update_radiotap(struct ath12k_pdev_dp *dp_pdev, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct sk_buff *mon_skb, + struct ieee80211_rx_status *rxs); +void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + u8 decap); +void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + u8 decap); +struct sk_buff * +ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, + struct dp_mon_mpdu *mon_mpdu, + struct hal_rx_mon_ppdu_info *ppdu_info, + struct ieee80211_rx_status *rxs); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index a4ac67eb91d1..88651553120d 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -165,6 +165,15 @@ static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) dev_kfree_skb_any(skb); } +static inline +void ath12k_dp_extract_rx_desc_data(struct ath12k_hal *hal, + struct hal_rx_desc_data *rx_info, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc) +{ + hal->ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); +} + void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, enum hal_encrypt_type enctype, diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 1d22173975f0..ce038906bd06 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -73,6 +73,16 @@ struct ath12k_base; #define HAL_RX_MAX_NSS 8 #define HAL_RX_MAX_NUM_LEGACY_RATES 12 +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER BIT(31) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS GENMASK(2, 0) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS GENMASK(6, 3) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC BIT(7) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_DCM BIT(8) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START GENMASK(15, 9) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE GENMASK(18, 16) +#define HAL_RX_FCS_LEN 4 + enum hal_srng_ring_id { HAL_SRNG_RING_ID_REO2SW0 = 0, HAL_SRNG_RING_ID_REO2SW1, @@ -597,6 +607,24 @@ struct hal_rx_msdu_desc_info { u16 msdu_len; /* 14 bits for length */ }; +/* hal_mon_buf_ring + * Producer : SW + * Consumer : Monitor + * + * paddr_lo + * Lower 32-bit physical address of the buffer pointer from the source ring. + * paddr_hi + * bit range 7-0 : upper 8 bit of the physical address. + * bit range 31-8 : reserved. + * cookie + * Consumer: RxMon/TxMon 64 bit cookie of the buffers. + */ +struct hal_mon_buf_ring { + __le32 paddr_lo; + __le32 paddr_hi; + __le64 cookie; +}; + struct hal_rx_mon_ppdu_info { u32 ppdu_id; u32 last_ppdu_id; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 6d829d3e1b0c..9878553289c4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -31,6 +31,32 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +/* Hardware fill buffer with 128 bytes aligned. So need to reap it + * with 128 bytes aligned. + */ +#define RXDMA_DATA_DMA_BLOCK_SIZE 128 + +static void +ath12k_wifi7_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, + bool *is_frag, u32 *total_len, + u32 *frag_len, u32 *msdu_cnt) +{ + if (info->msdu_flags & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) { + *is_frag = true; + *frag_len = (RX_MON_STATUS_BASE_BUF_SIZE - + sizeof(struct hal_rx_desc)) & + ~(RXDMA_DATA_DMA_BLOCK_SIZE - 1); + *total_len += *frag_len; + } else { + if (*is_frag) + *frag_len = info->msdu_len - *total_len; + else + *frag_len = info->msdu_len; + + *msdu_cnt -= 1; + } +} + static void ath12k_wifi7_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) @@ -2373,6 +2399,62 @@ ath12k_wifi7_dp_mon_tx_status_get_num_user(u16 tlv_tag, return tlv_status; } +static int +ath12k_wifi7_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, + struct dp_mon_mpdu *mon_mpdu, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct napi_struct *napi) +{ + struct sk_buff *mon_skb, *skb_next, *header; + struct ieee80211_rx_status *rxs = &dp_pdev->rx_status; + u8 decap = DP_RX_DECAP_TYPE_RAW; + + mon_skb = ath12k_dp_mon_rx_merg_msdus(dp_pdev, mon_mpdu, ppduinfo, rxs); + if (!mon_skb) + goto mon_deliver_fail; + + header = mon_skb; + rxs->flag = 0; + + if (mon_mpdu->err_bitmap & HAL_RX_MPDU_ERR_FCS) + rxs->flag = RX_FLAG_FAILED_FCS_CRC; + + do { + skb_next = mon_skb->next; + if (!skb_next) + rxs->flag &= ~RX_FLAG_AMSDU_MORE; + else + rxs->flag |= RX_FLAG_AMSDU_MORE; + + if (mon_skb == header) { + header = NULL; + rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN; + } else { + rxs->flag |= RX_FLAG_ALLOW_SAME_PN; + } + rxs->flag |= RX_FLAG_ONLY_MONITOR; + + if (!(rxs->flag & RX_FLAG_ONLY_MONITOR)) + decap = mon_mpdu->decap_format; + + ath12k_dp_mon_update_radiotap(dp_pdev, ppduinfo, mon_skb, rxs); + ath12k_dp_mon_rx_deliver_msdu(dp_pdev, napi, mon_skb, rxs, decap); + mon_skb = skb_next; + } while (mon_skb); + rxs->flag = 0; + + return 0; + +mon_deliver_fail: + mon_skb = mon_mpdu->head; + while (mon_skb) { + skb_next = mon_skb->next; + dev_kfree_skb_any(mon_skb); + mon_skb = skb_next; + } + return -EINVAL; +} + static void ath12k_wifi7_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, @@ -2385,8 +2467,8 @@ ath12k_wifi7_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, list_del(&mon_mpdu->list); if (mon_mpdu->head) - ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, - &tx_ppdu_info->rx_status, napi); + ath12k_wifi7_dp_mon_rx_deliver(dp_pdev, mon_mpdu, + &tx_ppdu_info->rx_status, napi); kfree(mon_mpdu); } @@ -2606,9 +2688,9 @@ ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, pmon->mon_last_linkdesc_paddr = paddr; is_first_msdu = false; } - ath12k_dp_mon_get_buf_len(&msdu_list.msdu_info[i], - &is_frag, &total_len, - &frag_len, &msdu_cnt); + ath12k_wifi7_dp_mon_get_buf_len(&msdu_list.msdu_info[i], + &is_frag, &total_len, + &frag_len, &msdu_cnt); rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len; if (ath12k_dp_pkt_set_pktlen(msdu, rx_buf_size)) { @@ -2748,8 +2830,8 @@ ath12k_wifi7_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, tmp_mpdu->tail = tail_msdu; tmp_mpdu->err_bitmap = pmon->err_bitmap; tmp_mpdu->decap_format = pmon->decap_format; - ath12k_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, - &pmon->mon_ppdu_info, napi); + ath12k_wifi7_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, + &pmon->mon_ppdu_info, napi); rx_mon_stats->dest_mpdu_done++; kfree(tmp_mpdu); } @@ -2883,7 +2965,8 @@ ath12k_wifi7_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, list_del(&mon_mpdu->list); if (mon_mpdu->head && mon_mpdu->tail) - ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, ppdu_info, napi); + ath12k_wifi7_dp_mon_rx_deliver(dp_pdev, mon_mpdu, + ppdu_info, napi); kfree(mon_mpdu); } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 08dcf170b801..af50dafc0349 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -524,7 +524,7 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, rx_desc = (struct hal_rx_desc *)msdu->data; lrx_desc = (struct hal_rx_desc *)last_buf->data; - ath12k_wifi7_dp_extract_rx_desc_data(hal, rx_info, rx_desc, lrx_desc); + ath12k_dp_extract_rx_desc_data(hal, rx_info, rx_desc, lrx_desc); if (!rx_info->msdu_done) { ath12k_warn(dp->ab, "msdu_done bit in msdu_end is not set\n"); ret = -EIO; @@ -1035,7 +1035,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true; (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true; - ath12k_wifi7_dp_extract_rx_desc_data(hal, rx_info, rx_desc, rx_desc); + ath12k_dp_extract_rx_desc_data(hal, rx_info, rx_desc, rx_desc); rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; @@ -1333,7 +1333,7 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, } rx_desc = (struct hal_rx_desc *)msdu->data; - ath12k_wifi7_dp_extract_rx_desc_data(hal, &rx_info, rx_desc, rx_desc); + ath12k_dp_extract_rx_desc_data(hal, &rx_info, rx_desc, rx_desc); msdu_len = rx_info.msdu_len; if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { @@ -1714,7 +1714,7 @@ static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k_pdev_dp *dp_pdev, rx_info.addr2_present = false; rx_info.rx_status = &rxs; - ath12k_wifi7_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); + ath12k_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); switch (rxcb->err_rel_src) { case HAL_WBM_REL_SRC_MODULE_REO: diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 2d3eb2313b2f..d15bffe223c7 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -52,12 +52,4 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, bool ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); -static inline -void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_hal *hal, - struct hal_rx_desc_data *rx_info, - struct hal_rx_desc *rx_desc, - struct hal_rx_desc *ldesc) -{ - hal->ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); -} #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index aecbf00ea87b..fb1bbe5c94cd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -2681,25 +2681,6 @@ struct hal_tcl_entrance_from_ppe_ring { __le32 info0; } __packed; -struct hal_mon_buf_ring { - __le32 paddr_lo; - __le32 paddr_hi; - __le64 cookie; -}; - -/* hal_mon_buf_ring - * Producer : SW - * Consumer : Monitor - * - * paddr_lo - * Lower 32-bit physical address of the buffer pointer from the source ring. - * paddr_hi - * bit range 7-0 : upper 8 bit of the physical address. - * bit range 31-8 : reserved. - * cookie - * Consumer: RxMon/TxMon 64 bit cookie of the buffers. - */ - #define HAL_MON_DEST_COOKIE_BUF_ID GENMASK(17, 0) #define HAL_MON_DEST_INFO0_END_OFFSET GENMASK(11, 0) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index c5a2125a04af..926fbcd2d8b8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -45,7 +45,6 @@ struct hal_rx_mon_status_tlv_hdr { #define HAL_TLV_STATUS_PPDU_DONE 1 #define HAL_TLV_STATUS_BUF_DONE 2 #define HAL_TLV_STATUS_PPDU_NON_STD_DONE 3 -#define HAL_RX_FCS_LEN 4 enum hal_rx_mon_status { HAL_RX_MON_STATUS_PPDU_NOT_DONE, @@ -365,15 +364,6 @@ struct hal_rx_resp_req_info { #define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2 0xBDBEEF #define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3 0xCDBEEF -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER BIT(31) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS GENMASK(2, 0) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS GENMASK(6, 3) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC BIT(7) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_DCM BIT(8) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START GENMASK(15, 9) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE GENMASK(18, 16) - /* HE Radiotap data1 Mask */ #define HE_SU_FORMAT_TYPE 0x0000 #define HE_EXT_SU_FORMAT_TYPE 0x0001 -- 2.34.1