]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: handle REO CMD ring for QCC2072
authorBaochen Qiang <baochen.qiang@oss.qualcomm.com>
Mon, 12 Jan 2026 07:36:33 +0000 (15:36 +0800)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Fri, 16 Jan 2026 01:19:41 +0000 (17:19 -0800)
As far as REO CMD ring is concerned, there are two differences between
QCC2072 and the existing chips:

For the first, the TLV header of ring descriptor for QCC2072 is 32 bits
while 64 bits for existing chips.

For the second, QCC2072 has different hal_reo_get_queue_stats,
hal_reo_flush_cache and hal_reo_update_rx_queue structures. Take
hal_reo_get_queue_stats as an example:

QCC2072:
struct hal_reo_get_queue_stats_qcc2072 {
        struct hal_reo_cmd_hdr cmd;
        [...]
        __le32 rsvd0[6];
} __packed;

QCN9274/WCN7850:
struct hal_reo_get_queue_stats {
        struct hal_reo_cmd_hdr cmd;
        [...]
        __le32 rsvd0[6];
        __le32 tlv64_pad;
} __packed;

Note there is no tlv64_pad at the end for QCC2072, but all other
former fields share the same layout.

These make different ring entry size, so that parameter has to be updated
with respect to existing chips. This is done in the newly introduced
ath12k_hal_srng_create_config_qcc2072() function, which first creates all
ring configs by utilizing ath12k_hal_srng_create_config_wcn7850() and then
updates the individual field.

Besides, the REO command TLV encoding also need to be corrected because of
the different TLV bits. This is done by introducing a 32 bit variant for
each of the existing 64 bit callback.

Note the hal_reo_get_queue_stats_qcc2072 structure is introduced for the
purpose of calculating ring entry size. Existing hal_reo_get_queue_stats
structure gets used elsewhere even for QCC2072. This is working because
the only difference is the tlv64_pad field that is located at the end and
not getting used, hence can be ignored.

Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3

Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-13-fc8ce1e43969@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/hal.c
drivers/net/wireless/ath/ath12k/hal.h
drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h
drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c
drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h

index bafb49ab5475fc2f68c3cd71028b819c74960726..5ce5e0f89ca885eb50b3a622e884793c4a5e2e6f 100644 (file)
@@ -835,6 +835,17 @@ void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len)
 }
 EXPORT_SYMBOL(ath12k_hal_encode_tlv64_hdr);
 
+void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len)
+{
+       struct hal_tlv_hdr *tlv32 = tlv;
+
+       tlv32->tl = le32_encode_bits(tag, HAL_TLV_HDR_TAG) |
+                   le32_encode_bits(len, HAL_TLV_HDR_LEN);
+
+       return tlv32->value;
+}
+EXPORT_SYMBOL(ath12k_hal_encode_tlv32_hdr);
+
 u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc)
 {
        struct hal_tlv_64_hdr *tlv64 = tlv;
index 94ecc035fc493125fc51d4ff53ba5a0fe782ab0a..f322000e8ac9f3cd0667a969d87f3aac5f8fb48e 100644 (file)
@@ -1544,5 +1544,6 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc,
                                         struct ath12k_buffer_addr **pp_buf_addr,
                                         u8 *rbm, u32 *msdu_cnt);
 void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len);
+void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len);
 u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc);
 #endif
index cdcf24b1d6eba32fb0bfb6c9d7a11a97892598d8..c4c7ca9ee827ac1e584049c7616eb85f19b257e9 100644 (file)
@@ -1049,6 +1049,13 @@ struct hal_reo_get_queue_stats {
  *             Hole_count
  */
 
+struct hal_reo_get_queue_stats_qcc2072 {
+       struct hal_reo_cmd_hdr cmd;
+       __le32 queue_addr_lo;
+       __le32 info0;
+       __le32 rsvd0[6];
+} __packed;
+
 #define HAL_REO_FLUSH_QUEUE_INFO0_DESC_ADDR_HI         GENMASK(7, 0)
 #define HAL_REO_FLUSH_QUEUE_INFO0_BLOCK_DESC_ADDR      BIT(8)
 #define HAL_REO_FLUSH_QUEUE_INFO0_BLOCK_RESRC_IDX      GENMASK(10, 9)
index 522b94b04f9f40578473a6ccdb649517f3f9e6f1..0ae5b073287aba42b14214662af437941e2da795 100644 (file)
@@ -412,8 +412,24 @@ static void ath12k_hal_extract_rx_desc_data_qcc2072(struct hal_rx_desc_data *rx_
        rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcc2072(rx_desc);
 }
 
+static int ath12k_hal_srng_create_config_qcc2072(struct ath12k_hal *hal)
+{
+       struct hal_srng_config *s;
+       int ret;
+
+       ret = ath12k_hal_srng_create_config_wcn7850(hal);
+       if (ret)
+               return ret;
+
+       s = &hal->srng_config[HAL_REO_CMD];
+       s->entry_size = (sizeof(struct hal_tlv_hdr) +
+                        sizeof(struct hal_reo_get_queue_stats_qcc2072)) >> 2;
+
+       return 0;
+}
+
 const struct hal_ops hal_qcc2072_ops = {
-       .create_srng_config = ath12k_hal_srng_create_config_wcn7850,
+       .create_srng_config = ath12k_hal_srng_create_config_qcc2072,
        .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcc2072,
        .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcc2072,
        .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcc2072,
@@ -443,7 +459,7 @@ const struct hal_ops hal_qcc2072_ops = {
        .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr,
        .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr,
        .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list,
-       .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64,
+       .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv32,
        .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup,
        .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set,
        .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get,
@@ -451,7 +467,7 @@ const struct hal_ops hal_qcc2072_ops = {
        .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm,
        .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get,
        .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get,
-       .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr,
+       .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv32_hdr,
        .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr,
 };
 
index a88ef126aadaba8aeadb71f380561f7613706def..49c69328970941f0076648f38d6e14e08d58a796 100644 (file)
@@ -890,6 +890,31 @@ void ath12k_wifi7_hal_reo_init_cmd_ring_tlv64(struct ath12k_base *ab,
        }
 }
 
+void ath12k_wifi7_hal_reo_init_cmd_ring_tlv32(struct ath12k_base *ab,
+                                             struct hal_srng *srng)
+{
+       struct hal_reo_get_queue_stats *desc;
+       struct hal_srng_params params;
+       struct hal_tlv_hdr *tlv;
+       int i, cmd_num = 1;
+       int entry_size;
+       u8 *entry;
+
+       memset(&params, 0, sizeof(params));
+
+       entry_size = ath12k_hal_srng_get_entrysize(ab, HAL_REO_CMD);
+       ath12k_hal_srng_get_params(ab, srng, &params);
+       entry = (u8 *)params.ring_base_vaddr;
+
+       for (i = 0; i < params.num_entries; i++) {
+               tlv = (struct hal_tlv_hdr *)entry;
+               desc = (struct hal_reo_get_queue_stats *)tlv->value;
+               desc->cmd.info0 = le32_encode_bits(cmd_num++,
+                                                  HAL_REO_CMD_HDR_INFO0_CMD_NUMBER);
+               entry += entry_size;
+       }
+}
+
 void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map)
 {
        struct ath12k_hal *hal = &ab->hal;
index 95f5595b30ad125f7788e32bc415faee41012a97..ac2a8ac03288f10fd03da500fde7745cef90bea1 100644 (file)
@@ -864,6 +864,8 @@ void ath12k_wifi7_hal_rx_msdu_list_get(struct ath12k *ar,
                                       u16 *num_msdus);
 void ath12k_wifi7_hal_reo_init_cmd_ring_tlv64(struct ath12k_base *ab,
                                              struct hal_srng *srng);
+void ath12k_wifi7_hal_reo_init_cmd_ring_tlv32(struct ath12k_base *ab,
+                                             struct hal_srng *srng);
 void ath12k_wifi7_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab);
 void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map);
 void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc,