]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: Fix the enabling of REO queue lookup table feature
authorSriram R <quic_srirrama@quicinc.com>
Wed, 2 Apr 2025 15:25:27 +0000 (20:55 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Thu, 3 Apr 2025 18:50:06 +0000 (11:50 -0700)
Instead of storing the REO queue address inside peer entries, REO
hardware module prefers them to be stored in SRAM which could be
directly accessed by REO using peer_ID/TID based lookup table
mechanism.

Fix the enabling of the REO queue lookup table(LUT) feature by
configuring the LUT address information in the REO hardware register
and setting the host service flags.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1

Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
Signed-off-by: Nithyanantham Paramasivam <quic_nithp@quicinc.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250402152529.1649402-2-quic_nithp@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/dp.c
drivers/net/wireless/ath/ath12k/dp.h
drivers/net/wireless/ath/ath12k/dp_rx.c
drivers/net/wireless/ath/ath12k/hal.h
drivers/net/wireless/ath/ath12k/hw.c
drivers/net/wireless/ath/ath12k/hw.h
drivers/net/wireless/ath/ath12k/wmi.c
drivers/net/wireless/ath/ath12k/wmi.h

index b1f27c3ac723e9db897fdfbd4af2096bab1fb850..80b9f4594deed622febfbb0ea3f849529ddfdeac 100644 (file)
@@ -1261,22 +1261,24 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab)
        if (!ab->hw_params->reoq_lut_support)
                return;
 
-       if (dp->reoq_lut.vaddr) {
+       if (dp->reoq_lut.vaddr_unaligned) {
                ath12k_hif_write32(ab,
                                   HAL_SEQ_WCSS_UMAC_REO_REG +
                                   HAL_REO1_QDESC_LUT_BASE0(ab), 0);
-               dma_free_coherent(ab->dev, DP_REOQ_LUT_SIZE,
-                                 dp->reoq_lut.vaddr, dp->reoq_lut.paddr);
-               dp->reoq_lut.vaddr = NULL;
+               dma_free_coherent(ab->dev, dp->reoq_lut.size,
+                                 dp->reoq_lut.vaddr_unaligned,
+                                 dp->reoq_lut.paddr_unaligned);
+               dp->reoq_lut.vaddr_unaligned = NULL;
        }
 
-       if (dp->ml_reoq_lut.vaddr) {
+       if (dp->ml_reoq_lut.vaddr_unaligned) {
                ath12k_hif_write32(ab,
                                   HAL_SEQ_WCSS_UMAC_REO_REG +
                                   HAL_REO1_QDESC_LUT_BASE1(ab), 0);
-               dma_free_coherent(ab->dev, DP_REOQ_LUT_SIZE,
-                                 dp->ml_reoq_lut.vaddr, dp->ml_reoq_lut.paddr);
-               dp->ml_reoq_lut.vaddr = NULL;
+               dma_free_coherent(ab->dev, dp->ml_reoq_lut.size,
+                                 dp->ml_reoq_lut.vaddr_unaligned,
+                                 dp->ml_reoq_lut.paddr_unaligned);
+               dp->ml_reoq_lut.vaddr_unaligned = NULL;
        }
 }
 
@@ -1608,39 +1610,66 @@ free:
        return ret;
 }
 
+static int ath12k_dp_alloc_reoq_lut(struct ath12k_base *ab,
+                                   struct ath12k_reo_q_addr_lut *lut)
+{
+       lut->size =  DP_REOQ_LUT_SIZE + HAL_REO_QLUT_ADDR_ALIGN - 1;
+       lut->vaddr_unaligned = dma_alloc_coherent(ab->dev, lut->size,
+                                                 &lut->paddr_unaligned,
+                                                 GFP_KERNEL | __GFP_ZERO);
+       if (!lut->vaddr_unaligned)
+               return -ENOMEM;
+
+       lut->vaddr = PTR_ALIGN(lut->vaddr_unaligned, HAL_REO_QLUT_ADDR_ALIGN);
+       lut->paddr = lut->paddr_unaligned +
+                    ((unsigned long)lut->vaddr - (unsigned long)lut->vaddr_unaligned);
+       return 0;
+}
+
 static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab)
 {
        struct ath12k_dp *dp = &ab->dp;
+       u32 val;
+       int ret;
 
        if (!ab->hw_params->reoq_lut_support)
                return 0;
 
-       dp->reoq_lut.vaddr = dma_alloc_coherent(ab->dev,
-                                               DP_REOQ_LUT_SIZE,
-                                               &dp->reoq_lut.paddr,
-                                               GFP_KERNEL | __GFP_ZERO);
-       if (!dp->reoq_lut.vaddr) {
+       ret = ath12k_dp_alloc_reoq_lut(ab, &dp->reoq_lut);
+       if (ret) {
                ath12k_warn(ab, "failed to allocate memory for reoq table");
-               return -ENOMEM;
+               return ret;
        }
 
-       dp->ml_reoq_lut.vaddr = dma_alloc_coherent(ab->dev,
-                                                  DP_REOQ_LUT_SIZE,
-                                                  &dp->ml_reoq_lut.paddr,
-                                                  GFP_KERNEL | __GFP_ZERO);
-       if (!dp->ml_reoq_lut.vaddr) {
+       ret = ath12k_dp_alloc_reoq_lut(ab, &dp->ml_reoq_lut);
+       if (ret) {
                ath12k_warn(ab, "failed to allocate memory for ML reoq table");
-               dma_free_coherent(ab->dev, DP_REOQ_LUT_SIZE,
-                                 dp->reoq_lut.vaddr, dp->reoq_lut.paddr);
-               dp->reoq_lut.vaddr = NULL;
-               return -ENOMEM;
+               dma_free_coherent(ab->dev, dp->reoq_lut.size,
+                                 dp->reoq_lut.vaddr_unaligned,
+                                 dp->reoq_lut.paddr_unaligned);
+               dp->reoq_lut.vaddr_unaligned = NULL;
+               return ret;
        }
 
+       /* Bits in the register have address [39:8] LUT base address to be
+        * allocated such that LSBs are assumed to be zero. Also, current
+        * design supports paddr upto 4 GB max hence it fits in 32 bit register only
+        */
+
        ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE0(ab),
-                          dp->reoq_lut.paddr);
+                          dp->reoq_lut.paddr >> 8);
+
        ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE1(ab),
                           dp->ml_reoq_lut.paddr >> 8);
 
+       val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(ab));
+
+       ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(ab),
+                          val | HAL_REO_QDESC_ADDR_READ_LUT_ENABLE);
+
+       ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_MAX_PEERID(ab),
+                          HAL_REO_QDESC_MAX_PEERID);
+
        return 0;
 }
 
index 427a87b63dec3bb94ae4d4c21a65199254eb7c06..e8dbba0c3bb7d4eae5e260d4ad0db46d08b45177 100644 (file)
@@ -311,8 +311,11 @@ struct ath12k_reo_queue_ref {
 } __packed;
 
 struct ath12k_reo_q_addr_lut {
-       dma_addr_t paddr;
+       u32 *vaddr_unaligned;
        u32 *vaddr;
+       dma_addr_t paddr_unaligned;
+       dma_addr_t paddr;
+       u32 size;
 };
 
 struct ath12k_dp {
index 66603e9c154b9036a8689053955cdbf53a1efe34..81e036f1d70ffd60807494e4516debc87c566257 100644 (file)
@@ -3242,8 +3242,14 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar,
        reo_ent_ring->rx_mpdu_info.peer_meta_data =
                reo_dest_ring->rx_mpdu_info.peer_meta_data;
 
-       reo_ent_ring->queue_addr_lo = cpu_to_le32(lower_32_bits(rx_tid->paddr));
-       queue_addr_hi = upper_32_bits(rx_tid->paddr);
+       if (ab->hw_params->reoq_lut_support) {
+               reo_ent_ring->queue_addr_lo = reo_dest_ring->rx_mpdu_info.peer_meta_data;
+               queue_addr_hi = 0;
+       } else {
+               reo_ent_ring->queue_addr_lo = cpu_to_le32(lower_32_bits(rx_tid->paddr));
+               queue_addr_hi = upper_32_bits(rx_tid->paddr);
+       }
+
        reo_ent_ring->info0 = le32_encode_bits(queue_addr_hi,
                                               HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI) |
                              le32_encode_bits(dst_ind,
index 9f12ed84a653789d52b861063001df34c9b39ebf..76bb095c62e6a7f333a1caee4eaa3ae46fe69db1 100644 (file)
@@ -22,6 +22,7 @@ struct ath12k_base;
 #define HAL_MAX_AVAIL_BLK_RES                  3
 
 #define HAL_RING_BASE_ALIGN    8
+#define HAL_REO_QLUT_ADDR_ALIGN 256
 
 #define HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX      32704
 /* TODO: Check with hw team on the supported scatter buf size */
@@ -40,6 +41,7 @@ struct ath12k_base;
 #define HAL_OFFSET_FROM_HP_TO_TP               4
 
 #define HAL_SHADOW_REG(x) (HAL_SHADOW_BASE_ADDR + (4 * (x)))
+#define HAL_REO_QDESC_MAX_PEERID               8191
 
 /* WCSS Relative address */
 #define HAL_SEQ_WCSS_CMEM_OFFSET               0x00100000
@@ -141,6 +143,8 @@ struct ath12k_base;
 #define HAL_REO1_DEST_RING_CTRL_IX_1           0x00000008
 #define HAL_REO1_DEST_RING_CTRL_IX_2           0x0000000c
 #define HAL_REO1_DEST_RING_CTRL_IX_3           0x00000010
+#define HAL_REO1_QDESC_ADDR(ab)                ((ab)->hw_params->regs->hal_reo1_qdesc_addr)
+#define HAL_REO1_QDESC_MAX_PEERID(ab)  ((ab)->hw_params->regs->hal_reo1_qdesc_max_peerid)
 #define HAL_REO1_SW_COOKIE_CFG0(ab)    ((ab)->hw_params->regs->hal_reo1_sw_cookie_cfg0)
 #define HAL_REO1_SW_COOKIE_CFG1(ab)    ((ab)->hw_params->regs->hal_reo1_sw_cookie_cfg1)
 #define HAL_REO1_QDESC_LUT_BASE0(ab)   ((ab)->hw_params->regs->hal_reo1_qdesc_lut_base0)
@@ -328,6 +332,8 @@ struct ath12k_base;
 #define HAL_REO1_SW_COOKIE_CFG_ALIGN                   BIT(18)
 #define HAL_REO1_SW_COOKIE_CFG_ENABLE                  BIT(19)
 #define HAL_REO1_SW_COOKIE_CFG_GLOBAL_ENABLE           BIT(20)
+#define HAL_REO_QDESC_ADDR_READ_LUT_ENABLE             BIT(7)
+#define HAL_REO_QDESC_ADDR_READ_CLEAR_QDESC_ARRAY      BIT(6)
 
 /* CE ring bit field mask and shift */
 #define HAL_CE_DST_R0_DEST_CTRL_MAX_LEN                        GENMASK(15, 0)
index a041697f6b1a2caa63a61d82cafd192d474f1ae0..c349911c47db27ae58cb557c650c3b0c58a8276f 100644 (file)
@@ -997,6 +997,8 @@ static const struct ath12k_hw_regs qcn9274_v2_regs = {
        .hal_reo1_sw_cookie_cfg1 = 0x00000070,
        .hal_reo1_qdesc_lut_base0 = 0x00000074,
        .hal_reo1_qdesc_lut_base1 = 0x00000078,
+       .hal_reo1_qdesc_addr = 0x0000007c,
+       .hal_reo1_qdesc_max_peerid = 0x00000088,
        .hal_reo1_ring_base_lsb = 0x00000500,
        .hal_reo1_ring_base_msb = 0x00000504,
        .hal_reo1_ring_id = 0x00000508,
index 774679f3340606b74bcda9747961269360183d76..d0218d3eea54f5fdd88ab2a3a689171a00f9d7b2 100644 (file)
@@ -312,6 +312,9 @@ struct ath12k_hw_regs {
 
        u32 hal_tcl_status_ring_base_lsb;
 
+       u32 hal_reo1_qdesc_addr;
+       u32 hal_reo1_qdesc_max_peerid;
+
        u32 hal_wbm_idle_ring_base_lsb;
        u32 hal_wbm_idle_ring_misc_addr;
        u32 hal_wbm_r0_idle_list_cntl_addr;
index 18469ddb7e6508f702080c201ebbe36bd46d5786..d0f3e27c87e317301ce6ad77378f63b89c164c5e 100644 (file)
@@ -3793,7 +3793,8 @@ ath12k_fill_band_to_mac_param(struct ath12k_base  *soc,
 }
 
 static void
-ath12k_wmi_copy_resource_config(struct ath12k_wmi_resource_config_params *wmi_cfg,
+ath12k_wmi_copy_resource_config(struct ath12k_base *ab,
+                               struct ath12k_wmi_resource_config_params *wmi_cfg,
                                struct ath12k_wmi_resource_config_arg *tg_cfg)
 {
        wmi_cfg->num_vdevs = cpu_to_le32(tg_cfg->num_vdevs);
@@ -3860,6 +3861,9 @@ ath12k_wmi_copy_resource_config(struct ath12k_wmi_resource_config_params *wmi_cf
                                           WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION);
        wmi_cfg->host_service_flags = cpu_to_le32(tg_cfg->is_reg_cc_ext_event_supported <<
                                WMI_RSRC_CFG_HOST_SVC_FLAG_REG_CC_EXT_SUPPORT_BIT);
+       if (ab->hw_params->reoq_lut_support)
+               wmi_cfg->host_service_flags |=
+                       cpu_to_le32(1 << WMI_RSRC_CFG_HOST_SVC_FLAG_REO_QREF_SUPPORT_BIT);
        wmi_cfg->ema_max_vap_cnt = cpu_to_le32(tg_cfg->ema_max_vap_cnt);
        wmi_cfg->ema_max_profile_period = cpu_to_le32(tg_cfg->ema_max_profile_period);
        wmi_cfg->flags2 |= cpu_to_le32(WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET);
@@ -3900,7 +3904,7 @@ static int ath12k_init_cmd_send(struct ath12k_wmi_pdev *wmi,
        ptr = skb->data + sizeof(*cmd);
        cfg = ptr;
 
-       ath12k_wmi_copy_resource_config(cfg, &arg->res_cfg);
+       ath12k_wmi_copy_resource_config(ab, cfg, &arg->res_cfg);
 
        cfg->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_RESOURCE_CONFIG,
                                                 sizeof(*cfg));
index 38dabdbfa1bdbbb4a0d7e5f23b04978681c28ae9..80fdbc5665181d77d1ec9590a5e87d8924494fed 100644 (file)
@@ -2461,6 +2461,7 @@ struct wmi_init_cmd {
 } __packed;
 
 #define WMI_RSRC_CFG_HOST_SVC_FLAG_REG_CC_EXT_SUPPORT_BIT 4
+#define WMI_RSRC_CFG_HOST_SVC_FLAG_REO_QREF_SUPPORT_BIT   12
 #define WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION           GENMASK(5, 4)
 #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
 #define WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET      BIT(9)