wifi: ath12k: add interrupt configuration for mon status ring
authorKang Yang <kang.yang@oss.qualcomm.com>
Mon, 21 Apr 2025 02:34:36 +0000 (10:34 +0800)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Fri, 16 May 2025 19:38:55 +0000 (12:38 -0700)
The monitor mode design is:
1. Hardware captures packets on the air.
2. Hardware stores the packets into related rings.
3. When the ring buffer reaches the interrupt threshold, it triggers
the interrupt.
4. Reap and process the ring buffer in ath12k_dp_service_srng().

Here the interrupt thresholds are intr_timer_thres_us, low_threshold and
intr_batch_cntr_thres_entries. An interrupt will be triggered once:
1. Number of packets in the ring reaches intr_batch_cntr_thres_entries.
2. Number of packets in the ring reaches low_threshold(by timer).
3. Timer reaches intr_timer_thres_us.

So, add interrupt configuration for the mon status ring, then start
to process ring buffers when the interrupt arrives.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1

Signed-off-by: Kang Yang <kang.yang@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250421023444.1778-6-kang.yang@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/dp.c
drivers/net/wireless/ath/ath12k/hw.c
drivers/net/wireless/ath/ath12k/hw.h
drivers/net/wireless/ath/ath12k/pci.c

index 2e0c5922b6e4c34b6eb24631925bd7d50bc9725e..8e4d8ef3229f3fcaa1bdd49d2295cfe63d5f3ece 100644 (file)
@@ -168,6 +168,8 @@ static int ath12k_dp_srng_calculate_msi_group(struct ath12k_base *ab,
                grp_mask = &ab->hw_params->ring_mask->reo_status[0];
                break;
        case HAL_RXDMA_MONITOR_STATUS:
+               grp_mask = &ab->hw_params->ring_mask->rx_mon_status[0];
+               break;
        case HAL_RXDMA_MONITOR_DST:
                grp_mask = &ab->hw_params->ring_mask->rx_mon_dest[0];
                break;
@@ -274,12 +276,17 @@ int ath12k_dp_srng_setup(struct ath12k_base *ab, struct dp_srng *ring,
                break;
        case HAL_RXDMA_BUF:
        case HAL_RXDMA_MONITOR_BUF:
-       case HAL_RXDMA_MONITOR_STATUS:
                params.low_threshold = num_entries >> 3;
                params.flags |= HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN;
                params.intr_batch_cntr_thres_entries = 0;
                params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_RX;
                break;
+       case HAL_RXDMA_MONITOR_STATUS:
+               params.low_threshold = num_entries >> 3;
+               params.flags |= HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN;
+               params.intr_batch_cntr_thres_entries = 1;
+               params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_RX;
+               break;
        case HAL_TX_MONITOR_DST:
                params.low_threshold = DP_TX_MONITOR_BUF_SIZE_MAX >> 3;
                params.flags |= HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN;
@@ -919,6 +926,21 @@ int ath12k_dp_service_srng(struct ath12k_base *ab,
                        goto done;
        }
 
+       if (ab->hw_params->ring_mask->rx_mon_status[grp_id]) {
+               ring_mask = ab->hw_params->ring_mask->rx_mon_status[grp_id];
+               for (i = 0; i < ab->num_radios; i++) {
+                       for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) {
+                               int id = i * ab->hw_params->num_rxdma_per_pdev + j;
+
+                               if (ring_mask & BIT(id)) {
+                                       /* TODO: add monitor mode function */
+                                       if (budget <= 0)
+                                               goto done;
+                               }
+                       }
+               }
+       }
+
        if (ab->hw_params->ring_mask->rx_mon_dest[grp_id]) {
                monitor_mode = ATH12K_DP_RX_MONITOR_MODE;
                ring_mask = ab->hw_params->ring_mask->rx_mon_dest[grp_id];
index a46d82857c5d3e111c5db4ff95eba2fa67cd1b41..482b0f4e8f95bfafe8ec5b7cc105002b10f741da 100644 (file)
@@ -118,6 +118,10 @@ static const struct ath12k_hw_ops wcn7850_ops = {
 #define ATH12K_TX_MON_RING_MASK_0 0x1
 #define ATH12K_TX_MON_RING_MASK_1 0x2
 
+#define ATH12K_RX_MON_STATUS_RING_MASK_0 0x1
+#define ATH12K_RX_MON_STATUS_RING_MASK_1 0x2
+#define ATH12K_RX_MON_STATUS_RING_MASK_2 0x4
+
 /* Target firmware's Copy Engine configuration. */
 static const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[] = {
        /* CE0: host->target HTC control and raw streams */
@@ -836,6 +840,12 @@ static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn7850 = {
        },
        .rx_mon_dest = {
        },
+       .rx_mon_status = {
+               0, 0, 0, 0,
+               ATH12K_RX_MON_STATUS_RING_MASK_0,
+               ATH12K_RX_MON_STATUS_RING_MASK_1,
+               ATH12K_RX_MON_STATUS_RING_MASK_2,
+       },
        .rx = {
                0, 0, 0,
                ATH12K_RX_RING_MASK_0,
index 024cfcd2cc158d6f4c26d369a97b1e2382ec6360..0fbc17649df463334aa0ebb3da407115985335ca 100644 (file)
@@ -135,6 +135,7 @@ enum hal_encrypt_type;
 struct ath12k_hw_ring_mask {
        u8 tx[ATH12K_EXT_IRQ_GRP_NUM_MAX];
        u8 rx_mon_dest[ATH12K_EXT_IRQ_GRP_NUM_MAX];
+       u8 rx_mon_status[ATH12K_EXT_IRQ_GRP_NUM_MAX];
        u8 rx[ATH12K_EXT_IRQ_GRP_NUM_MAX];
        u8 rx_err[ATH12K_EXT_IRQ_GRP_NUM_MAX];
        u8 rx_wbm_rel[ATH12K_EXT_IRQ_GRP_NUM_MAX];
index 528a4a57d13612ba7b8fcf0532b80f4d400e5a5b..5c012f7fcd975d795792a0a3e5e3385f38e256ce 100644 (file)
@@ -600,7 +600,8 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
                    ab->hw_params->ring_mask->rx_wbm_rel[i] ||
                    ab->hw_params->ring_mask->reo_status[i] ||
                    ab->hw_params->ring_mask->host2rxdma[i] ||
-                   ab->hw_params->ring_mask->rx_mon_dest[i]) {
+                   ab->hw_params->ring_mask->rx_mon_dest[i] ||
+                   ab->hw_params->ring_mask->rx_mon_status[i]) {
                        num_irq = 1;
                }