// 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 "dp_mon.h"
#include "debug.h"
#include "dp_tx.h"
#include "peer.h"
static void
ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info,
struct ieee80211_rx_status *rx_status)
{
u32 center_freq = ppdu_info->freq;
rx_status->freq = center_freq;
rx_status->bw = ath12k_mac_bw_to_mac80211_bw(ppdu_info->bw);
rx_status->nss = ppdu_info->nss;
rx_status->rate_idx = 0;
rx_status->encoding = RX_ENC_LEGACY;
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
if (center_freq >= ATH12K_MIN_6GHZ_FREQ &&
center_freq <= ATH12K_MAX_6GHZ_FREQ) {
rx_status->band = NL80211_BAND_6GHZ;
} else if (center_freq >= ATH12K_MIN_2GHZ_FREQ &&
center_freq <= ATH12K_MAX_2GHZ_FREQ) {
rx_status->band = NL80211_BAND_2GHZ;
} else if (center_freq >= ATH12K_MIN_5GHZ_FREQ &&
center_freq <= ATH12K_MAX_5GHZ_FREQ) {
rx_status->band = NL80211_BAND_5GHZ;
} else {
rx_status->band = NUM_NL80211_BANDS;
}
}
struct sk_buff
*ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab,
struct dp_rxdma_mon_ring *rx_ring,
int *buf_id)
{
struct sk_buff *skb;
dma_addr_t paddr;
skb = dev_alloc_skb(RX_MON_STATUS_BUF_SIZE);
if (!skb)
goto fail_alloc_skb;
if (!IS_ALIGNED((unsigned long)skb->data,
RX_MON_STATUS_BUF_ALIGN)) {
skb_pull(skb, PTR_ALIGN(skb->data, RX_MON_STATUS_BUF_ALIGN) -
skb->data);
}
paddr = dma_map_single(ab->dev, skb->data,
skb->len + skb_tailroom(skb),
DMA_FROM_DEVICE);
if (unlikely(dma_mapping_error(ab->dev, paddr)))
goto fail_free_skb;
spin_lock_bh(&rx_ring->idr_lock);
*buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 0,
rx_ring->bufs_max, GFP_ATOMIC);
spin_unlock_bh(&rx_ring->idr_lock);
if (*buf_id < 0)
goto fail_dma_unmap;
ATH12K_SKB_RXCB(skb)->paddr = paddr;
return skb;
fail_dma_unmap:
dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb),
DMA_FROM_DEVICE);
fail_free_skb:
dev_kfree_skb_any(skb);
fail_alloc_skb:
return NULL;
}
EXPORT_SYMBOL(ath12k_dp_rx_alloc_mon_status_buf);
u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id)
{
u32 ret = 0;
if ((*ppdu_id < msdu_ppdu_id) &&
((msdu_ppdu_id - *ppdu_id) < DP_NOT_PPDU_ID_WRAP_AROUND)) {
/* Hold on mon dest ring, and reap mon status ring. */
*ppdu_id = msdu_ppdu_id;
ret = msdu_ppdu_id;
} else if ((*ppdu_id > msdu_ppdu_id) &&
((*ppdu_id - msdu_ppdu_id) > DP_NOT_PPDU_ID_WRAP_AROUND)) {
/* PPDU ID has exceeded the maximum value and will
* restart from 0.
*/
*ppdu_id = msdu_ppdu_id;
ret = msdu_ppdu_id;
}
return ret;
}
EXPORT_SYMBOL(