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>
}
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;
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
* 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)
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,
.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,
.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,
};
}
}
+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(¶ms, 0, sizeof(params));
+
+ entry_size = ath12k_hal_srng_get_entrysize(ab, HAL_REO_CMD);
+ ath12k_hal_srng_get_params(ab, srng, ¶ms);
+ 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;
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,