Message ID | 20250127114030.43479-3-quic_periyasa@quicinc.com |
---|---|
State | Superseded |
Headers | show |
Series | wifi: ath12k: Add monitor interface support on QCN9274 | expand |
On 1/27/2025 5:10 PM, Karthikeyan Periyasamy wrote: > From: P Praneesh <quic_ppranees@quicinc.com> > > Currently, the monitor Rx parser handler is inherited from the ath11k. > However, the ath12k 802.11be hardware does not report the Rx TLV header > in the MSDU data. Instead, the hardware reports those TLVs under the > following TLV tags: > > 1. Buffer address > 2. MPDU start > 3. MPDU end > 4. MSDU end > > Therefore, add support for parsing the above TLVs in the Rx monitor path > and use this information for MSDU buffer and status updates. > > Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 > Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 > > Signed-off-by: P Praneesh <quic_ppranees@quicinc.com> > Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com> > Tested-by: Nicolas Escande <nico.escande@gmail.com> > --- > drivers/net/wireless/ath/ath12k/dp.h | 4 +- > drivers/net/wireless/ath/ath12k/dp_mon.c | 157 ++++++++++++++++++++++- > drivers/net/wireless/ath/ath12k/dp_mon.h | 4 +- > drivers/net/wireless/ath/ath12k/dp_rx.c | 1 + > drivers/net/wireless/ath/ath12k/hal_rx.h | 12 +- > 5 files changed, 170 insertions(+), 8 deletions(-) > > diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h > index f68bb78d4a11..27efd37f0955 100644 > --- a/drivers/net/wireless/ath/ath12k/dp.h > +++ b/drivers/net/wireless/ath/ath12k/dp.h > @@ -1,7 +1,7 @@ > /* SPDX-License-Identifier: BSD-3-Clause-Clear */ > /* > * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. > - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. > + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. > */ > > #ifndef ATH12K_DP_H > @@ -106,6 +106,8 @@ struct dp_mon_mpdu { > struct list_head list; > struct sk_buff *head; > struct sk_buff *tail; > + u32 err_bitmap; > + u8 decap_format; > }; > > #define DP_MON_MAX_STATUS_BUF 32 > diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c > index 023715df1126..e9f53ac169b4 100644 > --- a/drivers/net/wireless/ath/ath12k/dp_mon.c > +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c > @@ -1678,7 +1678,7 @@ ath12k_dp_mon_rx_parse_status_tlv(struct ath12k *ar, > u32_get_bits(info[0], HAL_RX_MPDU_START_INFO0_PPDU_ID); > } > > - break; > + return HAL_RX_MON_STATUS_MPDU_START; > } > case HAL_RX_MSDU_START: > /* TODO: add msdu start parsing logic */ > @@ -2121,6 +2121,144 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar, > return -EINVAL; > } > > +static int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) > +{ > + if (skb->len > len) { > + skb_trim(skb, len); > + } else { > + if (skb_tailroom(skb) < len - skb->len) { > + if ((pskb_expand_head(skb, 0, > + len - skb->len - skb_tailroom(skb), > + GFP_ATOMIC))) { > + return -ENOMEM; > + } > + } > + skb_put(skb, (len - skb->len)); > + } > + > + return 0; > +} > + > +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; > +} > + > +static int > +ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, > + const struct hal_rx_msdu_end *msdu_end) > +{ > + struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; > + > + ath12k_dp_mon_parse_rx_msdu_end_err(__le32_to_cpu(msdu_end->info2), > + &mon_mpdu->err_bitmap); > + > + mon_mpdu->decap_format = le32_get_bits(msdu_end->info1, > + RX_MSDU_END_INFO11_DECAP_FORMAT); > + > + return 0; > +} > + > +static int > +ath12k_dp_mon_parse_status_buf(struct ath12k *ar, > + struct ath12k_mon_data *pmon, > + const struct dp_mon_packet_info *packet_info) > +{ > + struct ath12k_base *ab = ar->ab; > + struct dp_rxdma_mon_ring *buf_ring = &ab->dp.rxdma_mon_buf_ring; > + struct sk_buff *msdu; > + int buf_id; > + u32 offset; > + > + buf_id = u32_get_bits(packet_info->cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); > + > + spin_lock_bh(&buf_ring->idr_lock); > + msdu = idr_remove(&buf_ring->bufs_idr, buf_id); > + spin_unlock_bh(&buf_ring->idr_lock); > + > + if (unlikely(!msdu)) { > + ath12k_warn(ab, "mon dest desc with inval buf_id %d\n", buf_id); > + return 0; > + } > + > + dma_unmap_single(ab->dev, ATH12K_SKB_RXCB(msdu)->paddr, > + msdu->len + skb_tailroom(msdu), > + DMA_FROM_DEVICE); > + > + offset = packet_info->dma_length + ATH12K_MON_RX_DOT11_OFFSET; > + if (ath12k_dp_pkt_set_pktlen(msdu, offset)) { > + dev_kfree_skb_any(msdu); > + goto dest_replenish; > + } > + > + if (!pmon->mon_mpdu->head) > + pmon->mon_mpdu->head = msdu; > + else > + pmon->mon_mpdu->tail->next = msdu; > + > + pmon->mon_mpdu->tail = msdu; > + > +dest_replenish: > + ath12k_dp_mon_buf_replenish(ab, buf_ring, 1); > + > + return 0; > +} > + > +static int > +ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k *ar, > + 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(ar, 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: > + return ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data); > + default: > + break; > + } > + > + return 0; > +} > + > static enum hal_rx_mon_status > ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon, > struct sk_buff *skb) > @@ -2147,14 +2285,20 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon, > tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); > > hal_status = ath12k_dp_mon_rx_parse_status_tlv(ar, pmon, tlv); > + > + if (ar->monitor_started && > + ath12k_dp_mon_parse_rx_dest_tlv(ar, 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) >= DP_RX_BUFFER_SIZE) > + 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)); > > @@ -2175,9 +2319,11 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, > struct dp_mon_mpdu *tmp; > struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; > struct sk_buff *head_msdu, *tail_msdu; > - enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE; > + enum hal_rx_mon_status hal_status; > > - ath12k_dp_mon_parse_rx_dest(ar, pmon, skb); > + hal_status = ath12k_dp_mon_parse_rx_dest(ar, 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); > @@ -2191,6 +2337,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, > > kfree(mon_mpdu); > } > + > return hal_status; > } > > @@ -3377,7 +3524,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, > ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); > > while ((skb = __skb_dequeue(&skb_list))) { > - hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb); > + hal_status = ath12k_dp_mon_rx_parse_mon_status(ar, pmon, skb, napi); > if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { > ppdu_info->ppdu_continuation = true; > dev_kfree_skb_any(skb); > diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h > index e4368eb42aca..b039f6b9277c 100644 > --- a/drivers/net/wireless/ath/ath12k/dp_mon.h > +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h > @@ -1,7 +1,7 @@ > /* SPDX-License-Identifier: BSD-3-Clause-Clear */ > /* > * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. > - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. > + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. > */ > > #ifndef ATH12K_DP_MON_H > @@ -9,6 +9,8 @@ > > #include "core.h" > > +#define ATH12K_MON_RX_DOT11_OFFSET 5 > + > enum dp_monitor_mode { > ATH12K_DP_TX_MONITOR_MODE, > ATH12K_DP_RX_MONITOR_MODE > diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c > index 95c9056642cf..44e47ec5b3ee 100644 > --- a/drivers/net/wireless/ath/ath12k/dp_rx.c > +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c > @@ -4442,6 +4442,7 @@ int ath12k_dp_rx_pdev_mon_attach(struct ath12k *ar) > > pmon->mon_last_linkdesc_paddr = 0; > pmon->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1; > + INIT_LIST_HEAD(&pmon->dp_rx_mon_mpdu_list); > spin_lock_init(&pmon->mon_lock); > > return 0; > diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.h b/drivers/net/wireless/ath/ath12k/hal_rx.h > index 6bdcd0867d86..6f10e4222ba6 100644 > --- a/drivers/net/wireless/ath/ath12k/hal_rx.h > +++ b/drivers/net/wireless/ath/ath12k/hal_rx.h > @@ -108,11 +108,12 @@ enum hal_rx_mon_status { > HAL_RX_MON_STATUS_PPDU_DONE, > HAL_RX_MON_STATUS_BUF_DONE, > HAL_RX_MON_STATUS_BUF_ADDR, > + HAL_RX_MON_STATUS_MPDU_START, > HAL_RX_MON_STATUS_MPDU_END, > HAL_RX_MON_STATUS_MSDU_END, > }; > > -#define HAL_RX_MAX_MPDU 256 > +#define HAL_RX_MAX_MPDU 1024 > #define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) > > struct hal_rx_user_status { > @@ -506,6 +507,15 @@ struct hal_rx_mpdu_start { > __le32 rsvd2[16]; > } __packed; > > +struct hal_rx_msdu_end { > + __le32 info0; > + __le32 rsvd0[18]; > + __le32 info1; > + __le32 rsvd1[10]; > + __le32 info2; > + __le32 rsvd2; > +} __packed; > + > #define HAL_RX_PPDU_END_DURATION GENMASK(23, 0) > struct hal_rx_ppdu_end_duration { > __le32 rsvd0[9]; Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index f68bb78d4a11..27efd37f0955 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH12K_DP_H @@ -106,6 +106,8 @@ struct dp_mon_mpdu { struct list_head list; struct sk_buff *head; struct sk_buff *tail; + u32 err_bitmap; + u8 decap_format; }; #define DP_MON_MAX_STATUS_BUF 32 diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 023715df1126..e9f53ac169b4 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -1678,7 +1678,7 @@ ath12k_dp_mon_rx_parse_status_tlv(struct ath12k *ar, u32_get_bits(info[0], HAL_RX_MPDU_START_INFO0_PPDU_ID); } - break; + return HAL_RX_MON_STATUS_MPDU_START; } case HAL_RX_MSDU_START: /* TODO: add msdu start parsing logic */ @@ -2121,6 +2121,144 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar, return -EINVAL; } +static int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) +{ + if (skb->len > len) { + skb_trim(skb, len); + } else { + if (skb_tailroom(skb) < len - skb->len) { + if ((pskb_expand_head(skb, 0, + len - skb->len - skb_tailroom(skb), + GFP_ATOMIC))) { + return -ENOMEM; + } + } + skb_put(skb, (len - skb->len)); + } + + return 0; +} + +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; +} + +static int +ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, + const struct hal_rx_msdu_end *msdu_end) +{ + struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; + + ath12k_dp_mon_parse_rx_msdu_end_err(__le32_to_cpu(msdu_end->info2), + &mon_mpdu->err_bitmap); + + mon_mpdu->decap_format = le32_get_bits(msdu_end->info1, + RX_MSDU_END_INFO11_DECAP_FORMAT); + + return 0; +} + +static int +ath12k_dp_mon_parse_status_buf(struct ath12k *ar, + struct ath12k_mon_data *pmon, + const struct dp_mon_packet_info *packet_info) +{ + struct ath12k_base *ab = ar->ab; + struct dp_rxdma_mon_ring *buf_ring = &ab->dp.rxdma_mon_buf_ring; + struct sk_buff *msdu; + int buf_id; + u32 offset; + + buf_id = u32_get_bits(packet_info->cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); + + spin_lock_bh(&buf_ring->idr_lock); + msdu = idr_remove(&buf_ring->bufs_idr, buf_id); + spin_unlock_bh(&buf_ring->idr_lock); + + if (unlikely(!msdu)) { + ath12k_warn(ab, "mon dest desc with inval buf_id %d\n", buf_id); + return 0; + } + + dma_unmap_single(ab->dev, ATH12K_SKB_RXCB(msdu)->paddr, + msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); + + offset = packet_info->dma_length + ATH12K_MON_RX_DOT11_OFFSET; + if (ath12k_dp_pkt_set_pktlen(msdu, offset)) { + dev_kfree_skb_any(msdu); + goto dest_replenish; + } + + if (!pmon->mon_mpdu->head) + pmon->mon_mpdu->head = msdu; + else + pmon->mon_mpdu->tail->next = msdu; + + pmon->mon_mpdu->tail = msdu; + +dest_replenish: + ath12k_dp_mon_buf_replenish(ab, buf_ring, 1); + + return 0; +} + +static int +ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k *ar, + 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(ar, 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: + return ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data); + default: + break; + } + + return 0; +} + static enum hal_rx_mon_status ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon, struct sk_buff *skb) @@ -2147,14 +2285,20 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon, tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); hal_status = ath12k_dp_mon_rx_parse_status_tlv(ar, pmon, tlv); + + if (ar->monitor_started && + ath12k_dp_mon_parse_rx_dest_tlv(ar, 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) >= DP_RX_BUFFER_SIZE) + 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)); @@ -2175,9 +2319,11 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, struct dp_mon_mpdu *tmp; struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; struct sk_buff *head_msdu, *tail_msdu; - enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE; + enum hal_rx_mon_status hal_status; - ath12k_dp_mon_parse_rx_dest(ar, pmon, skb); + hal_status = ath12k_dp_mon_parse_rx_dest(ar, 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); @@ -2191,6 +2337,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, kfree(mon_mpdu); } + return hal_status; } @@ -3377,7 +3524,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); while ((skb = __skb_dequeue(&skb_list))) { - hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb); + hal_status = ath12k_dp_mon_rx_parse_mon_status(ar, pmon, skb, napi); if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { ppdu_info->ppdu_continuation = true; dev_kfree_skb_any(skb); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index e4368eb42aca..b039f6b9277c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH12K_DP_MON_H @@ -9,6 +9,8 @@ #include "core.h" +#define ATH12K_MON_RX_DOT11_OFFSET 5 + enum dp_monitor_mode { ATH12K_DP_TX_MONITOR_MODE, ATH12K_DP_RX_MONITOR_MODE diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 95c9056642cf..44e47ec5b3ee 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -4442,6 +4442,7 @@ int ath12k_dp_rx_pdev_mon_attach(struct ath12k *ar) pmon->mon_last_linkdesc_paddr = 0; pmon->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1; + INIT_LIST_HEAD(&pmon->dp_rx_mon_mpdu_list); spin_lock_init(&pmon->mon_lock); return 0; diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.h b/drivers/net/wireless/ath/ath12k/hal_rx.h index 6bdcd0867d86..6f10e4222ba6 100644 --- a/drivers/net/wireless/ath/ath12k/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/hal_rx.h @@ -108,11 +108,12 @@ enum hal_rx_mon_status { HAL_RX_MON_STATUS_PPDU_DONE, HAL_RX_MON_STATUS_BUF_DONE, HAL_RX_MON_STATUS_BUF_ADDR, + HAL_RX_MON_STATUS_MPDU_START, HAL_RX_MON_STATUS_MPDU_END, HAL_RX_MON_STATUS_MSDU_END, }; -#define HAL_RX_MAX_MPDU 256 +#define HAL_RX_MAX_MPDU 1024 #define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) struct hal_rx_user_status { @@ -506,6 +507,15 @@ struct hal_rx_mpdu_start { __le32 rsvd2[16]; } __packed; +struct hal_rx_msdu_end { + __le32 info0; + __le32 rsvd0[18]; + __le32 info1; + __le32 rsvd1[10]; + __le32 info2; + __le32 rsvd2; +} __packed; + #define HAL_RX_PPDU_END_DURATION GENMASK(23, 0) struct hal_rx_ppdu_end_duration { __le32 rsvd0[9];