// 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. */ #include #include #include #include "debug.h" #include "core.h" #include "ce.h" #include "hw.h" #include "mhi.h" #include "dp_rx.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, 0xac, 0x12, 0x00, 0x03); static u8 ath12k_hw_qcn9274_mac_from_pdev_id(int pdev_idx) { return pdev_idx; } static int ath12k_hw_mac_id_to_pdev_id_qcn9274(const struct ath12k_hw_params *hw, int mac_id) { return mac_id; } static int ath12k_hw_mac_id_to_srng_id_qcn9274(const struct ath12k_hw_params *hw, int mac_id) { return 0; } static u8 ath12k_hw_get_ring_selector_qcn9274(struct sk_buff *skb) { return smp_processor_id(); } static bool ath12k_dp_srng_is_comp_ring_qcn9274(int ring_num) { if (ring_num < 3 || ring_num == 4) return true; return false; } static int ath12k_hw_mac_id_to_pdev_id_wcn7850(const struct ath12k_hw_params *hw, int mac_id) { return 0; } static int ath12k_hw_mac_id_to_srng_id_wcn7850(const struct ath12k_hw_params *hw, int mac_id) { return mac_id; } static u8 ath12k_hw_get_ring_selector_wcn7850(struct sk_buff *skb) { return skb_get_queue_mapping(skb); } static bool ath12k_dp_srng_is_comp_ring_wcn7850(int ring_num) { if (ring_num == 0 || ring_num == 2 || ring_num == 4) return true; return false; } static const struct ath12k_hw_ops qcn9274_ops = { .get_hw_mac_from_pdev_id = ath12k_hw_qcn9274_mac_from_pdev_id, .mac_id_to_pdev_id = ath12k_hw_mac_id_to_pdev_id_qcn9274, .mac_id_to_srng_id = ath12k_hw_mac_id_to_srng_id_qcn9274, .rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_qcn9274, .get_ring_selector = ath12k_hw_get_ring_selector_qcn9274, .dp_srng_is_tx_comp_ring = ath12k_dp_srng_is_comp_ring_qcn9274, }; static const struct ath12k_hw_ops wcn7850_ops = { .get_hw_mac_from_pdev_id = ath12k_hw_qcn9274_mac_from_pdev_id, .mac_id_to_pdev_id = ath12k_hw_mac_id_to_pdev_id_wcn7850, .mac_id_to_srng_id = ath12k_hw_mac_id_to_srng_id_wcn7850, .rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_wcn7850, .get_ring_selector = ath12k_hw_get_ring_selector_wcn7850, .dp_srng_is_tx_comp_ring = ath12k_dp_srng_is_comp_ring_wcn7850, }; #define ATH12K_TX_RING_MASK_0 0x1 #define ATH12K_TX_RING_MASK_1 0x2 #define ATH12K_TX_RING_MASK_2 0x4 #define ATH12K_TX_RING_MASK_3 0x8 #define ATH12K_TX_RING_MASK_4 0x10 #define ATH12K_RX_RING_MASK_0 0x1 #define ATH12K_RX_RING_MASK_1 0x2 #define ATH12K_RX_RING_MASK_2 0x4 #define ATH12K_RX_RING_MASK_3 0x8 #define ATH12K_RX_ERR_RING_MASK_0 0x1 #define ATH12K_RX_WBM_REL_RING_MASK_0 0x1 #define ATH12K_REO_STATUS_RING_MASK_0 0x1 #define ATH12K_HOST2RXDMA_RING_MASK_0 0x1 #define ATH12K_RX_MON_RING_MASK_0 0x1 #define ATH12K_RX_MON_RING_MASK_1 0x2 #define ATH12K_RX_MON_RING_MASK_2 0x4 #define ATH12K_TX_MON_RING_MASK_0 0x1 #define ATH12K_TX_MON_RING_MASK_1 0x2 /* 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 */ { .pipenum = __cpu_to_le32(0), .pipedir = __cpu_to_le32(PIPEDIR_OUT), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE1: target->host HTT + HTC control */ { .pipenum = __cpu_to_le32(1), .pipedir = __cpu_to_le32(PIPEDIR_IN), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE2: target->host WMI */ { .pipenum = __cpu_to_le32(2), .pipedir = __cpu_to_le32(PIPEDIR_IN), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE3: host->target WMI (mac0) */ { .pipenum = __cpu_to_le32(3), .pipedir = __cpu_to_le32(PIPEDIR_OUT), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE4: host->target HTT */ { .pipenum = __cpu_to_le32(4), .pipedir = __cpu_to_le32(PIPEDIR_OUT), .nentries = __cpu_to_le32(256), .nbytes_max = __cpu_to_le32(256), .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), .reserved = __cpu_to_le32(0), }, /* CE5: target->host Pktlog */ { .pipenum = __cpu_to_le32(5), .pipedir = __cpu_to_le32(PIPEDIR_IN), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE6: Reserved for target autonomous hif_memcpy */ { .pipenum = __cpu_to_le32(6), .pipedir = __cpu_to_le32(PIPEDIR_INOUT), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(16384), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE7: host->target WMI (mac1) */ { .pipenum = __cpu_to_le32(7), .pipedir = __cpu_to_le32(PIPEDIR_OUT), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE8: Reserved for target autonomous hif_memcpy */ { .pipenum = __cpu_to_le32(8), .pipedir = __cpu_to_le32(PIPEDIR_INOUT), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(16384), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE9, 10 and 11: Reserved for MHI */ /* CE12: Target CV prefetch */ { .pipenum = __cpu_to_le32(12), .pipedir = __cpu_to_le32(PIPEDIR_OUT), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE13: Target CV prefetch */ { .pipenum = __cpu_to_le32(13), .pipedir = __cpu_to_le32(PIPEDIR_OUT), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE14: WMI logging/CFR/Spectral/Radar */ { .pipenum = __cpu_to_le32(14), .pipedir = __cpu_to_le32(PIPEDIR_IN), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE15: Reserved */ }; /* Target firmware's Copy Engine configuration. */ static const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[] = { /* CE0: host->target HTC control and raw streams */ { .pipenum = __cpu_to_le32(0), .pipedir = __cpu_to_le32(PIPEDIR_OUT), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE1: target->host HTT + HTC control */ { .pipenum = __cpu_to_le32(1), .pipedir = __cpu_to_le32(PIPEDIR_IN), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE2: target->host WMI */ { .pipenum = __cpu_to_le32(2), .pipedir = __cpu_to_le32(PIPEDIR_IN), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE3: host->target WMI */ { .pipenum = __cpu_to_le32(3), .pipedir = __cpu_to_le32(PIPEDIR_OUT), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE4: host->target HTT */ { .pipenum = __cpu_to_le32(4), .pipedir = __cpu_to_le32(PIPEDIR_OUT), .nentries = __cpu_to_le32(256), .nbytes_max = __cpu_to_le32(256), .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), .reserved = __cpu_to_le32(0), }, /* CE5: target->host Pktlog */ { .pipenum = __cpu_to_le32(5), .pipedir = __cpu_to_le32(PIPEDIR_IN), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE6: Reserved for target autonomous hif_memcpy */ { .pipenum = __cpu_to_le32(6), .pipedir = __cpu_to_le32(PIPEDIR_INOUT), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(16384), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE7 used only by Host */ { .pipenum = __cpu_to_le32(7), .pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H), .nentries = __cpu_to_le32(0), .nbytes_max = __cpu_to_le32(0), .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), .reserved = __cpu_to_le32(0), }, /* CE8 target->host used only by IPA */ { .pipenum = __cpu_to_le32(8), .pipedir = __cpu_to_le32(PIPEDIR_INOUT), .nentries = __cpu_to_le32(32), .nbytes_max = __cpu_to_le32(16384), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, /* CE 9, 10, 11 are used by MHI driver */ }; /* Map from service/endpoint to Copy Engine. * This table is derived from the CE_PCI TABLE, above. * It is passed to the Target at startup for use by firmware. */ static const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[] = { { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(3), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(2), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(3), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(2), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(3), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(2), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(3), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(2), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(3), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(2), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(0), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(1), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(0), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(1), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(4), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(1), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_MAC1), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(7), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_MAC1), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(2), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_PKT_LOG), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(5), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_DIAG), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(14), }, /* (Additions here) */ { /* must be last */ __cpu_to_le32(0), __cpu_to_le32(0), __cpu_to_le32(0), }, }; static const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[] = { { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(3), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(2), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(3), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(2), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(3), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(2), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(3), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(2), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(3), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(2), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(0), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(2), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ __cpu_to_le32(4), }, { __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ __cpu_to_le32(1), }, /* (Additions here) */ { /* must be last */ __cpu_to_le32(0), __cpu_to_le32(0), __cpu_to_le32(0), }, }; static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9274 = { .tx = { ATH12K_TX_RING_MASK_0, ATH12K_TX_RING_MASK_1, ATH12K_TX_RING_MASK_2, ATH12K_TX_RING_MASK_3, }, .rx_mon_dest = { 0, 0, 0, }, .rx = { 0, 0, 0, 0, ATH12K_RX_RING_MASK_0, ATH12K_RX_RING_MASK_1, ATH12K_RX_RING_MASK_2, ATH12K_RX_RING_MASK_3, }, .rx_err = { 0, 0, 0, ATH12K_RX_ERR_RING_MASK_0, }, .rx_wbm_rel = { 0, 0, 0, ATH12K_RX_WBM_REL_RING_MASK_0, }, .reo_status = { 0, 0, 0, ATH12K_REO_STATUS_RING_MASK_0, }, .host2rxdma = { 0, 0, 0, ATH12K_HOST2RXDMA_RING_MASK_0, }, .tx_mon_dest = { 0, 0, 0, }, }; static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn7850 = { .tx = { ATH12K_TX_RING_MASK_0, ATH12K_TX_RING_MASK_1, ATH12K_TX_RING_MASK_2, }, .rx_mon_dest = { }, .rx = { 0, 0, 0, ATH12K_RX_RING_MASK_0, ATH12K_RX_RING_MASK_1, ATH12K_RX_RING_MASK_2, ATH12K_RX_RING_MASK_3, }, .rx_err = { ATH12K_RX_ERR_RING_MASK_0, }, .rx_wbm_rel = { ATH12K_RX_WBM_REL_RING_MASK_0, }, .reo_status = { ATH12K_REO_STATUS_RING_MASK_0, }, .host2rxdma = { }, .tx_mon_dest = { }, }; static const struct ath12k_hw_regs qcn9274_v1_regs = { /* SW2TCL(x) R0 ring configuration address */ .hal_tcl1_ring_id = 0x00000908, .hal_tcl1_ring_misc = 0x00000910, .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, .hal_tcl1_ring_tp_addr_msb = 0x00000920, .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, .hal_tcl1_ring_msi1_base_lsb = 0x00000948, .hal_tcl1_ring_msi1_base_msb = 0x0000094c, .hal_tcl1_ring_msi1_data = 0x00000950, .hal_tcl_ring_base_lsb = 0x00000b58, /* TCL STATUS ring address */ .hal_tcl_status_ring_base_lsb = 0x00000d38, .hal_wbm_idle_ring_base_lsb = 0x00000d0c, .hal_wbm_idle_ring_misc_addr = 0x00000d1c, .hal_wbm_r0_idle_list_cntl_addr = 0x00000210, .hal_wbm_r0_idle_list_size_addr = 0x00000214, .hal_wbm_scattered_ring_base_lsb = 0x00000220, .hal_wbm_scattered_ring_base_msb = 0x00000224, .hal_wbm_scattered_desc_head_info_ix0 = 0x00000230, .hal_wbm_scattered_desc_head_info_ix1 = 0x00000234, .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000240, .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000244, .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000024c, .hal_wbm_sw_release_ring_base_lsb = 0x0000034c, .hal_wbm_sw1_release_ring_base_lsb = 0x000003c4, .hal_wbm0_release_ring_base_lsb = 0x00000dd8, .hal_wbm1_release_ring_base_lsb = 0x00000e50, /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, /* PPE release ring address */ .hal_ppe_rel_ring_base = 0x0000043c, /* REO DEST ring address */ .hal_reo2_ring_base = 0x0000055c, .hal_reo1_misc_ctrl_addr = 0x00000b7c, .hal_reo1_sw_cookie_cfg0 = 0x00000050, .hal_reo1_sw_cookie_cfg1 = 0x00000054, .hal_reo1_qdesc_lut_base0 = 0x00000058, .hal_reo1_qdesc_lut_base1 = 0x0000005c, .hal_reo1_ring_base_lsb = 0x000004e4, .hal_reo1_ring_base_msb = 0x000004e8, .hal_reo1_ring_id = 0x000004ec, .hal_reo1_ring_misc = 0x000004f4, .hal_reo1_ring_hp_addr_lsb = 0x000004f8, .hal_reo1_ring_hp_addr_msb = 0x000004fc, .hal_reo1_ring_producer_int_setup = 0x00000508, .hal_reo1_ring_msi1_base_lsb = 0x0000052C, .hal_reo1_ring_msi1_base_msb = 0x00000530, .hal_reo1_ring_msi1_data = 0x00000534, .hal_reo1_aging_thres_ix0 = 0x00000b08, .hal_reo1_aging_thres_ix1 = 0x00000b0c, .hal_reo1_aging_thres_ix2 = 0x00000b10, .hal_reo1_aging_thres_ix3 = 0x00000b14, /* REO Exception ring address */ .hal_reo2_sw0_ring_base = 0x000008a4, /* REO Reinject ring address */ .hal_sw2reo_ring_base = 0x00000304, .hal_sw2reo1_ring_base = 0x0000037c, /* REO cmd ring address */ .hal_reo_cmd_ring_base = 0x0000028c, /* REO status ring address */ .hal_reo_status_ring_base = 0x00000a84, }; static const struct ath12k_hw_regs qcn9274_v2_regs = { /* SW2TCL(x) R0 ring configuration address */ .hal_tcl1_ring_id = 0x00000908, .hal_tcl1_ring_misc = 0x00000910, .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, .hal_tcl1_ring_tp_addr_msb = 0x00000920, .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, .hal_tcl1_ring_msi1_base_lsb = 0x00000948, .hal_tcl1_ring_msi1_base_msb = 0x0000094c, .hal_tcl1_ring_msi1_data = 0x00000950, .hal_tcl_ring_base_lsb = 0x00000b58, /* TCL STATUS ring address */ .hal_tcl_status_ring_base_lsb = 0x00000d38, /* WBM idle link ring address */ .hal_wbm_idle_ring_base_lsb = 0x00000d3c, .hal_wbm_idle_ring_misc_addr = 0x00000d4c, .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, .hal_wbm_r0_idle_list_size_addr = 0x00000244, .hal_wbm_scattered_ring_base_lsb = 0x00000250, .hal_wbm_scattered_ring_base_msb = 0x00000254, .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, /* SW2WBM release ring address */ .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, .hal_wbm_sw1_release_ring_base_lsb = 0x000003f4, /* WBM2SW release ring address */ .hal_wbm0_release_ring_base_lsb = 0x00000e08, .hal_wbm1_release_ring_base_lsb = 0x00000e80, /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, /* PPE release ring address */ .hal_ppe_rel_ring_base = 0x0000046c, /* REO DEST ring address */ .hal_reo2_ring_base = 0x00000578, .hal_reo1_misc_ctrl_addr = 0x00000b9c, .hal_reo1_sw_cookie_cfg0 = 0x0000006c, .hal_reo1_sw_cookie_cfg1 = 0x00000070, .hal_reo1_qdesc_lut_base0 = 0x00000074, .hal_reo1_qdesc_lut_base1 = 0x00000078, .hal_reo1_ring_base_lsb = 0x00000500, .hal_reo1_ring_base_msb = 0x00000504, .hal_reo1_ring_id = 0x00000508, .hal_reo1_ring_misc = 0x00000510, .hal_reo1_ring_hp_addr_lsb = 0x00000514, .hal_reo1_ring_hp_addr_msb = 0x00000518, .hal_reo1_ring_producer_int_setup = 0x00000524, .hal_reo1_ring_msi1_base_lsb = 0x00000548, .hal_reo1_ring_msi1_base_msb = 0x0000054C, .hal_reo1_ring_msi1_data = 0x00000550, .hal_reo1_aging_thres_ix0 = 0x00000B28, .hal_reo1_aging_thres_ix1 = 0x00000B2C, .hal_reo1_aging_thres_ix2 = 0x00000B30, .hal_reo1_aging_thres_ix3 = 0x00000B34, /* REO Exception ring address */ .hal_reo2_sw0_ring_base = 0x000008c0, /* REO Reinject ring address */ .hal_sw2reo_ring_base = 0x00000320, .hal_sw2reo1_ring_base = 0x00000398, /* REO cmd ring address */ .hal_reo_cmd_ring_base = 0x000002A8, /* REO status ring address */ .hal_reo_status_ring_base = 0x00000aa0, }; static const struct ath12k_hw_regs wcn7850_regs = { /* SW2TCL(x) R0 ring configuration address */ .hal_tcl1_ring_id = 0x00000908, .hal_tcl1_ring_misc = 0x00000910, .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, .hal_tcl1_ring_tp_addr_msb = 0x00000920, .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, .hal_tcl1_ring_msi1_base_lsb = 0x00000948, .hal_tcl1_ring_msi1_base_msb = 0x0000094c, .hal_tcl1_ring_msi1_data = 0x00000950, .hal_tcl_ring_base_lsb = 0x00000b58, /* TCL STATUS ring address */ .hal_tcl_status_ring_base_lsb = 0x00000d38, .hal_wbm_idle_ring_base_lsb = 0x00000d3c, .hal_wbm_idle_ring_misc_addr = 0x00000d4c, .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, .hal_wbm_r0_idle_list_size_addr = 0x00000244, .hal_wbm_scattered_ring_base_lsb = 0x00000250, .hal_wbm_scattered_ring_base_msb = 0x00000254, .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, .hal_wbm_scattered_desc_ptr_hp_addr = 0x00000027c, .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, .hal_wbm_sw1_release_ring_base_lsb = 0x00000284, .hal_wbm0_release_ring_base_lsb = 0x00000e08, .hal_wbm1_release_ring_base_lsb = 0x00000e80, /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0e0a8, .pcie_pcs_osc_dtct_config_base = 0x01e0f45c, /* PPE release ring address */ .hal_ppe_rel_ring_base = 0x0000043c, /* REO DEST ring address */ .hal_reo2_ring_base = 0x0000055c, .hal_reo1_misc_ctrl_addr = 0x00000b7c, .hal_reo1_sw_cookie_cfg0 = 0x00000050, .hal_reo1_sw_cookie_cfg1 = 0x00000054, .hal_reo1_qdesc_lut_base0 = 0x00000058, .hal_reo1_qdesc_lut_base1 = 0x0000005c, .hal_reo1_ring_base_lsb = 0x000004e4, .hal_reo1_ring_base_msb = 0x000004e8, .hal_reo1_ring_id = 0x000004ec, .hal_reo1_ring_misc = 0x000004f4, .hal_reo1_ring_hp_addr_lsb = 0x000004f8, .hal_reo1_ring_hp_addr_msb = 0x000004fc, .hal_reo1_ring_producer_int_setup = 0x00000508, .hal_reo1_ring_msi1_base_lsb = 0x0000052C, .hal_reo1_ring_msi1_base_msb = 0x00000530, .hal_reo1_ring_msi1_data = 0x00000534, .hal_reo1_aging_thres_ix0 = 0x00000b08, .hal_reo1_aging_thres_ix1 = 0x00000b0c, .hal_reo1_aging_thres_ix2 = 0x00000b10, .hal_reo1_aging_thres_ix3 = 0x00000b14, /* REO Exception ring address */ .hal_reo2_sw0_ring_base = 0x000008a4, /* REO Reinject ring address */ .hal_sw2reo_ring_base = 0x00000304, .hal_sw2reo1_ring_base = 0x0000037c, /* REO cmd ring address */ .hal_reo_cmd_ring_base = 0x0000028c, /* REO status ring address */ .hal_reo_status_ring_base = 0x00000a84, }; static const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274 = { .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, }; static const struct ath12k_hw_hal_params ath12k_hw_hal_params_wcn7850 = { .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, }; static const struct ath12k_hw_params ath12k_hw_params[] = { { .name = "qcn9274 hw1.0", .hw_rev = ATH12K_HW_QCN9274_HW10, .fw = { .dir = "QCN9274/hw1.0", .board_size = 256 * 1024, .cal_offset = 128 * 1024, }, .max_radios = 1, .single_pdev_only = false, .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9274, .internal_sleep_clock = false, .hw_ops = &qcn9274_ops, .ring_mask = &ath12k_hw_ring_mask_qcn9274, .regs = &qcn9274_v1_regs, .host_ce_config = ath12k_host_ce_config_qcn9274, .ce_count = 16, .target_ce_config = ath12k_target_ce_config_wlan_qcn9274, .target_ce_count = 12, .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_qcn9274, .svc_to_ce_map_len = 18, .hal_params = &ath12k_hw_hal_params_qcn9274, .rxdma1_enable = false, .num_rxdma_per_pdev = 1, .num_rxdma_dst_ring = 0, .rx_mac_buf_ring = false, .vdev_start_delay = false, .interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MESH_POINT) | BIT(NL80211_IFTYPE_AP_VLAN), .supports_monitor = false, .idle_ps = false, .download_calib = true, .supports_suspend = false, .tcl_ring_retry = true, .reoq_lut_support = false, .supports_shadow_regs = false, .num_tcl_banks = 48, .max_tx_ring = 4, .mhi_config = &ath12k_mhi_config_qcn9274, .wmi_init = ath12k_wmi_init_qcn9274, .hal_ops = &hal_qcn9274_ops, .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01), .rfkill_pin = 0, .rfkill_cfg = 0, .rfkill_on_level = 0, .rddm_size = 0, .def_num_link = 0, .max_mlo_peer = 256, .otp_board_id_register = QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB, .supports_sta_ps = false, .acpi_guid = NULL, .supports_dynamic_smps_6ghz = true, .iova_mask = 0, .supports_aspm = false, }, { .name = "wcn7850 hw2.0", .hw_rev = ATH12K_HW_WCN7850_HW20, .fw = { .dir = "WCN7850/hw2.0", .board_size = 256 * 1024, .cal_offset = 256 * 1024, }, .max_radios = 1, .single_pdev_only = true, .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850, .internal_sleep_clock = true, .hw_ops = &wcn7850_ops, .ring_mask = &ath12k_hw_ring_mask_wcn7850, .regs = &wcn7850_regs, .host_ce_config = ath12k_host_ce_config_wcn7850, .ce_count = 9, .target_ce_config = ath12k_target_ce_config_wlan_wcn7850, .target_ce_count = 9, .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_wcn7850, .svc_to_ce_map_len = 14, .hal_params = &ath12k_hw_hal_params_wcn7850, .rxdma1_enable = false, .num_rxdma_per_pdev = 2, .num_rxdma_dst_ring = 1, .rx_mac_buf_ring = true, .vdev_start_delay = true, .interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_DEVICE) | BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO), .supports_monitor = false, .idle_ps = true, .download_calib = false, .supports_suspend = true, .tcl_ring_retry = false, .reoq_lut_support = false, .supports_shadow_regs = true, .num_tcl_banks = 7, .max_tx_ring = 3, .mhi_config = &ath12k_mhi_config_wcn7850, .wmi_init = ath12k_wmi_init_wcn7850, .hal_ops = &hal_wcn7850_ops, .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) | BIT(CNSS_PCIE_PERST_NO_PULL_V01), .rfkill_pin = 48, .rfkill_cfg = 0, .rfkill_on_level = 1, .rddm_size = 0x780000, .def_num_link = 2, .max_mlo_peer = 32, .otp_board_id_register = 0, .supports_sta_ps = true, .acpi_guid = &wcn7850_uuid, .supports_dynamic_smps_6ghz = false, .iova_mask = ATH12K_PCIE_MAX_PAYLOAD_SIZE - 1, .supports_aspm = true, }, { .name = "qcn9274 hw2.0", .hw_rev = ATH12K_HW_QCN9274_HW20, .fw = { .dir = "QCN9274/hw2.0", .board_size = 256 * 1024, .cal_offset = 128 * 1024, }, .max_radios = 2, .single_pdev_only = false, .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9274, .internal_sleep_clock = false, .hw_ops = &qcn9274_ops, .ring_mask = &ath12k_hw_ring_mask_qcn9274, .regs = &qcn9274_v2_regs, .host_ce_config = ath12k_host_ce_config_qcn9274, .ce_count = 16, .target_ce_config = ath12k_target_ce_config_wlan_qcn9274, .target_ce_count = 12, .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_qcn9274, .svc_to_ce_map_len = 18, .hal_params = &ath12k_hw_hal_params_qcn9274, .rxdma1_enable = false, .num_rxdma_per_pdev = 1, .num_rxdma_dst_ring = 0, .rx_mac_buf_ring = false, .vdev_start_delay = false, .interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MESH_POINT) | BIT(NL80211_IFTYPE_AP_VLAN), .supports_monitor = false, .idle_ps = false, .download_calib = true, .supports_suspend = false, .tcl_ring_retry = true, .reoq_lut_support = false, .supports_shadow_regs = false, .num_tcl_banks = 48, .max_tx_ring = 4, .mhi_config = &ath12k_mhi_config_qcn9274, .wmi_init = ath12k_wmi_init_qcn9274, .hal_ops = &hal_qcn9274_ops, .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01), .rfkill_pin = 0, .rfkill_cfg = 0, .rfkill_on_level = 0, .rddm_size = 0, .def_num_link = 0, .max_mlo_peer = 256, .otp_board_id_register = QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB, .supports_sta_ps = false, .acpi_guid = NULL, .supports_dynamic_smps_6ghz = true, .iova_mask = 0, .supports_aspm = false, }, }; int ath12k_hw_init(struct ath12k_base *ab) { const struct ath12k_hw_params *hw_params = NULL; int i; for (i = 0; i < ARRAY_SIZE(ath12k_hw_params); i++) { hw_params = &ath12k_hw_params[i]; if (hw_params->hw_rev == ab->hw_rev) break; } if (i == ARRAY_SIZE(ath12k_hw_params)) { ath12k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev); return -EINVAL; } ab->hw_params = hw_params; ath12k_info(ab, "Hardware name: %s\n", ab->hw_params->name); return 0; }