diff --git a/package/kernel/mac80211/patches/ath11k/921-wifi-ath11k-update-hw-params-for-QCN6122.patch b/package/kernel/mac80211/patches/ath11k/921-wifi-ath11k-update-hw-params-for-QCN6122.patch new file mode 100644 index 0000000000..2c97c97f31 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/921-wifi-ath11k-update-hw-params-for-QCN6122.patch @@ -0,0 +1,115 @@ +From: Sowmiya Sree Elavalagan +Date: Tue, 22 Dec 2020 20:08:37 +0530 +Subject: [PATCH 1/2] ath11k: qcn6122 bring up + +Add qcn6122 platform support. +qcn6122 is a hybrid bus type device which is enumerated as +pci device by Q6 and enumerates as ahb device on host. +It uses qgic interrupts to notify events to host driver. +Used qgic api to convert MSI interrupt to qgic interrupt. +Added qmi message to learn bar address from qcn6122. +Test performed: +Ran ping test for open, ccmp and tkip modes. +Ran iperf traffic for few mins. + +Signed-off-by: Sowmiya Sree Elavalagan + +Download from https://git.codelinaro.org/clo/qsdk/oss/system/feeds/wlan-open/-/blob/NHSS.QSDK.12.4.5.r2/mac80211/patches/232-ath11k-qcn6122-support.patch + +Signed-off-by: George Moussalem +--- + +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -809,6 +809,66 @@ static struct ath11k_hw_params ath11k_hw + .support_fw_mac_sequence = true, + .support_dual_stations = true, + }, ++ { ++ .hw_rev = ATH11K_HW_QCN6122_HW10, ++ .name = "qcn6122 hw1.0", ++ .fw = { ++ .dir = "qcn6122/hw1.0", ++ .board_size = 256 * 1024, ++ .cal_offset = 128 * 1024, ++ }, ++ .hal_params = &ath11k_hw_hal_params_ipq8074, ++ .max_radios = MAX_RADIOS_5018, ++ .bdf_addr = 0x4D200000, ++ .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), ++ .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN6122, ++ .interface_modes = BIT(NL80211_IFTYPE_STATION) | ++ BIT(NL80211_IFTYPE_AP) | ++ BIT(NL80211_IFTYPE_MESH_POINT), ++ .spectral = { ++ .fft_sz = 2, ++ .fft_pad_sz = 0, ++ .summary_pad_sz = 16, ++ .fft_hdr_len = 24, ++ .max_fft_bins = 1024, ++ }, ++ .credit_flow = false, ++ .max_tx_ring = 1, ++ .supports_monitor = true, ++ .supports_shadow_regs = false, ++ .idle_ps = false, ++ .supports_suspend = false, ++ .host_ce_config = ath11k_host_ce_config_qcn9074, ++ .ce_count = CE_CNT_5018, ++ .target_ce_config = ath11k_target_ce_config_wlan_ipq5018, ++ .target_ce_count = TARGET_CE_CNT_5018, ++ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq5018, ++ .svc_to_ce_map_len = SVC_CE_MAP_LEN_5018, ++ .single_pdev_only = false, ++ .rxdma1_enable = true, ++ .num_rxmda_per_pdev = RXDMA_PER_PDEV_5018, ++ .rx_mac_buf_ring = false, ++ .vdev_start_delay = false, ++ .htt_peer_map_v2 = true, ++ .coldboot_cal_mm = true, ++ .coldboot_cal_ftm = true, ++ .cbcal_restart_fw = true, ++ .fix_l1ss = true, ++ .alloc_cacheable_memory = true, ++ .m3_fw_support = false, ++ .fixed_bdf_addr = true, ++ .fixed_mem_region = true, ++ .static_window_map = true, ++ .hybrid_bus_type = false, ++ .fw_mem_mode = 1, ++ .supports_sta_ps = false, ++ .dbr_debug_support = true, ++ .bios_sar_capa = NULL, ++ .fixed_fw_mem = false, ++ .support_off_channel_tx = false, ++ .tcl_ring_retry = true, ++ .tx_ring_size = DP_TCL_DATA_RING_SIZE, ++ }, + }; + + static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab) +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -148,6 +148,7 @@ enum ath11k_hw_rev { + ATH11K_HW_WCN6750_HW10, + ATH11K_HW_IPQ5018_HW10, + ATH11K_HW_QCA2066_HW21, ++ ATH11K_HW_QCN6122_HW10, + }; + + enum ath11k_firmware_mode { +--- a/drivers/net/wireless/ath/ath11k/qmi.h ++++ b/drivers/net/wireless/ath/ath11k/qmi.h +@@ -22,10 +22,11 @@ + #define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074 0x02 + #define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074 0x07 + #define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750 0x03 ++#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN6122 0x40 + #define ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 32 + #define ATH11K_QMI_RESP_LEN_MAX 8192 + #define ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01 52 +-#define ATH11K_QMI_CALDB_SIZE 0x480000 ++#define ATH11K_QMI_CALDB_SIZE 0x500000 + #define ATH11K_QMI_BDF_EXT_STR_LENGTH 0x20 + #define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT 5 + diff --git a/package/kernel/mac80211/patches/ath11k/922-wifi-ath11k-update-hal-srng-regs-for-QCN6122.patch b/package/kernel/mac80211/patches/ath11k/922-wifi-ath11k-update-hal-srng-regs-for-QCN6122.patch new file mode 100644 index 0000000000..768c960a5b --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/922-wifi-ath11k-update-hal-srng-regs-for-QCN6122.patch @@ -0,0 +1,104 @@ +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -821,6 +821,7 @@ static struct ath11k_hw_params ath11k_hw + .max_radios = MAX_RADIOS_5018, + .bdf_addr = 0x4D200000, + .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), ++ .regs = &qcn6122_regs, + .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN6122, + .interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -2822,6 +2822,81 @@ const struct ath11k_hw_regs ipq5018_regs + .hal_wbm1_release_ring_base_lsb = 0x0000097c, + }; + ++const struct ath11k_hw_regs qcn6122_regs = { ++ /* SW2TCL(x) R0 ring configuration address */ ++ .hal_tcl1_ring_base_lsb = 0x00000694, ++ .hal_tcl1_ring_base_msb = 0x00000698, ++ .hal_tcl1_ring_id = 0x0000069c, ++ .hal_tcl1_ring_misc = 0x000006a4, ++ .hal_tcl1_ring_tp_addr_lsb = 0x000006b0, ++ .hal_tcl1_ring_tp_addr_msb = 0x000006b4, ++ .hal_tcl1_ring_consumer_int_setup_ix0 = 0x000006c4, ++ .hal_tcl1_ring_consumer_int_setup_ix1 = 0x000006c8, ++ .hal_tcl1_ring_msi1_base_lsb = 0x000006dc, ++ .hal_tcl1_ring_msi1_base_msb = 0x000006e0, ++ .hal_tcl1_ring_msi1_data = 0x000006e4, ++ .hal_tcl2_ring_base_lsb = 0x000006ec, ++ .hal_tcl_ring_base_lsb = 0x0000079c, ++ ++ /* TCL STATUS ring address */ ++ .hal_tcl_status_ring_base_lsb = 0x000008a4, ++ ++ /* REO2SW(x) R0 ring configuration address */ ++ .hal_reo1_ring_base_lsb = 0x000001ec, ++ .hal_reo1_ring_base_msb = 0x000001f0, ++ .hal_reo1_ring_id = 0x000001f4, ++ .hal_reo1_ring_misc = 0x000001fc, ++ .hal_reo1_ring_hp_addr_lsb = 0x00000200, ++ .hal_reo1_ring_hp_addr_msb = 0x00000204, ++ .hal_reo1_ring_producer_int_setup = 0x00000210, ++ .hal_reo1_ring_msi1_base_lsb = 0x00000234, ++ .hal_reo1_ring_msi1_base_msb = 0x00000238, ++ .hal_reo1_ring_msi1_data = 0x0000023c, ++ .hal_reo2_ring_base_lsb = 0x00000244, ++ .hal_reo1_aging_thresh_ix_0 = 0x00000564, ++ .hal_reo1_aging_thresh_ix_1 = 0x00000568, ++ .hal_reo1_aging_thresh_ix_2 = 0x0000056c, ++ .hal_reo1_aging_thresh_ix_3 = 0x00000570, ++ ++ /* REO2SW(x) R2 ring pointers (head/tail) address */ ++ .hal_reo1_ring_hp = 0x00003028, ++ .hal_reo1_ring_tp = 0x0000302c, ++ .hal_reo2_ring_hp = 0x00003030, ++ ++ /* REO2TCL R0 ring configuration address */ ++ .hal_reo_tcl_ring_base_lsb = 0x000003fc, ++ .hal_reo_tcl_ring_hp = 0x00003058, ++ ++ /* SW2REO ring address */ ++ .hal_sw2reo_ring_base_lsb = 0x0000013c, ++ .hal_sw2reo_ring_hp = 0x00003018, ++ ++ /* REO CMD ring address */ ++ .hal_reo_cmd_ring_base_lsb = 0x000000e4, ++ .hal_reo_cmd_ring_hp = 0x00003010, ++ ++ /* REO status address */ ++ .hal_reo_status_ring_base_lsb = 0x00000504, ++ .hal_reo_status_hp = 0x00003070, ++ ++ /* WCSS relative address */ ++ .hal_seq_wcss_umac_ce0_src_reg = 0x03B80000, ++ .hal_seq_wcss_umac_ce0_dst_reg = 0x03b81000, ++ .hal_seq_wcss_umac_ce1_src_reg = 0x03b82000, ++ .hal_seq_wcss_umac_ce1_dst_reg = 0x03b83000, ++ ++ /* WBM Idle address */ ++ .hal_wbm_idle_link_ring_base_lsb = 0x00000874, ++ .hal_wbm_idle_link_ring_misc = 0x00000884, ++ ++ /* SW2WBM release address */ ++ .hal_wbm_release_ring_base_lsb = 0x000001ec, ++ ++ /* WBM2SW release address */ ++ .hal_wbm0_release_ring_base_lsb = 0x00000924, ++ .hal_wbm1_release_ring_base_lsb = 0x0000097c, ++}; ++ + const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = { + .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, + .tcl2wbm_rbm_map = ath11k_hw_tcl2wbm_rbm_map_ipq8074, +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -425,6 +425,7 @@ extern const struct ath11k_hw_regs qcn90 + extern const struct ath11k_hw_regs wcn6855_regs; + extern const struct ath11k_hw_regs wcn6750_regs; + extern const struct ath11k_hw_regs ipq5018_regs; ++extern const struct ath11k_hw_regs qcn6122_regs; + + static inline const char *ath11k_bd_ie_type_str(enum ath11k_bd_ie_type type) + { diff --git a/package/kernel/mac80211/patches/ath11k/923-wifi-ath11k-initialize-hw_ops-for-QCN6122.patch b/package/kernel/mac80211/patches/ath11k/923-wifi-ath11k-initialize-hw_ops-for-QCN6122.patch new file mode 100644 index 0000000000..9d7044816a --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/923-wifi-ath11k-initialize-hw_ops-for-QCN6122.patch @@ -0,0 +1,69 @@ +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -820,6 +820,7 @@ static struct ath11k_hw_params ath11k_hw + .hal_params = &ath11k_hw_hal_params_ipq8074, + .max_radios = MAX_RADIOS_5018, + .bdf_addr = 0x4D200000, ++ .hw_ops = &qcn6122_ops, + .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), + .regs = &qcn6122_regs, + .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN6122, +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -1181,6 +1181,46 @@ const struct ath11k_hw_ops ipq5018_ops = + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + }; + ++const struct ath11k_hw_ops qcn6122_ops = { ++ .get_hw_mac_from_pdev_id = ath11k_hw_ipq6018_mac_from_pdev_id, ++ .wmi_init_config = ath11k_init_wmi_config_ipq8074, ++ .mac_id_to_pdev_id = ath11k_hw_mac_id_to_pdev_id_ipq8074, ++ .mac_id_to_srng_id = ath11k_hw_mac_id_to_srng_id_ipq8074, ++ .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid, ++ .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2, ++ .tx_mesh_enable = ath11k_hw_qcn9074_tx_mesh_enable, ++ .rx_desc_get_first_msdu = ath11k_hw_qcn9074_rx_desc_get_first_msdu, ++ .rx_desc_get_last_msdu = ath11k_hw_qcn9074_rx_desc_get_last_msdu, ++ .rx_desc_get_l3_pad_bytes = ath11k_hw_qcn9074_rx_desc_get_l3_pad_bytes, ++ .rx_desc_get_hdr_status = ath11k_hw_qcn9074_rx_desc_get_hdr_status, ++ .rx_desc_encrypt_valid = ath11k_hw_qcn9074_rx_desc_encrypt_valid, ++ .rx_desc_get_encrypt_type = ath11k_hw_qcn9074_rx_desc_get_encrypt_type, ++ .rx_desc_get_decap_type = ath11k_hw_qcn9074_rx_desc_get_decap_type, ++ .rx_desc_get_mesh_ctl = ath11k_hw_qcn9074_rx_desc_get_mesh_ctl, ++ .rx_desc_get_ldpc_support = ath11k_hw_qcn9074_rx_desc_get_ldpc_support, ++ .rx_desc_get_mpdu_seq_ctl_vld = ath11k_hw_qcn9074_rx_desc_get_mpdu_seq_ctl_vld, ++ .rx_desc_get_mpdu_fc_valid = ath11k_hw_qcn9074_rx_desc_get_mpdu_fc_valid, ++ .rx_desc_get_mpdu_start_seq_no = ath11k_hw_qcn9074_rx_desc_get_mpdu_start_seq_no, ++ .rx_desc_get_msdu_len = ath11k_hw_qcn9074_rx_desc_get_msdu_len, ++ .rx_desc_get_msdu_sgi = ath11k_hw_qcn9074_rx_desc_get_msdu_sgi, ++ .rx_desc_get_msdu_rate_mcs = ath11k_hw_qcn9074_rx_desc_get_msdu_rate_mcs, ++ .rx_desc_get_msdu_rx_bw = ath11k_hw_qcn9074_rx_desc_get_msdu_rx_bw, ++ .rx_desc_get_msdu_freq = ath11k_hw_qcn9074_rx_desc_get_msdu_freq, ++ .rx_desc_get_msdu_pkt_type = ath11k_hw_qcn9074_rx_desc_get_msdu_pkt_type, ++ .rx_desc_get_msdu_nss = ath11k_hw_qcn9074_rx_desc_get_msdu_nss, ++ .rx_desc_get_mpdu_tid = ath11k_hw_qcn9074_rx_desc_get_mpdu_tid, ++ .rx_desc_get_mpdu_peer_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_peer_id, ++ .rx_desc_copy_attn_end_tlv = ath11k_hw_qcn9074_rx_desc_copy_attn_end, ++ .rx_desc_get_mpdu_start_tag = ath11k_hw_qcn9074_rx_desc_get_mpdu_start_tag, ++ .rx_desc_get_mpdu_ppdu_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_ppdu_id, ++ .rx_desc_set_msdu_len = ath11k_hw_qcn9074_rx_desc_set_msdu_len, ++ .reo_setup = ath11k_hw_ipq5018_reo_setup, ++ .rx_desc_get_attention = ath11k_hw_qcn9074_rx_desc_get_attention, ++ .rx_desc_get_msdu_payload = ath11k_hw_qcn9074_rx_desc_get_msdu_payload, ++ .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, ++ .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, ++}; ++ + #define ATH11K_TX_RING_MASK_0 BIT(0) + #define ATH11K_TX_RING_MASK_1 BIT(1) + #define ATH11K_TX_RING_MASK_2 BIT(2) +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -284,6 +284,7 @@ extern const struct ath11k_hw_ops qcn907 + extern const struct ath11k_hw_ops wcn6855_ops; + extern const struct ath11k_hw_ops wcn6750_ops; + extern const struct ath11k_hw_ops ipq5018_ops; ++extern const struct ath11k_hw_ops qcn6122_ops; + + extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074; + extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390; diff --git a/package/kernel/mac80211/patches/ath11k/924-wifi-ath11k-update-hw-ring-mask-for-QCN6122.patch b/package/kernel/mac80211/patches/ath11k/924-wifi-ath11k-update-hw-ring-mask-for-QCN6122.patch new file mode 100644 index 0000000000..a79f81b1c1 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/924-wifi-ath11k-update-hw-ring-mask-for-QCN6122.patch @@ -0,0 +1,81 @@ +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -651,7 +651,7 @@ static struct ath11k_hw_params ath11k_hw + /* hal_desc_sz and hw ops are similar to qcn9074 */ + .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), + .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074, +- .ring_mask = &ath11k_hw_ring_mask_ipq8074, ++ .ring_mask = &ath11k_hw_ring_mask_qcn6122, + .credit_flow = false, + .max_tx_ring = 1, + .spectral = { +@@ -821,6 +821,7 @@ static struct ath11k_hw_params ath11k_hw + .max_radios = MAX_RADIOS_5018, + .bdf_addr = 0x4D200000, + .hw_ops = &qcn6122_ops, ++ .ring_mask = &ath11k_hw_ring_mask_ipq8074, + .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), + .regs = &qcn6122_regs, + .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN6122, +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: BSD-3-Clause-Clear ++/// SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. +@@ -2110,6 +2110,43 @@ const struct ath11k_hw_ring_mask ath11k_ + }, + }; + ++const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn6122 = { ++ .tx = { ++ ATH11K_TX_RING_MASK_0, ++ ATH11K_TX_RING_MASK_1, ++ ATH11K_TX_RING_MASK_2, ++ }, ++ .rx_mon_status = { ++ 0, 0, 0, ++ ATH11K_RX_MON_STATUS_RING_MASK_0, ++ }, ++ .rx = { ++ 0, 0, 0, 0, ++ ATH11K_RX_RING_MASK_0, ++ ATH11K_RX_RING_MASK_1, ++ ATH11K_RX_RING_MASK_2, ++ ATH11K_RX_RING_MASK_3, ++ }, ++ .rx_err = { ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ ATH11K_RX_ERR_RING_MASK_0, ++ }, ++ .rx_wbm_rel = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ ATH11K_RX_WBM_REL_RING_MASK_0, ++ }, ++ .reo_status = { ++ 0, 0, 0, ++ ATH11K_REO_STATUS_RING_MASK_0, ++ }, ++ .rxdma2host = { ++ ATH11K_RXDMA2HOST_RING_MASK_0, ++ }, ++ .host2rxdma = { ++ ATH11K_HOST2RXDMA_RING_MASK_0, ++ }, ++}; ++ + /* Target firmware's Copy Engine configuration for IPQ5018 */ + const struct ce_pipe_config ath11k_target_ce_config_wlan_ipq5018[] = { + /* CE0: host->target HTC control and raw streams */ +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -290,6 +290,7 @@ extern const struct ath11k_hw_ring_mask + extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390; + extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074; + extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_wcn6750; ++extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn6122; + + extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq8074; + extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018; diff --git a/package/kernel/mac80211/patches/ath11k/925-wifi-ath11k-refactor-register-access-logic-for-general-purpose.patch b/package/kernel/mac80211/patches/ath11k/925-wifi-ath11k-refactor-register-access-logic-for-general-purpose.patch new file mode 100644 index 0000000000..ec0eeb4628 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/925-wifi-ath11k-refactor-register-access-logic-for-general-purpose.patch @@ -0,0 +1,474 @@ +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -142,58 +142,47 @@ enum ext_irq_num { + }; + + static int +-ath11k_ahb_get_msi_irq_wcn6750(struct ath11k_base *ab, unsigned int vector) ++ath11k_ahb_get_msi_irq(struct ath11k_base *ab, unsigned int vector) + { + return ab->pci.msi.irqs[vector]; + } + +-static inline u32 +-ath11k_ahb_get_window_start_wcn6750(struct ath11k_base *ab, u32 offset) ++static u32 ath11k_ahb_get_window_start(struct ath11k_base *ab, u32 offset) + { +- u32 window_start = 0; +- +- /* If offset lies within DP register range, use 1st window */ +- if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK) +- window_start = ATH11K_PCI_WINDOW_START; +- /* If offset lies within CE register range, use 2nd window */ +- else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) < +- ATH11K_PCI_WINDOW_RANGE_MASK) +- window_start = 2 * ATH11K_PCI_WINDOW_START; +- +- return window_start; ++ return ath11k_pcic_get_window_start(ab, offset, ATH11K_BUS_AHB); + } + + static void +-ath11k_ahb_window_write32_wcn6750(struct ath11k_base *ab, u32 offset, u32 value) ++ath11k_ahb_window_write32(struct ath11k_base *ab, u32 offset, u32 value) + { + u32 window_start; + + /* WCN6750 uses static window based register access*/ +- window_start = ath11k_ahb_get_window_start_wcn6750(ab, offset); ++ window_start = ath11k_ahb_get_window_start(ab, offset); + + iowrite32(value, ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + } + +-static u32 ath11k_ahb_window_read32_wcn6750(struct ath11k_base *ab, u32 offset) ++static u32 ath11k_ahb_window_read32(struct ath11k_base *ab, u32 offset) + { + u32 window_start; + u32 val; + + /* WCN6750 uses static window based register access */ +- window_start = ath11k_ahb_get_window_start_wcn6750(ab, offset); ++ window_start = ath11k_ahb_get_window_start(ab, offset); + + val = ioread32(ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + return val; + } + +-static const struct ath11k_pci_ops ath11k_ahb_pci_ops_wcn6750 = { ++static const struct ath11k_pci_ops ath11k_ahb_pci_ops = { + .wakeup = NULL, + .release = NULL, +- .get_msi_irq = ath11k_ahb_get_msi_irq_wcn6750, +- .window_write32 = ath11k_ahb_window_write32_wcn6750, +- .window_read32 = ath11k_ahb_window_read32_wcn6750, ++ .get_msi_irq = ath11k_ahb_get_msi_irq, ++ .window_write32 = ath11k_ahb_window_write32, ++ .window_read32 = ath11k_ahb_window_read32, + }; + + static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset) +@@ -1142,7 +1131,7 @@ static int ath11k_ahb_probe(struct platf + break; + case ATH11K_HW_WCN6750_HW10: + hif_ops = &ath11k_ahb_hif_ops_wcn6750; +- pci_ops = &ath11k_ahb_pci_ops_wcn6750; ++ pci_ops = &ath11k_ahb_pci_ops; + break; + default: + dev_err(&pdev->dev, "unsupported device type %d\n", hw_rev); +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -56,18 +56,7 @@ static void ath11k_pci_bus_release(struc + + static u32 ath11k_pci_get_window_start(struct ath11k_base *ab, u32 offset) + { +- if (!ab->hw_params.static_window_map) +- return ATH11K_PCI_WINDOW_START; +- +- if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK) +- /* if offset lies within DP register range, use 3rd window */ +- return 3 * ATH11K_PCI_WINDOW_START; +- else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) < +- ATH11K_PCI_WINDOW_RANGE_MASK) +- /* if offset lies within CE register range, use 2nd window */ +- return 2 * ATH11K_PCI_WINDOW_START; +- else +- return ATH11K_PCI_WINDOW_START; ++ return ath11k_pcic_get_window_start(ab, offset, ATH11K_BUS_PCI); + } + + static inline void ath11k_pci_select_window(struct ath11k_pci *ab_pci, u32 offset) +@@ -161,20 +150,6 @@ static const struct ath11k_msi_config ms + }, + }; + +-static inline void ath11k_pci_select_static_window(struct ath11k_pci *ab_pci) +-{ +- u32 umac_window; +- u32 ce_window; +- u32 window; +- +- umac_window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, HAL_SEQ_WCSS_UMAC_OFFSET); +- ce_window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, HAL_CE_WFSS_CE_REG_BASE); +- window = (umac_window << 12) | (ce_window << 6); +- +- iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window, +- ab_pci->ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); +-} +- + static void ath11k_pci_soc_global_reset(struct ath11k_base *ab) + { + u32 val, delay; +@@ -644,7 +619,7 @@ static int ath11k_pci_power_up(struct at + } + + if (ab->hw_params.static_window_map) +- ath11k_pci_select_static_window(ab_pci); ++ ath11k_pcic_config_static_window(ab); + + return 0; + } +--- a/drivers/net/wireless/ath/ath11k/pcic.c ++++ b/drivers/net/wireless/ath/ath11k/pcic.c +@@ -7,6 +7,10 @@ + #include "core.h" + #include "pcic.h" + #include "debug.h" ++#include "pci.h" ++#include ++#include ++#include + + static const char *irq_name[ATH11K_IRQ_NUM_MAX] = { + "bhi", +@@ -126,6 +130,15 @@ static const struct ath11k_msi_config at + }, + .hw_rev = ATH11K_HW_QCA2066_HW21, + }, ++ { ++ .total_vectors = 13, ++ .total_users = 2, ++ .users = (struct ath11k_msi_user[]) { ++ { .name = "CE", .num_vectors = 5, .base_vector = 0 }, ++ { .name = "DP", .num_vectors = 8, .base_vector = 5 }, ++ }, ++ .hw_rev = ATH11K_HW_QCN6122_HW10, ++ }, + }; + + int ath11k_pcic_init_msi_config(struct ath11k_base *ab) +@@ -335,6 +348,15 @@ void ath11k_pcic_free_irq(struct ath11k_ + } + EXPORT_SYMBOL(ath11k_pcic_free_irq); + ++void ath11k_pcic_ipci_free_irq(struct ath11k_base *ab) ++{ ++ struct platform_device *pdev = ab->pdev; ++ ++ ath11k_pcic_free_irq(ab); ++ platform_msi_domain_free_irqs(&pdev->dev); ++} ++EXPORT_SYMBOL(ath11k_pcic_ipci_free_irq); ++ + static void ath11k_pcic_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) + { + u32 irq_idx; +@@ -808,7 +830,7 @@ int ath11k_pcic_register_pci_ops(struct + return 0; + + /* Return error if mandatory pci_ops callbacks are missing */ +- if (!pci_ops->get_msi_irq || !pci_ops->window_write32 || ++ if (!pci_ops->window_write32 || + !pci_ops->window_read32) + return -EINVAL; + +@@ -850,3 +872,251 @@ void ath11k_pci_disable_ce_irqs_except_w + } + } + EXPORT_SYMBOL(ath11k_pci_disable_ce_irqs_except_wake_irq); ++ ++void ath11k_pcic_select_static_window(struct ath11k_base *ab) ++{ ++ u32 umac_window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, HAL_SEQ_WCSS_UMAC_OFFSET); ++ u32 ce_window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, HAL_CE_WFSS_CE_REG_BASE); ++ u32 window; ++ ++ window = (umac_window << 12) | (ce_window << 6); ++ ++ iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window, ++ ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); ++} ++ ++void ath11k_pcic_config_static_window(struct ath11k_base *ab) ++{ ++ if (ab->hw_params.static_window_map) ++ ath11k_pcic_select_static_window(ab); ++} ++EXPORT_SYMBOL(ath11k_pcic_config_static_window); ++ ++int ath11k_pcic_ext_config_gic_msi_irq(struct ath11k_base *ab, struct platform_device *pdev, ++ struct msi_desc *msi_desc, int i) ++{ ++ u32 user_base_data = 0, base_vector = 0, base_idx; ++ struct ath11k_ext_irq_grp *irq_grp; ++ int j, ret = 0, num_vectors = 0; ++ u32 num_irq = 0; ++ ++ base_idx = ATH11K_PCI_IRQ_CE0_OFFSET + CE_COUNT_MAX; ++ ret = ath11k_pcic_get_user_msi_assignment(ab, "DP", &num_vectors, ++ &user_base_data, &base_vector); ++ if (ret < 0) ++ return ret; ++ ++ irq_grp = &ab->ext_irq_grp[i]; ++ irq_grp->ab = ab; ++ irq_grp->grp_id = i; ++ init_dummy_netdev(&irq_grp->napi_ndev); ++ netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi, ++ ath11k_pcic_ext_grp_napi_poll); ++ ++ if (ab->hw_params.ring_mask->tx[i] || ++ ab->hw_params.ring_mask->rx[i] || ++ ab->hw_params.ring_mask->rx_err[i] || ++ ab->hw_params.ring_mask->rx_wbm_rel[i] || ++ ab->hw_params.ring_mask->reo_status[i] || ++ ab->hw_params.ring_mask->rxdma2host[i] || ++ ab->hw_params.ring_mask->host2rxdma[i] || ++ ab->hw_params.ring_mask->rx_mon_status[i]) { ++ num_irq = 1; ++ } ++ ++ irq_grp->num_irq = num_irq; ++ irq_grp->irqs[0] = base_idx + i; ++ ++ for (j = 0; j < irq_grp->num_irq; j++) { ++ int irq_idx = irq_grp->irqs[j]; ++ int vector = (i % num_vectors); ++ ++ irq_set_status_flags(msi_desc->irq, IRQ_DISABLE_UNLAZY); ++ ret = devm_request_irq(&pdev->dev, msi_desc->irq, ++ ath11k_pcic_ext_interrupt_handler, ++ IRQF_SHARED, "irq", ++ irq_grp); ++ if (ret) { ++ ath11k_err(ab, "failed request irq %d: %d\n", ++ irq_idx, ret); ++ return ret; ++ } ++ ab->irq_num[irq_idx] = msi_desc->irq; ++ ab->ipci.dp_irq_num[vector] = msi_desc->irq; ++ ab->ipci.dp_msi_data[i] = msi_desc->msg.data; ++ disable_irq_nosync(ab->irq_num[irq_idx]); ++ } ++ return ret; ++} ++ ++int ath11k_pcic_config_gic_msi_irq(struct ath11k_base *ab, struct platform_device *pdev, ++ struct msi_desc *msi_desc, int i) ++{ ++ struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i]; ++ int irq_idx, ret; ++ ++ tasklet_setup(&ce_pipe->intr_tq, ath11k_pcic_ce_tasklet); ++ irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i; ++ ++ ret = devm_request_irq(&pdev->dev, msi_desc->irq, ++ ath11k_pcic_ce_interrupt_handler, ++ IRQF_SHARED, "ce", ++ ce_pipe); ++ if (ret) { ++ ath11k_warn(ab, "failed to request irq %d: %d\n", ++ irq_idx, ret); ++ return ret; ++ } ++ ab->irq_num[irq_idx] = msi_desc->irq; ++ ab->ipci.ce_msi_data[i] = msi_desc->msg.data; ++ ath11k_pcic_ce_irq_disable(ab, i); ++ ++ return ret; ++} ++ ++static void ath11k_msi_msg_handler(struct msi_desc *desc, struct msi_msg *msg) ++{ ++ desc->msg.address_lo = msg->address_lo; ++ desc->msg.address_hi = msg->address_hi; ++ desc->msg.data = msg->data; ++} ++ ++int ath11k_pcic_ipci_config_irq(struct ath11k_base *ab) ++{ ++ int ret; ++ struct platform_device *pdev = ab->pdev; ++ struct msi_desc *msi_desc; ++ bool ce_done = false; ++ int i = 0; ++ ++ ret = ath11k_pcic_init_msi_config(ab); ++ if (ret) { ++ ath11k_err(ab, "failed to fetch msi config: %d\n", ret); ++ return ret; ++ } ++ ++ ret = platform_msi_domain_alloc_irqs(&pdev->dev, ab->pci.msi.config->total_vectors, ++ ath11k_msi_msg_handler); ++ if (ret) { ++ ath11k_warn(ab, "failed to alloc irqs %d ab %pM\n", ret, ab); ++ return ret; ++ } ++ ++ msi_for_each_desc(msi_desc, &pdev->dev, MSI_DESC_ALL) { ++ if (!ce_done && i == ab->hw_params.ce_count) { ++ i = 0; ++ ce_done = true; ++ } ++ ++ if (!ce_done && i < ab->hw_params.ce_count) { ++ if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) ++ i++; ++ ++ ret = ath11k_pcic_config_gic_msi_irq(ab, pdev, msi_desc, i); ++ if (ret) { ++ ath11k_warn(ab, "failed to request irq %d\n", ret); ++ return ret; ++ } ++ } else { ++ ret = ath11k_pcic_ext_config_gic_msi_irq(ab, pdev, msi_desc, i); ++ if (ret) { ++ ath11k_warn(ab, "failed to config ext msi irq %d\n", ret); ++ return ret; ++ } ++ } ++ ++ i++; ++ ab->pci.msi.addr_lo = msi_desc->msg.address_lo; ++ ab->pci.msi.addr_hi = msi_desc->msg.address_hi; ++ ++ if (i == 0 && !ce_done) ++ ab->pci.msi.ep_base_data = msi_desc->msg.data; ++ } ++ ++ msi_for_each_desc(msi_desc, &pdev->dev, MSI_DESC_ALL) { ++ u32 user_base_data = 0, base_vector = 0; ++ int vector, num_vectors = 0; ++ ++ ret = ath11k_pcic_get_user_msi_assignment(ab, "DP", &num_vectors, ++ &user_base_data, &base_vector); ++ if (ret < 0) ++ return ret; ++ ++ vector = (i % num_vectors); ++ ++ if (i >= ATH11K_EXT_IRQ_GRP_NUM_MAX) ++ break; ++ ++ if (ab->ipci.dp_irq_num[vector] != msi_desc->irq) ++ continue; ++ ++ ret = ath11k_pcic_ext_config_gic_msi_irq(ab, pdev, msi_desc, i); ++ if (ret) { ++ ath11k_warn(ab, "failed to config ext msi irq %d\n", ret); ++ return ret; ++ } ++ ++ i++; ++ } ++ ++ ab->ipci.gic_enabled = 1; ++ wake_up(&ab->ipci.gic_msi_waitq); ++ return ret; ++} ++EXPORT_SYMBOL(ath11k_pcic_ipci_config_irq); ++ ++u32 ath11k_pcic_get_window_start(struct ath11k_base *ab, u32 offset, ++ enum ath11k_bus bus) ++{ ++ u32 window_start = 0; ++ ++ if (bus == ATH11K_BUS_PCI) { ++ if (!ab->hw_params.static_window_map) ++ return ATH11K_PCI_WINDOW_START; ++ ++ /* if offset lies within DP register range, use 3rd window */ ++ if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ++ ATH11K_PCI_WINDOW_RANGE_MASK) ++ window_start = 3 * ATH11K_PCI_WINDOW_START; ++ /* if offset lies within CE register range, use 2nd window */ ++ else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) < ++ ATH11K_PCI_WINDOW_RANGE_MASK) ++ window_start = 2 * ATH11K_PCI_WINDOW_START; ++ else ++ window_start = ATH11K_PCI_WINDOW_START; ++ } else if (bus == ATH11K_BUS_AHB) { ++ /* If offset lies within DP register range, use 1st window */ ++ if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ++ ATH11K_PCI_WINDOW_RANGE_MASK) ++ window_start = ((ab->hw_params.dp_window) ? ab->hw_params.dp_window : 1) ++ * ATH11K_PCI_WINDOW_START; ++ /* If offset lies within CE register range, use 2nd window */ ++ else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) < ++ ATH11K_PCI_WINDOW_RANGE_MASK) ++ window_start = 2 * ATH11K_PCI_WINDOW_START; ++ else ++ window_start = ATH11K_PCI_WINDOW_START; ++ } ++ else { ++ /* Must not come here */ ++ WARN_ON(1); ++ } ++ ++ return window_start; ++} ++EXPORT_SYMBOL(ath11k_pcic_get_window_start); ++ ++u32 ath11k_pci_get_window_offset(struct ath11k_base *ab, u32 offset) ++{ ++ u32 window_start; ++ ++ if (ab->hw_params.static_window_map) { ++ window_start = ath11k_pcic_get_window_start(ab, offset, ++ ATH11K_BUS_PCI); ++ ++ if (window_start) ++ offset = window_start + (offset & ATH11K_PCI_WINDOW_RANGE_MASK); ++ } ++ return offset; ++} ++EXPORT_SYMBOL(ath11k_pci_get_window_offset); +--- a/drivers/net/wireless/ath/ath11k/pcic.h ++++ b/drivers/net/wireless/ath/ath11k/pcic.h +@@ -51,4 +51,12 @@ int ath11k_pcic_read(struct ath11k_base + void ath11k_pci_enable_ce_irqs_except_wake_irq(struct ath11k_base *ab); + void ath11k_pci_disable_ce_irqs_except_wake_irq(struct ath11k_base *ab); + ++void ath11k_pcic_select_static_window(struct ath11k_base *ab); ++void ath11k_pcic_ipci_free_irq(struct ath11k_base *ab); ++int ath11k_pcic_ipci_config_irq(struct ath11k_base *ab); ++void ath11k_pcic_config_static_window(struct ath11k_base *ab); ++u32 ath11k_pcic_get_window_start(struct ath11k_base *ab, u32 offset, ++ enum ath11k_bus bus); ++u32 ath11k_pci_get_window_offset(struct ath11k_base *ab, u32 offset); ++ + #endif +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -871,6 +871,7 @@ static struct ath11k_hw_params ath11k_hw + .support_off_channel_tx = false, + .tcl_ring_retry = true, + .tx_ring_size = DP_TCL_DATA_RING_SIZE, ++ .dp_window = 3, + }, + }; + +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -232,6 +232,7 @@ struct ath11k_hw_params { + bool smp2p_wow_exit; + bool support_fw_mac_sequence; + bool support_dual_stations; ++ u8 dp_window; + }; + + struct ath11k_hw_ops { diff --git a/package/kernel/mac80211/patches/ath11k/926-wifi-ath11k-update-hif_ops-for-qcn6122.patch b/package/kernel/mac80211/patches/ath11k/926-wifi-ath11k-update-hif_ops-for-qcn6122.patch new file mode 100644 index 0000000000..c3c204990d --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/926-wifi-ath11k-update-hif_ops-for-qcn6122.patch @@ -0,0 +1,59 @@ +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -789,6 +789,22 @@ static const struct ath11k_hif_ops ath11 + .ce_irq_disable = ath11k_pci_disable_ce_irqs_except_wake_irq, + }; + ++static const struct ath11k_hif_ops ath11k_ahb_hif_ops_qcn6122 = { ++ .start = ath11k_pcic_start, ++ .stop = ath11k_pcic_stop, ++ .read32 = ath11k_pcic_read32, ++ .write32 = ath11k_pcic_write32, ++ .power_down = ath11k_ahb_power_down, ++ .power_up = ath11k_ahb_power_up, ++ .irq_enable = ath11k_pcic_ext_irq_enable, ++ .irq_disable = ath11k_pcic_ext_irq_disable, ++ .get_msi_address = ath11k_pcic_get_msi_address, ++ .get_user_msi_vector = ath11k_pcic_get_user_msi_assignment, ++ .map_service_to_pipe = ath11k_pcic_map_service_to_pipe, ++ .get_ce_msi_idx = ath11k_pcic_get_ce_msi_idx, ++ .config_static_window = ath11k_pcic_config_static_window, ++}; ++ + static int ath11k_core_get_rproc(struct ath11k_base *ab) + { + struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab); +@@ -1133,6 +1149,10 @@ static int ath11k_ahb_probe(struct platf + hif_ops = &ath11k_ahb_hif_ops_wcn6750; + pci_ops = &ath11k_ahb_pci_ops; + break; ++ case ATH11K_HW_QCN6122_HW10: ++ hif_ops = &ath11k_ahb_hif_ops_qcn6122; ++ pci_ops = &ath11k_ahb_pci_ops; ++ break; + default: + dev_err(&pdev->dev, "unsupported device type %d\n", hw_rev); + return -EOPNOTSUPP; +--- a/drivers/net/wireless/ath/ath11k/hif.h ++++ b/drivers/net/wireless/ath/ath11k/hif.h +@@ -31,6 +31,7 @@ struct ath11k_hif_ops { + void (*ce_irq_enable)(struct ath11k_base *ab); + void (*ce_irq_disable)(struct ath11k_base *ab); + void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx); ++ void (*config_static_window)(struct ath11k_base *ab); + }; + + static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab) +@@ -146,4 +147,12 @@ static inline void ath11k_get_ce_msi_idx + *msi_data_idx = ce_id; + } + ++static inline void ath11k_hif_config_static_window(struct ath11k_base *ab) ++{ ++ if (!ab->hif.ops->config_static_window) ++ return; ++ ++ ab->hif.ops->config_static_window(ab); ++} ++ + #endif /* _HIF_H_ */ diff --git a/package/kernel/mac80211/patches/ath11k/927-wifi-ath11k-add-internal-pci-logic.patch b/package/kernel/mac80211/patches/ath11k/927-wifi-ath11k-add-internal-pci-logic.patch new file mode 100644 index 0000000000..c10596de03 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/927-wifi-ath11k-add-internal-pci-logic.patch @@ -0,0 +1,202 @@ +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -446,6 +446,9 @@ static void ath11k_ahb_free_irq(struct a + int irq_idx; + int i; + ++ if (ab->hw_params.internal_pci) ++ return ath11k_pcic_ipci_free_irq(ab); ++ + if (ab->hw_params.hybrid_bus_type) + return ath11k_pcic_free_irq(ab); + +@@ -607,6 +610,9 @@ static int ath11k_ahb_config_irq(struct + int irq, irq_idx, i; + int ret; + ++ if (ab->hw_params.internal_pci) ++ return ath11k_pcic_ipci_config_irq(ab); ++ + if (ab->hw_params.hybrid_bus_type) + return ath11k_pcic_config_irq(ab); + +@@ -911,6 +917,11 @@ static int ath11k_ahb_setup_resources(st + struct resource *mem_res; + void __iomem *mem; + ++ if (ab->hw_params.internal_pci) { ++ set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags); ++ return 0; ++ } ++ + if (ab->hw_params.hybrid_bus_type) + return ath11k_ahb_setup_msi_resources(ab); + +--- a/drivers/net/wireless/ath/ath11k/ce.c ++++ b/drivers/net/wireless/ath/ath11k/ce.c +@@ -548,7 +548,11 @@ static void ath11k_ce_srng_msi_ring_para + + ring_params->msi_addr = addr_lo; + ring_params->msi_addr |= (dma_addr_t)(((uint64_t)addr_hi) << 32); +- ring_params->msi_data = (msi_data_idx % msi_data_count) + msi_data_start; ++ if (ab->hw_params.internal_pci) ++ ring_params->msi_data = ab->ipci.ce_msi_data[ce_id]; ++ else ++ ring_params->msi_data = (msi_data_idx % msi_data_count) + msi_data_start; ++ + ring_params->flags |= HAL_SRNG_FLAGS_MSI_INTR; + } + +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -871,6 +871,7 @@ static struct ath11k_hw_params ath11k_hw + .support_off_channel_tx = false, + .tcl_ring_retry = true, + .tx_ring_size = DP_TCL_DATA_RING_SIZE, ++ .internal_pci = true, + .dp_window = 3, + }, + }; +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -883,6 +883,14 @@ struct ath11k_msi_config { + u16 hw_rev; + }; + ++struct ath11k_internal_pci { ++ bool gic_enabled; ++ wait_queue_head_t gic_msi_waitq; ++ u32 dp_msi_data[ATH11K_EXT_IRQ_GRP_NUM_MAX]; ++ u32 ce_msi_data[CE_CNT_5018]; ++ u32 dp_irq_num[8]; ++}; ++ + /* Master structure to hold the hw data which may be used in core module */ + struct ath11k_base { + enum ath11k_hw_rev hw_rev; +@@ -944,6 +952,7 @@ struct ath11k_base { + struct list_head peers; + wait_queue_head_t peer_mapping_wq; + u8 mac_addr[ETH_ALEN]; ++ struct ath11k_internal_pci ipci; + int irq_num[ATH11K_IRQ_NUM_MAX]; + struct ath11k_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX]; + struct ath11k_targ_cap target_caps; +--- a/drivers/net/wireless/ath/ath11k/dp.c ++++ b/drivers/net/wireless/ath/ath11k/dp.c +@@ -216,8 +216,12 @@ static void ath11k_dp_srng_msi_setup(str + + ring_params->msi_addr = addr_lo; + ring_params->msi_addr |= (dma_addr_t)(((uint64_t)addr_hi) << 32); +- ring_params->msi_data = (msi_group_number % msi_data_count) ++ if (ab->hw_params.internal_pci) { ++ ring_params->msi_data = ab->ipci.dp_msi_data[msi_group_number]; ++ } else { ++ ring_params->msi_data = (msi_group_number % msi_data_count) + + msi_data_start; ++ } + ring_params->flags |= HAL_SRNG_FLAGS_MSI_INTR; + } + +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -232,6 +232,7 @@ struct ath11k_hw_params { + bool smp2p_wow_exit; + bool support_fw_mac_sequence; + bool support_dual_stations; ++ bool internal_pci; + u8 dp_window; + }; + +--- a/drivers/net/wireless/ath/ath11k/pcic.c ++++ b/drivers/net/wireless/ath/ath11k/pcic.c +@@ -770,7 +770,8 @@ EXPORT_SYMBOL(ath11k_pcic_stop); + + int ath11k_pcic_start(struct ath11k_base *ab) + { +- set_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags); ++ if (!ab->hw_params.internal_pci) ++ set_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags); + + ath11k_pcic_ce_irqs_enable(ab); + ath11k_ce_rx_post_buf(ab); +--- a/drivers/net/wireless/ath/ath11k/qmi.c ++++ b/drivers/net/wireless/ath/ath11k/qmi.c +@@ -2124,7 +2124,7 @@ static int ath11k_qmi_request_device_inf + int ret; + + /* device info message req is only sent for hybrid bus devices */ +- if (!ab->hw_params.hybrid_bus_type) ++ if (!ab->hw_params.hybrid_bus_type && !ab->hw_params.internal_pci) + return 0; + + ret = qmi_txn_init(&ab->qmi.handle, &txn, +@@ -2184,6 +2184,12 @@ static int ath11k_qmi_request_device_inf + ab->mem = bar_addr_va; + ab->mem_len = resp.bar_size; + ++ if (ab->hw_params.internal_pci) ++ ath11k_hif_config_static_window(ab); ++ ++ ath11k_dbg(ab, ATH11K_DBG_QMI, "Device BAR Info pa: 0x%llx, size: 0x%lx\n", ++ resp.bar_addr, ab->mem_len); ++ + return 0; + out: + return ret; +@@ -3200,6 +3206,23 @@ static const struct qmi_ops ath11k_qmi_o + .del_server = ath11k_qmi_ops_del_server, + }; + ++static int ath11k_wait_for_gic_msi(struct ath11k_base *ab) ++{ ++ int timeout; ++ ++ if (ab->hw_rev != ATH11K_HW_QCN6122_HW10) ++ return 0; ++ ++ timeout = wait_event_timeout(ab->ipci.gic_msi_waitq, ++ (ab->ipci.gic_enabled == 1), ++ ATH11K_RCV_GIC_MSI_HDLR_DELAY); ++ if (timeout <= 0) { ++ ath11k_warn(ab, "Receive gic msi handler timed out\n"); ++ return -ETIMEDOUT; ++ } ++ return 0; ++} ++ + static void ath11k_qmi_driver_event_work(struct work_struct *work) + { + struct ath11k_qmi *qmi = container_of(work, struct ath11k_qmi, +@@ -3269,6 +3292,13 @@ static void ath11k_qmi_driver_event_work + clear_bit(ATH11K_FLAG_CRASH_FLUSH, + &ab->dev_flags); + clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags); ++ ret = ath11k_wait_for_gic_msi(ab); ++ if (ret) { ++ ath11k_warn(ab, ++ "Failed to get qgic handler for dev %d ret: %d\n", ++ ab->hw_rev, ret); ++ break; ++ } + ret = ath11k_core_qmi_firmware_ready(ab); + if (ret) { + set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags); +@@ -3341,6 +3371,7 @@ int ath11k_qmi_init_service(struct ath11 + return ret; + } + ++ init_waitqueue_head(&ab->ipci.gic_msi_waitq); + return ret; + } + +--- a/drivers/net/wireless/ath/ath11k/qmi.h ++++ b/drivers/net/wireless/ath/ath11k/qmi.h +@@ -41,6 +41,7 @@ + #define ATH11K_COLD_BOOT_FW_RESET_DELAY (60 * HZ) + + #define ATH11K_QMI_DEVICE_BAR_SIZE 0x200000 ++#define ATH11K_RCV_GIC_MSI_HDLR_DELAY (3 * HZ) + + struct ath11k_base; + diff --git a/package/kernel/mac80211/patches/ath11k/928-wifi-ath11k-add-multipd-support-for-qcn6122.patch b/package/kernel/mac80211/patches/ath11k/928-wifi-ath11k-add-multipd-support-for-qcn6122.patch new file mode 100644 index 0000000000..19e3430ba0 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/928-wifi-ath11k-add-multipd-support-for-qcn6122.patch @@ -0,0 +1,110 @@ +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -424,6 +424,7 @@ static void ath11k_ahb_init_qmi_ce_confi + cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len; + cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map; + ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id; ++ ab->qmi.service_ins_id += ab->userpd_id; + } + + static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab) +@@ -1104,6 +1105,28 @@ err_unregister: + return ret; + } + ++static int ath11k_get_userpd_id(struct device *dev) ++{ ++ int ret; ++ int userpd_id = 0; ++ const char *subsys_name; ++ ++ ret = of_property_read_string(dev->of_node, ++ "qcom,userpd-subsys-name", ++ &subsys_name); ++ if (ret) { ++ dev_err(dev, "Not multipd architecture"); ++ return 0; ++ } ++ ++ if (strcmp(subsys_name, "q6v5_wcss_userpd2") == 0) ++ userpd_id = ATH11K_QCN6122_USERPD_2; ++ else if (strcmp(subsys_name, "q6v5_wcss_userpd3") == 0) ++ userpd_id = ATH11K_QCN6122_USERPD_3; ++ ++ return userpd_id; ++} ++ + static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab) + { + struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab); +@@ -1145,7 +1168,7 @@ static int ath11k_ahb_probe(struct platf + const struct ath11k_hif_ops *hif_ops; + const struct ath11k_pci_ops *pci_ops; + enum ath11k_hw_rev hw_rev; +- int ret; ++ int ret, userpd_id; + + hw_rev = (uintptr_t)device_get_match_data(&pdev->dev); + +@@ -1169,6 +1192,7 @@ static int ath11k_ahb_probe(struct platf + return -EOPNOTSUPP; + } + ++ userpd_id = ath11k_get_userpd_id(&pdev->dev); + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "failed to set 32-bit consistent dma\n"); +@@ -1185,6 +1209,7 @@ static int ath11k_ahb_probe(struct platf + ab->hif.ops = hif_ops; + ab->pdev = pdev; + ab->hw_rev = hw_rev; ++ ab->userpd_id = userpd_id; + ab->fw_mode = ATH11K_FIRMWARE_MODE_NORMAL; + platform_set_drvdata(pdev, ab); + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -45,6 +45,9 @@ + #define ATH11K_INVALID_HW_MAC_ID 0xFF + #define ATH11K_CONNECTION_LOSS_HZ (3 * HZ) + ++#define ATH11K_QCN6122_USERPD_2 1 ++#define ATH11K_QCN6122_USERPD_3 2 ++ + /* SMBIOS type containing Board Data File Name Extension */ + #define ATH11K_SMBIOS_BDF_EXT_TYPE 0xF8 + +@@ -952,6 +955,7 @@ struct ath11k_base { + struct list_head peers; + wait_queue_head_t peer_mapping_wq; + u8 mac_addr[ETH_ALEN]; ++ int userpd_id; + struct ath11k_internal_pci ipci; + int irq_num[ATH11K_IRQ_NUM_MAX]; + struct ath11k_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX]; +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -364,6 +364,8 @@ static void ath11k_pci_init_qmi_ce_confi + } else + ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id; + ++ ab->qmi.service_ins_id += ab->userpd_id; ++ + ath11k_ce_get_shadow_config(ab, &cfg->shadow_reg_v2, + &cfg->shadow_reg_v2_len); + } +--- a/drivers/net/wireless/ath/ath11k/pcic.c ++++ b/drivers/net/wireless/ath/ath11k/pcic.c +@@ -990,6 +990,12 @@ int ath11k_pcic_ipci_config_irq(struct a + bool ce_done = false; + int i = 0; + ++ if (ab->userpd_id != ATH11K_QCN6122_USERPD_2 && ++ ab->userpd_id != ATH11K_QCN6122_USERPD_3) { ++ ath11k_warn(ab, "ath11k userpd invalid %d\n", ab->userpd_id); ++ return -ENODEV; ++ } ++ + ret = ath11k_pcic_init_msi_config(ab); + if (ret) { + ath11k_err(ab, "failed to fetch msi config: %d\n", ret); diff --git a/package/kernel/mac80211/patches/ath11k/929-wifi-ath11k-add-qcn6122-device-support.patch b/package/kernel/mac80211/patches/ath11k/929-wifi-ath11k-add-qcn6122-device-support.patch new file mode 100644 index 0000000000..01333e5ef4 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/929-wifi-ath11k-add-qcn6122-device-support.patch @@ -0,0 +1,23 @@ +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -37,6 +37,9 @@ static const struct of_device_id ath11k_ + { .compatible = "qcom,ipq5018-wifi", + .data = (void *)ATH11K_HW_IPQ5018_HW10, + }, ++ { .compatible = "qcom,qcn6122-wifi", ++ .data = (void *)ATH11K_HW_QCN6122_HW10, ++ }, + { } + }; + +--- a/drivers/net/wireless/ath/ath11k/ce.c ++++ b/drivers/net/wireless/ath/ath11k/ce.c +@@ -217,7 +217,7 @@ const struct ce_attr ath11k_host_ce_conf + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, +- .dest_nentries = 32, ++ .dest_nentries = 128, + .recv_cb = ath11k_htc_rx_completion_handler, + }, + diff --git a/package/kernel/mac80211/patches/ath11k/930-wifi-ath11k-qcn6122-fix-null-pointer-and-compilation-errors.patch b/package/kernel/mac80211/patches/ath11k/930-wifi-ath11k-qcn6122-fix-null-pointer-and-compilation-errors.patch new file mode 100644 index 0000000000..002123c3e8 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/930-wifi-ath11k-qcn6122-fix-null-pointer-and-compilation-errors.patch @@ -0,0 +1,61 @@ +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -849,7 +849,7 @@ static struct ath11k_hw_params ath11k_hw + .svc_to_ce_map_len = SVC_CE_MAP_LEN_5018, + .single_pdev_only = false, + .rxdma1_enable = true, +- .num_rxmda_per_pdev = RXDMA_PER_PDEV_5018, ++ .num_rxdma_per_pdev = RXDMA_PER_PDEV_5018, + .rx_mac_buf_ring = false, + .vdev_start_delay = false, + .htt_peer_map_v2 = true, +--- a/drivers/net/wireless/ath/ath11k/pcic.c ++++ b/drivers/net/wireless/ath/ath11k/pcic.c +@@ -898,7 +898,7 @@ int ath11k_pcic_ext_config_gic_msi_irq(s + { + u32 user_base_data = 0, base_vector = 0, base_idx; + struct ath11k_ext_irq_grp *irq_grp; +- int j, ret = 0, num_vectors = 0; ++ int j, n, ret = 0, num_vectors = 0; + u32 num_irq = 0; + + base_idx = ATH11K_PCI_IRQ_CE0_OFFSET + CE_COUNT_MAX; +@@ -910,8 +910,13 @@ int ath11k_pcic_ext_config_gic_msi_irq(s + irq_grp = &ab->ext_irq_grp[i]; + irq_grp->ab = ab; + irq_grp->grp_id = i; +- init_dummy_netdev(&irq_grp->napi_ndev); +- netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi, ++ irq_grp->napi_ndev = alloc_netdev_dummy(0); ++ if (!irq_grp->napi_ndev) { ++ ret = -ENOMEM; ++ goto fail_allocate; ++ } ++ ++ netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi, + ath11k_pcic_ext_grp_napi_poll); + + if (ab->hw_params.ring_mask->tx[i] || +@@ -940,13 +945,21 @@ int ath11k_pcic_ext_config_gic_msi_irq(s + if (ret) { + ath11k_err(ab, "failed request irq %d: %d\n", + irq_idx, ret); +- return ret; ++ goto fail_irq; + } + ab->irq_num[irq_idx] = msi_desc->irq; + ab->ipci.dp_irq_num[vector] = msi_desc->irq; + ab->ipci.dp_msi_data[i] = msi_desc->msg.data; + disable_irq_nosync(ab->irq_num[irq_idx]); + } ++ return 0; ++fail_irq: ++ j += 1; ++fail_allocate: ++ for (n = 0; n <= j; n++) { ++ irq_grp = &ab->ext_irq_grp[n]; ++ free_netdev(irq_grp->napi_ndev); ++ } + return ret; + } + diff --git a/package/kernel/mac80211/patches/ath11k/931-wifi-ath11k-Support-to-assign-m3-dump-memory.patch b/package/kernel/mac80211/patches/ath11k/931-wifi-ath11k-Support-to-assign-m3-dump-memory.patch new file mode 100644 index 0000000000..67d25a9fa2 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/931-wifi-ath11k-Support-to-assign-m3-dump-memory.patch @@ -0,0 +1,31 @@ +From 64f6f6cdde0b6b763181145a698207fad4536c06 Mon Sep 17 00:00:00 2001 +From: hzy +Date: Wed, 9 Aug 2023 17:44:49 +0000 +Subject: [PATCH 2/2] wifi: ath11k: Support to assign m3 dump memory + +Signed-off-by: hzy +--- + drivers/net/wireless/ath/ath11k/qmi.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/net/wireless/ath/ath11k/qmi.c ++++ b/drivers/net/wireless/ath/ath11k/qmi.c +@@ -2104,6 +2104,18 @@ static int ath11k_qmi_assign_target_mem_ + ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; + idx++; + break; ++ case M3_DUMP_REGION_TYPE: ++ if (of_property_read_u32(dev->of_node, "qcom,m3-dump-addr", &addr)) { ++ ath11k_warn(ab, "qmi fail to get qcom,m3-dump-addr, ignore m3 dump mem req\n"); ++ break; ++ } ++ ++ ab->qmi.target_mem[idx].paddr = (phys_addr_t) addr; ++ ab->qmi.target_mem[idx].vaddr = NULL; ++ ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size; ++ ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; ++ idx++; ++ break; + default: + ath11k_warn(ab, "qmi ignore invalid mem req type %d\n", + ab->qmi.target_mem[i].type);