+++ /dev/null
-From d45daa6d1a8da080f1b516c570a8428a7b9225e4 Mon Sep 17 00:00:00 2001
-Date: Tue, 6 Dec 2022 00:51:25 +0530
-Subject: [PATCH] wifi: ath11k: Fix scan request param frame size warning
-
-Following warning was observed
-
-drivers/net/wireless/ath/ath11k/mac.c:2351:1: warning: the frame
-size of 1184 bytes is larger than 1024 bytes [-Wframe-larger-than=]
-
-A local variable is declared with a size larger than 1024 bytes
-this causing a compilation warning. Change the local variable to
-heap memory to fix the warning.
-
-Tested-on: IPQ8074 AHB WLAN.HK.2.7.0.1-01701-QCAHKSWPL_SILICONZ-1 v2
-
----
- drivers/net/wireless/ath/ath11k/mac.c | 83 +++++++++++++++------------
- 1 file changed, 45 insertions(+), 38 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/mac.c
-+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -3612,7 +3612,7 @@ static int ath11k_mac_op_hw_scan(struct
- struct ath11k *ar = hw->priv;
- struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
- struct cfg80211_scan_request *req = &hw_req->req;
-- struct scan_req_params arg;
-+ struct scan_req_params *arg = NULL;
- int ret = 0;
- int i;
- u32 scan_timeout;
-@@ -3640,72 +3640,78 @@ static int ath11k_mac_op_hw_scan(struct
- if (ret)
- goto exit;
-
-- memset(&arg, 0, sizeof(arg));
-- ath11k_wmi_start_scan_init(ar, &arg);
-- arg.vdev_id = arvif->vdev_id;
-- arg.scan_id = ATH11K_SCAN_ID;
-+ arg = kzalloc(sizeof(*arg), GFP_KERNEL);
-+
-+ if (!arg) {
-+ ret = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ ath11k_wmi_start_scan_init(ar, arg);
-+ arg->vdev_id = arvif->vdev_id;
-+ arg->scan_id = ATH11K_SCAN_ID;
-
- if (req->ie_len) {
-- arg.extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL);
-- if (!arg.extraie.ptr) {
-+ arg->extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL);
-+ if (!arg->extraie.ptr) {
- ret = -ENOMEM;
- goto exit;
- }
-- arg.extraie.len = req->ie_len;
-+ arg->extraie.len = req->ie_len;
- }
-
- if (req->n_ssids) {
-- arg.num_ssids = req->n_ssids;
-- for (i = 0; i < arg.num_ssids; i++) {
-- arg.ssid[i].length = req->ssids[i].ssid_len;
-- memcpy(&arg.ssid[i].ssid, req->ssids[i].ssid,
-+ arg->num_ssids = req->n_ssids;
-+ for (i = 0; i < arg->num_ssids; i++) {
-+ arg->ssid[i].length = req->ssids[i].ssid_len;
-+ memcpy(&arg->ssid[i].ssid, req->ssids[i].ssid,
- req->ssids[i].ssid_len);
- }
- } else {
-- arg.scan_flags |= WMI_SCAN_FLAG_PASSIVE;
-+ arg->scan_flags |= WMI_SCAN_FLAG_PASSIVE;
- }
-
- if (req->n_channels) {
-- arg.num_chan = req->n_channels;
-- arg.chan_list = kcalloc(arg.num_chan, sizeof(*arg.chan_list),
-- GFP_KERNEL);
-+ arg->num_chan = req->n_channels;
-+ arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list),
-+ GFP_KERNEL);
-
-- if (!arg.chan_list) {
-+ if (!arg->chan_list) {
- ret = -ENOMEM;
- goto exit;
- }
-
-- for (i = 0; i < arg.num_chan; i++)
-- arg.chan_list[i] = req->channels[i]->center_freq;
-+ for (i = 0; i < arg->num_chan; i++)
-+ arg->chan_list[i] = req->channels[i]->center_freq;
- }
-
- if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
-- arg.scan_f_add_spoofed_mac_in_probe = 1;
-- ether_addr_copy(arg.mac_addr.addr, req->mac_addr);
-- ether_addr_copy(arg.mac_mask.addr, req->mac_addr_mask);
-+ arg->scan_f_add_spoofed_mac_in_probe = 1;
-+ ether_addr_copy(arg->mac_addr.addr, req->mac_addr);
-+ ether_addr_copy(arg->mac_mask.addr, req->mac_addr_mask);
- }
-
- /* if duration is set, default dwell times will be overwritten */
- if (req->duration) {
-- arg.dwell_time_active = req->duration;
-- arg.dwell_time_active_2g = req->duration;
-- arg.dwell_time_active_6g = req->duration;
-- arg.dwell_time_passive = req->duration;
-- arg.dwell_time_passive_6g = req->duration;
-- arg.burst_duration = req->duration;
-+ arg->dwell_time_active = req->duration;
-+ arg->dwell_time_active_2g = req->duration;
-+ arg->dwell_time_active_6g = req->duration;
-+ arg->dwell_time_passive = req->duration;
-+ arg->dwell_time_passive_6g = req->duration;
-+ arg->burst_duration = req->duration;
-
-- scan_timeout = min_t(u32, arg.max_rest_time *
-- (arg.num_chan - 1) + (req->duration +
-+ scan_timeout = min_t(u32, arg->max_rest_time *
-+ (arg->num_chan - 1) + (req->duration +
- ATH11K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) *
-- arg.num_chan, arg.max_scan_time);
-+ arg->num_chan, arg->max_scan_time);
- } else {
-- scan_timeout = arg.max_scan_time;
-+ scan_timeout = arg->max_scan_time;
- }
-
- /* Add a margin to account for event/command processing */
- scan_timeout += ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD;
-
-- ret = ath11k_start_scan(ar, &arg);
-+ ret = ath11k_start_scan(ar, arg);
- if (ret) {
- ath11k_warn(ar->ab, "failed to start hw scan: %d\n", ret);
- spin_lock_bh(&ar->data_lock);
-@@ -3717,10 +3723,11 @@ static int ath11k_mac_op_hw_scan(struct
- msecs_to_jiffies(scan_timeout));
-
- exit:
-- kfree(arg.chan_list);
--
-- if (req->ie_len)
-- kfree(arg.extraie.ptr);
-+ if (arg) {
-+ kfree(arg->chan_list);
-+ kfree(arg->extraie.ptr);
-+ kfree(arg);
-+ }
-
- mutex_unlock(&ar->conf_mutex);
-
--- /dev/null
+From 8dfe875aa24aec68baf6702018633c84c2c1feca Mon Sep 17 00:00:00 2001
+Date: Fri, 2 Dec 2022 23:37:13 +0200
+Subject: [PATCH] wifi: ath11k: update hw params for IPQ5018
+
+Add new compatible string for IPQ5018 and add
+required hw params for IPQ5018. The hw descriptors size and
+datapath ops are similar to QCN9074, hence reuse the same.
+
+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1
+
+---
+ drivers/net/wireless/ath/ath11k/core.c | 71 ++++++++++++++++++++++++++
+ drivers/net/wireless/ath/ath11k/core.h | 8 +++
+ 2 files changed, 79 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -604,6 +604,77 @@ static const struct ath11k_hw_params ath
+ .smp2p_wow_exit = true,
+ .support_fw_mac_sequence = true,
+ },
++ {
++ .hw_rev = ATH11K_HW_IPQ5018_HW10,
++ .name = "ipq5018 hw1.0",
++ .fw = {
++ .dir = "IPQ5018/hw1.0",
++ .board_size = 256 * 1024,
++ .cal_offset = 128 * 1024,
++ },
++ .max_radios = MAX_RADIOS_5018,
++ .bdf_addr = 0x4BA00000,
++ /* 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,
++ .credit_flow = false,
++ .max_tx_ring = 1,
++ .spectral = {
++ .fft_sz = 2,
++ .fft_pad_sz = 0,
++ .summary_pad_sz = 16,
++ .fft_hdr_len = 24,
++ .max_fft_bins = 1024,
++ },
++ .internal_sleep_clock = false,
++ .host_ce_config = ath11k_host_ce_config_qcn9074,
++ .ce_count = CE_CNT_5018,
++ .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,
++ .interface_modes = BIT(NL80211_IFTYPE_STATION) |
++ BIT(NL80211_IFTYPE_AP) |
++ BIT(NL80211_IFTYPE_MESH_POINT),
++ .supports_monitor = false,
++ .supports_sta_ps = false,
++ .supports_shadow_regs = false,
++ .fw_mem_mode = 0,
++ .num_vdevs = 16 + 1,
++ .num_peers = 512,
++ .supports_regdb = false,
++ .idle_ps = false,
++ .supports_suspend = false,
++ .hal_params = &ath11k_hw_hal_params_ipq8074,
++ .single_pdev_only = false,
++ .cold_boot_calib = true,
++ .fix_l1ss = true,
++ .supports_dynamic_smps_6ghz = false,
++ .alloc_cacheable_memory = true,
++ .supports_rssi_stats = false,
++ .fw_wmi_diag_event = false,
++ .current_cc_support = false,
++ .dbr_debug_support = true,
++ .global_reset = false,
++ .bios_sar_capa = NULL,
++ .m3_fw_support = false,
++ .fixed_bdf_addr = true,
++ .fixed_mem_region = true,
++ .static_window_map = false,
++ .hybrid_bus_type = false,
++ .fixed_fw_mem = false,
++ .support_off_channel_tx = false,
++ .supports_multi_bssid = false,
++
++ .sram_dump = {},
++
++ .tcl_ring_retry = true,
++ .tx_ring_size = DP_TCL_DATA_RING_SIZE,
++ .smp2p_wow_exit = false,
++ .support_fw_mac_sequence = false,
++ },
+ };
+
+ 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
+@@ -142,6 +142,7 @@ enum ath11k_hw_rev {
+ ATH11K_HW_WCN6855_HW20,
+ ATH11K_HW_WCN6855_HW21,
+ ATH11K_HW_WCN6750_HW10,
++ ATH11K_HW_IPQ5018_HW10,
+ };
+
+ enum ath11k_firmware_mode {
+@@ -230,6 +231,13 @@ struct ath11k_he {
+
+ #define MAX_RADIOS 3
+
++/* ipq5018 hw param macros */
++#define MAX_RADIOS_5018 1
++#define CE_CNT_5018 6
++#define TARGET_CE_CNT_5018 9
++#define SVC_CE_MAP_LEN_5018 17
++#define RXDMA_PER_PDEV_5018 1
++
+ enum {
+ WMI_HOST_TP_SCALE_MAX = 0,
+ WMI_HOST_TP_SCALE_50 = 1,
+++ /dev/null
-From 950b43f8bd8a4d476d2da6d2a083a89bcd3c90d7 Mon Sep 17 00:00:00 2001
-Date: Tue, 29 Nov 2022 19:55:32 +0530
-Subject: [PATCH] wifi: ath11k: fix monitor mode bringup crash
-
-When the interface is brought up in monitor mode, it leads
-to NULL pointer dereference crash. This crash happens when
-the packet type is extracted for a SKB. This extraction
-which is present in the received msdu delivery path,is
-not needed for the monitor ring packets since they are
-all RAW packets. Hence appending the flags with
-"RX_FLAG_ONLY_MONITOR" to skip that extraction.
-
-Observed calltrace:
-
-Unable to handle kernel NULL pointer dereference at virtual address
-0000000000000064
-Mem abort info:
- ESR = 0x0000000096000004
- EC = 0x25: DABT (current EL), IL = 32 bits
- SET = 0, FnV = 0
- EA = 0, S1PTW = 0
- FSC = 0x04: level 0 translation fault
-Data abort info:
- ISV = 0, ISS = 0x00000004
- CM = 0, WnR = 0
-user pgtable: 4k pages, 48-bit VAs, pgdp=0000000048517000
-[0000000000000064] pgd=0000000000000000, p4d=0000000000000000
-Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
-Modules linked in: ath11k_pci ath11k qmi_helpers
-CPU: 2 PID: 1781 Comm: napi/-271 Not tainted
-6.1.0-rc5-wt-ath-656295-gef907406320c-dirty #6
-Hardware name: Qualcomm Technologies, Inc. IPQ8074/AP-HK10-C2 (DT)
-pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
-pc : ath11k_hw_qcn9074_rx_desc_get_decap_type+0x34/0x60 [ath11k]
-lr : ath11k_hw_qcn9074_rx_desc_get_decap_type+0x5c/0x60 [ath11k]
-sp : ffff80000ef5bb10
-x29: ffff80000ef5bb10 x28: 0000000000000000 x27: ffff000007baafa0
-x26: ffff000014a91ed0 x25: 0000000000000000 x24: 0000000000000000
-x23: ffff800002b77378 x22: ffff000014a91ec0 x21: ffff000006c8d600
-x20: 0000000000000000 x19: ffff800002b77740 x18: 0000000000000006
-x17: 736564203634343a x16: 656e694c20657079 x15: 0000000000000143
-x14: 00000000ffffffea x13: ffff80000ef5b8b8 x12: ffff80000ef5b8c8
-x11: ffff80000a591d30 x10: ffff80000a579d40 x9 : c0000000ffffefff
-x8 : 0000000000000003 x7 : 0000000000017fe8 x6 : ffff80000a579ce8
-x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
-x2 : 3a35ec12ed7f8900 x1 : 0000000000000000 x0 : 0000000000000052
-Call trace:
- ath11k_hw_qcn9074_rx_desc_get_decap_type+0x34/0x60 [ath11k]
- ath11k_dp_rx_deliver_msdu.isra.42+0xa4/0x3d0 [ath11k]
- ath11k_dp_rx_mon_deliver.isra.43+0x2f8/0x458 [ath11k]
- ath11k_dp_rx_process_mon_rings+0x310/0x4c0 [ath11k]
- ath11k_dp_service_srng+0x234/0x338 [ath11k]
- ath11k_pcic_ext_grp_napi_poll+0x30/0xb8 [ath11k]
- __napi_poll+0x5c/0x190
- napi_threaded_poll+0xf0/0x118
- kthread+0xf4/0x110
- ret_from_fork+0x10/0x20
-
-Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
-Link: https://bugzilla.kernel.org/show_bug.cgi?id=216573
----
- drivers/net/wireless/ath/ath11k/dp_rx.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/wireless/ath/ath11k/dp_rx.c
-+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
-@@ -5022,6 +5022,7 @@ static int ath11k_dp_rx_mon_deliver(stru
- } else {
- rxs->flag |= RX_FLAG_ALLOW_SAME_PN;
- }
-+ rxs->flag |= RX_FLAG_ONLY_MONITOR;
- ath11k_update_radiotap(ar, ppduinfo, mon_skb, rxs);
-
- ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb, rxs);
--- /dev/null
+From 26af7aabd2d8225c6b2056234626ba5099610871 Mon Sep 17 00:00:00 2001
+Date: Fri, 2 Dec 2022 23:37:14 +0200
+Subject: [PATCH] wifi: ath11k: update ce configurations for IPQ5018
+
+IPQ5018 is a single pdev device. Update host
+and target CE configurations accordingly.
+
+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1
+
+---
+ drivers/net/wireless/ath/ath11k/core.c | 4 +
+ drivers/net/wireless/ath/ath11k/core.h | 3 +
+ drivers/net/wireless/ath/ath11k/hw.c | 191 +++++++++++++++++++++++++
+ 3 files changed, 198 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -630,6 +630,10 @@ static const struct ath11k_hw_params ath
+ .internal_sleep_clock = 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,
+ .rxdma1_enable = true,
+ .num_rxmda_per_pdev = RXDMA_PER_PDEV_5018,
+ .rx_mac_buf_ring = false,
+--- a/drivers/net/wireless/ath/ath11k/core.h
++++ b/drivers/net/wireless/ath/ath11k/core.h
+@@ -1146,6 +1146,9 @@ extern const struct service_to_pipe ath1
+ extern const struct ce_pipe_config ath11k_target_ce_config_wlan_qca6390[];
+ extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qca6390[];
+
++extern const struct ce_pipe_config ath11k_target_ce_config_wlan_ipq5018[];
++extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq5018[];
++
+ extern const struct ce_pipe_config ath11k_target_ce_config_wlan_qcn9074[];
+ extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qcn9074[];
+ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab);
+--- a/drivers/net/wireless/ath/ath11k/hw.c
++++ b/drivers/net/wireless/ath/ath11k/hw.c
+@@ -1972,6 +1972,197 @@ const struct ath11k_hw_ring_mask ath11k_
+ },
+ };
+
++/* 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 */
++ {
++ .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_OUT),
++ .nentries = __cpu_to_le32(32),
++ .nbytes_max = __cpu_to_le32(2048),
++ .flags = __cpu_to_le32(0x2000),
++ .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),
++ },
++};
++
++/* Map from service/endpoint to Copy Engine for IPQ5018.
++ * This table is derived from the CE TABLE, above.
++ * It is passed to the Target at startup for use by firmware.
++ */
++const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq5018[] = {
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
++ .pipenum = __cpu_to_le32(3),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
++ .pipenum = __cpu_to_le32(2),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
++ .pipenum = __cpu_to_le32(3),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
++ .pipenum = __cpu_to_le32(2),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
++ .pipenum = __cpu_to_le32(3),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
++ .pipenum = __cpu_to_le32(2),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
++ .pipenum = __cpu_to_le32(3),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
++ .pipenum = __cpu_to_le32(2),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
++ .pipenum = __cpu_to_le32(3),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
++ .pipenum = __cpu_to_le32(2),
++ },
++
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
++ .pipenum = __cpu_to_le32(0),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
++ .pipenum = __cpu_to_le32(1),
++ },
++
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS),
++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
++ .pipenum = __cpu_to_le32(0),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS),
++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
++ .pipenum = __cpu_to_le32(1),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
++ .pipenum = __cpu_to_le32(4),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
++ .pipenum = __cpu_to_le32(1),
++ },
++ {
++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_PKT_LOG),
++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
++ .pipenum = __cpu_to_le32(5),
++ },
++
++ /* (Additions here) */
++
++ { /* terminator entry */ }
++};
++
+ const struct ath11k_hw_regs ipq8074_regs = {
+ /* SW2TCL(x) R0 ring configuration address */
+ .hal_tcl1_ring_base_lsb = 0x00000510,
+++ /dev/null
-From 323d91d4684d238f6bc3693fed93caf795378fe0 Mon Sep 17 00:00:00 2001
-Date: Thu, 22 Dec 2022 19:15:59 +0200
-Subject: [PATCH] wifi: ath11k: debugfs: fix to work with multiple PCI devices
-
-ath11k fails to load if there are multiple ath11k PCI devices with same name:
-
- ath11k_pci 0000:01:00.0: Hardware name qcn9074 hw1.0
- debugfs: Directory 'ath11k' with parent '/' already present!
- ath11k_pci 0000:01:00.0: failed to create ath11k debugfs
- ath11k_pci 0000:01:00.0: failed to create soc core: -17
- ath11k_pci 0000:01:00.0: failed to init core: -17
- ath11k_pci: probe of 0000:01:00.0 failed with error -17
-
-Fix this by creating a directory for each ath11k device using schema
-<bus>-<devname>, for example "pci-0000:06:00.0". This directory created under
-the top-level ath11k directory, for example /sys/kernel/debug/ath11k.
-
-The reference to the toplevel ath11k directory is not stored anymore within ath11k, instead
-it's retrieved using debugfs_lookup(). If the directory does not exist it will
-be created. After the last directory from the ath11k directory is removed, for
-example when doing rmmod ath11k, the empty ath11k directory is left in place,
-it's a minor cosmetic issue anyway.
-
-Here's an example hierarchy with one WCN6855:
-
-ath11k
-`-- pci-0000:06:00.0
- |-- mac0
- | |-- dfs_block_radar_events
- | |-- dfs_simulate_radar
- | |-- ext_rx_stats
- | |-- ext_tx_stats
- | |-- fw_dbglog_config
- | |-- fw_stats
- | | |-- beacon_stats
- | | |-- pdev_stats
- | | `-- vdev_stats
- | |-- htt_stats
- | |-- htt_stats_reset
- | |-- htt_stats_type
- | `-- pktlog_filter
- |-- simulate_fw_crash
- `-- soc_dp_stats
-
-I didn't have a test setup where I could connect multiple ath11k devices to the
-same the host, so I have only tested this with one device.
-
-Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.9
-Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
-Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
-
----
- drivers/net/wireless/ath/ath11k/core.h | 1 -
- drivers/net/wireless/ath/ath11k/debugfs.c | 48 +++++++++++++++++++----
- 2 files changed, 40 insertions(+), 9 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/core.h
-+++ b/drivers/net/wireless/ath/ath11k/core.h
-@@ -912,7 +912,6 @@ struct ath11k_base {
- enum ath11k_dfs_region dfs_region;
- #ifdef CPTCFG_ATH11K_DEBUGFS
- struct dentry *debugfs_soc;
-- struct dentry *debugfs_ath11k;
- #endif
- struct ath11k_soc_dp_stats soc_stats;
-
---- a/drivers/net/wireless/ath/ath11k/debugfs.c
-+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
-@@ -976,10 +976,6 @@ int ath11k_debugfs_pdev_create(struct at
- if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
- return 0;
-
-- ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k);
-- if (IS_ERR(ab->debugfs_soc))
-- return PTR_ERR(ab->debugfs_soc);
--
- debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
- &fops_simulate_fw_crash);
-
-@@ -1001,15 +997,51 @@ void ath11k_debugfs_pdev_destroy(struct
-
- int ath11k_debugfs_soc_create(struct ath11k_base *ab)
- {
-- ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
-+ struct dentry *root;
-+ bool dput_needed;
-+ char name[64];
-+ int ret;
-+
-+ root = debugfs_lookup("ath11k", NULL);
-+ if (!root) {
-+ root = debugfs_create_dir("ath11k", NULL);
-+ if (IS_ERR_OR_NULL(root))
-+ return PTR_ERR(root);
-+
-+ dput_needed = false;
-+ } else {
-+ /* a dentry from lookup() needs dput() after we don't use it */
-+ dput_needed = true;
-+ }
-+
-+ scnprintf(name, sizeof(name), "%s-%s", ath11k_bus_str(ab->hif.bus),
-+ dev_name(ab->dev));
-+
-+ ab->debugfs_soc = debugfs_create_dir(name, root);
-+ if (IS_ERR_OR_NULL(ab->debugfs_soc)) {
-+ ret = PTR_ERR(ab->debugfs_soc);
-+ goto out;
-+ }
-+
-+ ret = 0;
-+
-+out:
-+ if (dput_needed)
-+ dput(root);
-
-- return PTR_ERR_OR_ZERO(ab->debugfs_ath11k);
-+ return ret;
- }
-
- void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
- {
-- debugfs_remove_recursive(ab->debugfs_ath11k);
-- ab->debugfs_ath11k = NULL;
-+ debugfs_remove_recursive(ab->debugfs_soc);
-+ ab->debugfs_soc = NULL;
-+
-+ /* We are not removing ath11k directory on purpose, even if it
-+ * would be empty. This simplifies the directory handling and it's
-+ * a minor cosmetic issue to leave an empty ath11k directory to
-+ * debugfs.
-+ */
- }
- EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
-
--- /dev/null
+From b42b3678c91f3ca6e0888bf5a15c1e8678fd5f2d Mon Sep 17 00:00:00 2001
+Date: Fri, 2 Dec 2022 23:37:14 +0200
+Subject: [PATCH] wifi: ath11k: remap ce register space for IPQ5018
+
+In IPQ5018 ce register space is moved out of wcss unlike
+ipq8074 or ipq6018 and the space is not contiguous,
+hence remap the CE registers to a new space to access them.
+
+Register read/write is modified to check if the register to be written
+falls in the CE register space and corresponding register is written.
+Also adjust the interrupt register address to ce irq enable/disable.
+
+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1
+
+---
+ drivers/net/wireless/ath/ath11k/ahb.c | 44 ++++++++++++++++++++++----
+ drivers/net/wireless/ath/ath11k/ce.h | 16 ++++++++++
+ drivers/net/wireless/ath/ath11k/core.c | 8 +++++
+ drivers/net/wireless/ath/ath11k/core.h | 1 +
+ drivers/net/wireless/ath/ath11k/hal.c | 17 ++++++----
+ drivers/net/wireless/ath/ath11k/hal.h | 5 +++
+ drivers/net/wireless/ath/ath11k/hw.c | 17 ++++++++++
+ drivers/net/wireless/ath/ath11k/hw.h | 9 ++++++
+ drivers/net/wireless/ath/ath11k/pci.c | 2 ++
+ 9 files changed, 107 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -267,30 +267,42 @@ static void ath11k_ahb_clearbit32(struct
+ static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
+ {
+ const struct ce_attr *ce_attr;
++ const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr;
++ u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr;
++
++ ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab);
++ ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab);
++ ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab);
+
+ ce_attr = &ab->hw_params.host_ce_config[ce_id];
+ if (ce_attr->src_nentries)
+- ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
++ ath11k_ahb_setbit32(ab, ce_id, ie1_reg_addr);
+
+ if (ce_attr->dest_nentries) {
+- ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
++ ath11k_ahb_setbit32(ab, ce_id, ie2_reg_addr);
+ ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
+- CE_HOST_IE_3_ADDRESS);
++ ie3_reg_addr);
+ }
+ }
+
+ static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
+ {
+ const struct ce_attr *ce_attr;
++ const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr;
++ u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr;
++
++ ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab);
++ ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab);
++ ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab);
+
+ ce_attr = &ab->hw_params.host_ce_config[ce_id];
+ if (ce_attr->src_nentries)
+- ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
++ ath11k_ahb_clearbit32(ab, ce_id, ie1_reg_addr);
+
+ if (ce_attr->dest_nentries) {
+- ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
++ ath11k_ahb_clearbit32(ab, ce_id, ie2_reg_addr);
+ ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
+- CE_HOST_IE_3_ADDRESS);
++ ie3_reg_addr);
+ }
+ }
+
+@@ -1142,10 +1154,26 @@ static int ath11k_ahb_probe(struct platf
+ goto err_core_free;
+ }
+
++ ab->mem_ce = ab->mem;
++
+ ret = ath11k_core_pre_init(ab);
+ if (ret)
+ goto err_core_free;
+
++ if (ab->hw_params.ce_remap) {
++ const struct ce_remap *ce_remap = ab->hw_params.ce_remap;
++ /* ce register space is moved out of wcss unlike ipq8074 or ipq6018
++ * and the space is not contiguous, hence remapping the CE registers
++ * to a new space for accessing them.
++ */
++ ab->mem_ce = ioremap(ce_remap->base, ce_remap->size);
++ if (IS_ERR(ab->mem_ce)) {
++ dev_err(&pdev->dev, "ce ioremap error\n");
++ ret = -ENOMEM;
++ goto err_core_free;
++ }
++ }
++
+ ret = ath11k_ahb_setup_resources(ab);
+ if (ret)
+ goto err_core_free;
+@@ -1236,6 +1264,10 @@ static void ath11k_ahb_free_resources(st
+ ath11k_ahb_release_smp2p_handle(ab);
+ ath11k_ahb_fw_resource_deinit(ab);
+ ath11k_ce_free_pipes(ab);
++
++ if (ab->hw_params.ce_remap)
++ iounmap(ab->mem_ce);
++
+ ath11k_core_free(ab);
+ platform_set_drvdata(pdev, NULL);
+ }
+--- a/drivers/net/wireless/ath/ath11k/ce.h
++++ b/drivers/net/wireless/ath/ath11k/ce.h
+@@ -49,6 +49,11 @@ void ath11k_ce_byte_swap(void *mem, u32
+ #define CE_HOST_IE_2_ADDRESS 0x00A18040
+ #define CE_HOST_IE_3_ADDRESS CE_HOST_IE_ADDRESS
+
++/* CE IE registers are different for IPQ5018 */
++#define CE_HOST_IPQ5018_IE_ADDRESS 0x0841804C
++#define CE_HOST_IPQ5018_IE_2_ADDRESS 0x08418050
++#define CE_HOST_IPQ5018_IE_3_ADDRESS CE_HOST_IPQ5018_IE_ADDRESS
++
+ #define CE_HOST_IE_3_SHIFT 0xC
+
+ #define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1) & (nentries_mask))
+@@ -84,6 +89,17 @@ struct ce_pipe_config {
+ __le32 reserved;
+ };
+
++struct ce_ie_addr {
++ u32 ie1_reg_addr;
++ u32 ie2_reg_addr;
++ u32 ie3_reg_addr;
++};
++
++struct ce_remap {
++ u32 base;
++ u32 size;
++};
++
+ struct ce_attr {
+ /* CE_ATTR_* values */
+ unsigned int flags;
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -54,6 +54,7 @@ static const struct ath11k_hw_params ath
+ .target_ce_count = 11,
+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
+ .svc_to_ce_map_len = 21,
++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
+ .single_pdev_only = false,
+ .rxdma1_enable = true,
+ .num_rxmda_per_pdev = 1,
+@@ -137,6 +138,7 @@ static const struct ath11k_hw_params ath
+ .target_ce_count = 11,
+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
+ .svc_to_ce_map_len = 19,
++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
+ .single_pdev_only = false,
+ .rxdma1_enable = true,
+ .num_rxmda_per_pdev = 1,
+@@ -218,6 +220,7 @@ static const struct ath11k_hw_params ath
+ .target_ce_count = 9,
+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
+ .svc_to_ce_map_len = 14,
++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
+ .single_pdev_only = true,
+ .rxdma1_enable = false,
+ .num_rxmda_per_pdev = 2,
+@@ -301,6 +304,7 @@ static const struct ath11k_hw_params ath
+ .target_ce_count = 9,
+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074,
+ .svc_to_ce_map_len = 18,
++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
+ .rxdma1_enable = true,
+ .num_rxmda_per_pdev = 1,
+ .rx_mac_buf_ring = false,
+@@ -381,6 +385,7 @@ static const struct ath11k_hw_params ath
+ .target_ce_count = 9,
+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
+ .svc_to_ce_map_len = 14,
++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
+ .single_pdev_only = true,
+ .rxdma1_enable = false,
+ .num_rxmda_per_pdev = 2,
+@@ -546,6 +551,7 @@ static const struct ath11k_hw_params ath
+ .target_ce_count = 9,
+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
+ .svc_to_ce_map_len = 14,
++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
+ .single_pdev_only = true,
+ .rxdma1_enable = false,
+ .num_rxmda_per_pdev = 1,
+@@ -634,6 +640,8 @@ static const struct ath11k_hw_params ath
+ .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,
++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq5018,
++ .ce_remap = &ath11k_ce_remap_ipq5018,
+ .rxdma1_enable = true,
+ .num_rxmda_per_pdev = RXDMA_PER_PDEV_5018,
+ .rx_mac_buf_ring = false,
+--- a/drivers/net/wireless/ath/ath11k/core.h
++++ b/drivers/net/wireless/ath/ath11k/core.h
+@@ -851,6 +851,7 @@ struct ath11k_base {
+ struct ath11k_dp dp;
+
+ void __iomem *mem;
++ void __iomem *mem_ce;
+ unsigned long mem_len;
+
+ struct {
+--- a/drivers/net/wireless/ath/ath11k/hal.c
++++ b/drivers/net/wireless/ath/ath11k/hal.c
+@@ -1220,16 +1220,20 @@ static int ath11k_hal_srng_create_config
+ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP;
+
+ s = &hal->srng_config[HAL_CE_SRC];
+- s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
+- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP;
++ s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB +
++ ATH11K_CE_OFFSET(ab);
++ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP +
++ ATH11K_CE_OFFSET(ab);
+ s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
+ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
+ s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
+ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
+
+ s = &hal->srng_config[HAL_CE_DST];
+- s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
+- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP;
++ s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB +
++ ATH11K_CE_OFFSET(ab);
++ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP +
++ ATH11K_CE_OFFSET(ab);
+ s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
+ HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
+ s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
+@@ -1237,8 +1241,9 @@ static int ath11k_hal_srng_create_config
+
+ s = &hal->srng_config[HAL_CE_DST_STATUS];
+ s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) +
+- HAL_CE_DST_STATUS_RING_BASE_LSB;
+- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP;
++ HAL_CE_DST_STATUS_RING_BASE_LSB + ATH11K_CE_OFFSET(ab);
++ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP +
++ ATH11K_CE_OFFSET(ab);
+ s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
+ HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
+ s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
+--- a/drivers/net/wireless/ath/ath11k/hal.h
++++ b/drivers/net/wireless/ath/ath11k/hal.h
+@@ -321,6 +321,10 @@ struct ath11k_base;
+ #define HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff
+ #define HAL_RXDMA_RING_MAX_SIZE 0x0000ffff
+
++/* IPQ5018 ce registers */
++#define HAL_IPQ5018_CE_WFSS_REG_BASE 0x08400000
++#define HAL_IPQ5018_CE_SIZE 0x200000
++
+ /* Add any other errors here and return them in
+ * ath11k_hal_rx_desc_get_err().
+ */
+@@ -519,6 +523,7 @@ enum hal_srng_dir {
+ #define HAL_SRNG_FLAGS_MSI_INTR 0x00020000
+ #define HAL_SRNG_FLAGS_CACHED 0x20000000
+ #define HAL_SRNG_FLAGS_LMAC_RING 0x80000000
++#define HAL_SRNG_FLAGS_REMAP_CE_RING 0x10000000
+
+ #define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1)
+ #define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10)
+--- a/drivers/net/wireless/ath/ath11k/hw.c
++++ b/drivers/net/wireless/ath/ath11k/hw.c
+@@ -2163,6 +2163,23 @@ const struct service_to_pipe ath11k_targ
+ { /* terminator entry */ }
+ };
+
++const struct ce_ie_addr ath11k_ce_ie_addr_ipq8074 = {
++ .ie1_reg_addr = CE_HOST_IE_ADDRESS,
++ .ie2_reg_addr = CE_HOST_IE_2_ADDRESS,
++ .ie3_reg_addr = CE_HOST_IE_3_ADDRESS,
++};
++
++const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018 = {
++ .ie1_reg_addr = CE_HOST_IPQ5018_IE_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
++ .ie2_reg_addr = CE_HOST_IPQ5018_IE_2_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
++ .ie3_reg_addr = CE_HOST_IPQ5018_IE_3_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
++};
++
++const struct ce_remap ath11k_ce_remap_ipq5018 = {
++ .base = HAL_IPQ5018_CE_WFSS_REG_BASE,
++ .size = HAL_IPQ5018_CE_SIZE,
++};
++
+ const struct ath11k_hw_regs ipq8074_regs = {
+ /* SW2TCL(x) R0 ring configuration address */
+ .hal_tcl1_ring_base_lsb = 0x00000510,
+--- a/drivers/net/wireless/ath/ath11k/hw.h
++++ b/drivers/net/wireless/ath/ath11k/hw.h
+@@ -80,6 +80,8 @@
+ #define ATH11K_M3_FILE "m3.bin"
+ #define ATH11K_REGDB_FILE_NAME "regdb.bin"
+
++#define ATH11K_CE_OFFSET(ab) (ab->mem_ce - ab->mem)
++
+ enum ath11k_hw_rate_cck {
+ ATH11K_HW_RATE_CCK_LP_11M = 0,
+ ATH11K_HW_RATE_CCK_LP_5_5M,
+@@ -158,6 +160,8 @@ struct ath11k_hw_params {
+ u32 target_ce_count;
+ const struct service_to_pipe *svc_to_ce_map;
+ u32 svc_to_ce_map_len;
++ const struct ce_ie_addr *ce_ie_addr;
++ const struct ce_remap *ce_remap;
+
+ bool single_pdev_only;
+
+@@ -277,6 +281,11 @@ extern const struct ath11k_hw_ring_mask
+ 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 ce_ie_addr ath11k_ce_ie_addr_ipq8074;
++extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018;
++
++extern const struct ce_remap ath11k_ce_remap_ipq5018;
++
+ extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074;
+ extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390;
+ extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_wcn6750;
+--- a/drivers/net/wireless/ath/ath11k/pci.c
++++ b/drivers/net/wireless/ath/ath11k/pci.c
+@@ -543,6 +543,8 @@ static int ath11k_pci_claim(struct ath11
+ goto clear_master;
+ }
+
++ ab->mem_ce = ab->mem;
++
+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot pci_mem 0x%pK\n", ab->mem);
+ return 0;
+
--- /dev/null
+From 711b80acbdfb9667a9cf8374e13320a6e624ce73 Mon Sep 17 00:00:00 2001
+Date: Fri, 2 Dec 2022 23:37:14 +0200
+Subject: [PATCH] wifi: ath11k: update hal srng regs for IPQ5018
+
+IPQ5018 hal srng register address & offsets are not
+similar to IPQ8074/IPQ6018/QCN9074, hence define a
+new set of srng register group data for IPQ5018.
+
+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1
+
+---
+ drivers/net/wireless/ath/ath11k/core.c | 1 +
+ drivers/net/wireless/ath/ath11k/hw.c | 79 ++++++++++++++++++++++++++
+ drivers/net/wireless/ath/ath11k/hw.h | 1 +
+ 3 files changed, 81 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -634,6 +634,7 @@ static const struct ath11k_hw_params ath
+ .max_fft_bins = 1024,
+ },
+ .internal_sleep_clock = false,
++ .regs = &ipq5018_regs,
+ .host_ce_config = ath11k_host_ce_config_qcn9074,
+ .ce_count = CE_CNT_5018,
+ .target_ce_config = ath11k_target_ce_config_wlan_ipq5018,
+--- a/drivers/net/wireless/ath/ath11k/hw.c
++++ b/drivers/net/wireless/ath/ath11k/hw.c
+@@ -2645,6 +2645,85 @@ static const struct ath11k_hw_tcl2wbm_rb
+ },
+ };
+
++const struct ath11k_hw_regs ipq5018_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 = 0x08400000
++ - HAL_IPQ5018_CE_WFSS_REG_BASE,
++ .hal_seq_wcss_umac_ce0_dst_reg = 0x08401000
++ - HAL_IPQ5018_CE_WFSS_REG_BASE,
++ .hal_seq_wcss_umac_ce1_src_reg = 0x08402000
++ - HAL_IPQ5018_CE_WFSS_REG_BASE,
++ .hal_seq_wcss_umac_ce1_dst_reg = 0x08403000
++ - HAL_IPQ5018_CE_WFSS_REG_BASE,
++
++ /* 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
+@@ -415,6 +415,7 @@ extern const struct ath11k_hw_regs qca63
+ extern const struct ath11k_hw_regs qcn9074_regs;
+ extern const struct ath11k_hw_regs wcn6855_regs;
+ extern const struct ath11k_hw_regs wcn6750_regs;
++extern const struct ath11k_hw_regs ipq5018_regs;
+
+ static inline const char *ath11k_bd_ie_type_str(enum ath11k_bd_ie_type type)
+ {
--- /dev/null
+From ba60f2793d3a37a00da14bb56a26558a902d2831 Mon Sep 17 00:00:00 2001
+Date: Fri, 2 Dec 2022 23:37:14 +0200
+Subject: [PATCH] wifi: ath11k: initialize hw_ops for IPQ5018
+
+The ipq5018_ops is initialized for IPQ5018. This is different from
+other platforms.
+
+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1
+
+---
+ drivers/net/wireless/ath/ath11k/core.c | 1 +
+ drivers/net/wireless/ath/ath11k/hw.c | 40 ++++++++++++++++++++++++++
+ drivers/net/wireless/ath/ath11k/hw.h | 1 +
+ 3 files changed, 42 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -635,6 +635,7 @@ static const struct ath11k_hw_params ath
+ },
+ .internal_sleep_clock = false,
+ .regs = &ipq5018_regs,
++ .hw_ops = &ipq5018_ops,
+ .host_ce_config = ath11k_host_ce_config_qcn9074,
+ .ce_count = CE_CNT_5018,
+ .target_ce_config = ath11k_target_ce_config_wlan_ipq5018,
+--- a/drivers/net/wireless/ath/ath11k/hw.c
++++ b/drivers/net/wireless/ath/ath11k/hw.c
+@@ -1084,6 +1084,46 @@ const struct ath11k_hw_ops wcn6750_ops =
+ .get_ring_selector = ath11k_hw_wcn6750_get_tcl_ring_selector,
+ };
+
++/* IPQ5018 hw ops is similar to QCN9074 except for the dest ring remap */
++const struct ath11k_hw_ops ipq5018_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,
++ .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,
++ .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,
++ .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,
++
++};
++
+ #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
+@@ -275,6 +275,7 @@ extern const struct ath11k_hw_ops qca639
+ extern const struct ath11k_hw_ops qcn9074_ops;
+ 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_ring_mask ath11k_hw_ring_mask_ipq8074;
+ extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390;
--- /dev/null
+From 69968f88f1770d61cae0febef805fd00d66cf6a1 Mon Sep 17 00:00:00 2001
+Date: Fri, 2 Dec 2022 23:37:15 +0200
+Subject: [PATCH] wifi: ath11k: add new hw ops for IPQ5018 to get rx dest ring
+ hashmap
+
+The Destination ring control register is different
+for IPQ5018 when compared to IPQ8074/IPQ6018/QCN9074.
+Hence create a new hw ops to fetch the hash ring map
+for different device variants. ipq5018 hw ops
+is similar to qcn9074 except for this change, so reuse
+all the qcn9074 ops for ipq5018.
+
+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1
+
+---
+ drivers/net/wireless/ath/ath11k/hw.c | 44 ++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath11k/hw.c
++++ b/drivers/net/wireless/ath/ath11k/hw.c
+@@ -791,6 +791,49 @@ static void ath11k_hw_wcn6855_reo_setup(
+ ring_hash_map);
+ }
+
++static void ath11k_hw_ipq5018_reo_setup(struct ath11k_base *ab)
++{
++ u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG;
++ u32 val;
++
++ /* Each hash entry uses three bits to map to a particular ring. */
++ u32 ring_hash_map = HAL_HASH_ROUTING_RING_SW1 << 0 |
++ HAL_HASH_ROUTING_RING_SW2 << 4 |
++ HAL_HASH_ROUTING_RING_SW3 << 8 |
++ HAL_HASH_ROUTING_RING_SW4 << 12 |
++ HAL_HASH_ROUTING_RING_SW1 << 16 |
++ HAL_HASH_ROUTING_RING_SW2 << 20 |
++ HAL_HASH_ROUTING_RING_SW3 << 24 |
++ HAL_HASH_ROUTING_RING_SW4 << 28;
++
++ val = ath11k_hif_read32(ab, reo_base + HAL_REO1_GEN_ENABLE);
++
++ val &= ~HAL_REO1_GEN_ENABLE_FRAG_DST_RING;
++ val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_FRAG_DST_RING,
++ HAL_SRNG_RING_ID_REO2SW1) |
++ FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE, 1) |
++ FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1);
++ ath11k_hif_write32(ab, reo_base + HAL_REO1_GEN_ENABLE, val);
++
++ ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0(ab),
++ HAL_DEFAULT_REO_TIMEOUT_USEC);
++ ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_1(ab),
++ HAL_DEFAULT_REO_TIMEOUT_USEC);
++ ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_2(ab),
++ HAL_DEFAULT_REO_TIMEOUT_USEC);
++ ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab),
++ HAL_DEFAULT_REO_TIMEOUT_USEC);
++
++ ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_0,
++ ring_hash_map);
++ ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_1,
++ ring_hash_map);
++ ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2,
++ ring_hash_map);
++ ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3,
++ ring_hash_map);
++}
++
+ static u16 ath11k_hw_ipq8074_mpdu_info_get_peerid(u8 *tlv_data)
+ {
+ u16 peer_id = 0;
+@@ -1117,6 +1160,7 @@ const struct ath11k_hw_ops ipq5018_ops =
+ .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,
+ .rx_desc_get_attention = ath11k_hw_qcn9074_rx_desc_get_attention,
++ .reo_setup = ath11k_hw_ipq5018_reo_setup,
+ .rx_desc_get_msdu_payload = ath11k_hw_qcn9074_rx_desc_get_msdu_payload,
+ .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid,
+ .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid,
--- /dev/null
+From 25edca7bb18a2a40cc7e54c6f522e9b3c917e2c5 Mon Sep 17 00:00:00 2001
+Date: Fri, 2 Dec 2022 23:37:15 +0200
+Subject: [PATCH] wifi: ath11k: add ipq5018 device support
+
+ipq5018 is a ahb 2ghz device, enable the compatible support for
+ipq5018 in ahb.
+
+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1
+
+---
+ drivers/net/wireless/ath/ath11k/ahb.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -32,6 +32,9 @@ static const struct of_device_id ath11k_
+ { .compatible = "qcom,wcn6750-wifi",
+ .data = (void *)ATH11K_HW_WCN6750_HW10,
+ },
++ { .compatible = "qcom,ipq5018-wifi",
++ .data = (void *)ATH11K_HW_IPQ5018_HW10,
++ },
+ { }
+ };
+
--- /dev/null
+From d45daa6d1a8da080f1b516c570a8428a7b9225e4 Mon Sep 17 00:00:00 2001
+Date: Tue, 6 Dec 2022 00:51:25 +0530
+Subject: [PATCH] wifi: ath11k: Fix scan request param frame size warning
+
+Following warning was observed
+
+drivers/net/wireless/ath/ath11k/mac.c:2351:1: warning: the frame
+size of 1184 bytes is larger than 1024 bytes [-Wframe-larger-than=]
+
+A local variable is declared with a size larger than 1024 bytes
+this causing a compilation warning. Change the local variable to
+heap memory to fix the warning.
+
+Tested-on: IPQ8074 AHB WLAN.HK.2.7.0.1-01701-QCAHKSWPL_SILICONZ-1 v2
+
+---
+ drivers/net/wireless/ath/ath11k/mac.c | 83 +++++++++++++++------------
+ 1 file changed, 45 insertions(+), 38 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -3612,7 +3612,7 @@ static int ath11k_mac_op_hw_scan(struct
+ struct ath11k *ar = hw->priv;
+ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
+ struct cfg80211_scan_request *req = &hw_req->req;
+- struct scan_req_params arg;
++ struct scan_req_params *arg = NULL;
+ int ret = 0;
+ int i;
+ u32 scan_timeout;
+@@ -3640,72 +3640,78 @@ static int ath11k_mac_op_hw_scan(struct
+ if (ret)
+ goto exit;
+
+- memset(&arg, 0, sizeof(arg));
+- ath11k_wmi_start_scan_init(ar, &arg);
+- arg.vdev_id = arvif->vdev_id;
+- arg.scan_id = ATH11K_SCAN_ID;
++ arg = kzalloc(sizeof(*arg), GFP_KERNEL);
++
++ if (!arg) {
++ ret = -ENOMEM;
++ goto exit;
++ }
++
++ ath11k_wmi_start_scan_init(ar, arg);
++ arg->vdev_id = arvif->vdev_id;
++ arg->scan_id = ATH11K_SCAN_ID;
+
+ if (req->ie_len) {
+- arg.extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL);
+- if (!arg.extraie.ptr) {
++ arg->extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL);
++ if (!arg->extraie.ptr) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+- arg.extraie.len = req->ie_len;
++ arg->extraie.len = req->ie_len;
+ }
+
+ if (req->n_ssids) {
+- arg.num_ssids = req->n_ssids;
+- for (i = 0; i < arg.num_ssids; i++) {
+- arg.ssid[i].length = req->ssids[i].ssid_len;
+- memcpy(&arg.ssid[i].ssid, req->ssids[i].ssid,
++ arg->num_ssids = req->n_ssids;
++ for (i = 0; i < arg->num_ssids; i++) {
++ arg->ssid[i].length = req->ssids[i].ssid_len;
++ memcpy(&arg->ssid[i].ssid, req->ssids[i].ssid,
+ req->ssids[i].ssid_len);
+ }
+ } else {
+- arg.scan_flags |= WMI_SCAN_FLAG_PASSIVE;
++ arg->scan_flags |= WMI_SCAN_FLAG_PASSIVE;
+ }
+
+ if (req->n_channels) {
+- arg.num_chan = req->n_channels;
+- arg.chan_list = kcalloc(arg.num_chan, sizeof(*arg.chan_list),
+- GFP_KERNEL);
++ arg->num_chan = req->n_channels;
++ arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list),
++ GFP_KERNEL);
+
+- if (!arg.chan_list) {
++ if (!arg->chan_list) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+- for (i = 0; i < arg.num_chan; i++)
+- arg.chan_list[i] = req->channels[i]->center_freq;
++ for (i = 0; i < arg->num_chan; i++)
++ arg->chan_list[i] = req->channels[i]->center_freq;
+ }
+
+ if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
+- arg.scan_f_add_spoofed_mac_in_probe = 1;
+- ether_addr_copy(arg.mac_addr.addr, req->mac_addr);
+- ether_addr_copy(arg.mac_mask.addr, req->mac_addr_mask);
++ arg->scan_f_add_spoofed_mac_in_probe = 1;
++ ether_addr_copy(arg->mac_addr.addr, req->mac_addr);
++ ether_addr_copy(arg->mac_mask.addr, req->mac_addr_mask);
+ }
+
+ /* if duration is set, default dwell times will be overwritten */
+ if (req->duration) {
+- arg.dwell_time_active = req->duration;
+- arg.dwell_time_active_2g = req->duration;
+- arg.dwell_time_active_6g = req->duration;
+- arg.dwell_time_passive = req->duration;
+- arg.dwell_time_passive_6g = req->duration;
+- arg.burst_duration = req->duration;
++ arg->dwell_time_active = req->duration;
++ arg->dwell_time_active_2g = req->duration;
++ arg->dwell_time_active_6g = req->duration;
++ arg->dwell_time_passive = req->duration;
++ arg->dwell_time_passive_6g = req->duration;
++ arg->burst_duration = req->duration;
+
+- scan_timeout = min_t(u32, arg.max_rest_time *
+- (arg.num_chan - 1) + (req->duration +
++ scan_timeout = min_t(u32, arg->max_rest_time *
++ (arg->num_chan - 1) + (req->duration +
+ ATH11K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) *
+- arg.num_chan, arg.max_scan_time);
++ arg->num_chan, arg->max_scan_time);
+ } else {
+- scan_timeout = arg.max_scan_time;
++ scan_timeout = arg->max_scan_time;
+ }
+
+ /* Add a margin to account for event/command processing */
+ scan_timeout += ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD;
+
+- ret = ath11k_start_scan(ar, &arg);
++ ret = ath11k_start_scan(ar, arg);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to start hw scan: %d\n", ret);
+ spin_lock_bh(&ar->data_lock);
+@@ -3717,10 +3723,11 @@ static int ath11k_mac_op_hw_scan(struct
+ msecs_to_jiffies(scan_timeout));
+
+ exit:
+- kfree(arg.chan_list);
+-
+- if (req->ie_len)
+- kfree(arg.extraie.ptr);
++ if (arg) {
++ kfree(arg->chan_list);
++ kfree(arg->extraie.ptr);
++ kfree(arg);
++ }
+
+ mutex_unlock(&ar->conf_mutex);
+
--- /dev/null
+From 950b43f8bd8a4d476d2da6d2a083a89bcd3c90d7 Mon Sep 17 00:00:00 2001
+Date: Tue, 29 Nov 2022 19:55:32 +0530
+Subject: [PATCH] wifi: ath11k: fix monitor mode bringup crash
+
+When the interface is brought up in monitor mode, it leads
+to NULL pointer dereference crash. This crash happens when
+the packet type is extracted for a SKB. This extraction
+which is present in the received msdu delivery path,is
+not needed for the monitor ring packets since they are
+all RAW packets. Hence appending the flags with
+"RX_FLAG_ONLY_MONITOR" to skip that extraction.
+
+Observed calltrace:
+
+Unable to handle kernel NULL pointer dereference at virtual address
+0000000000000064
+Mem abort info:
+ ESR = 0x0000000096000004
+ EC = 0x25: DABT (current EL), IL = 32 bits
+ SET = 0, FnV = 0
+ EA = 0, S1PTW = 0
+ FSC = 0x04: level 0 translation fault
+Data abort info:
+ ISV = 0, ISS = 0x00000004
+ CM = 0, WnR = 0
+user pgtable: 4k pages, 48-bit VAs, pgdp=0000000048517000
+[0000000000000064] pgd=0000000000000000, p4d=0000000000000000
+Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
+Modules linked in: ath11k_pci ath11k qmi_helpers
+CPU: 2 PID: 1781 Comm: napi/-271 Not tainted
+6.1.0-rc5-wt-ath-656295-gef907406320c-dirty #6
+Hardware name: Qualcomm Technologies, Inc. IPQ8074/AP-HK10-C2 (DT)
+pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : ath11k_hw_qcn9074_rx_desc_get_decap_type+0x34/0x60 [ath11k]
+lr : ath11k_hw_qcn9074_rx_desc_get_decap_type+0x5c/0x60 [ath11k]
+sp : ffff80000ef5bb10
+x29: ffff80000ef5bb10 x28: 0000000000000000 x27: ffff000007baafa0
+x26: ffff000014a91ed0 x25: 0000000000000000 x24: 0000000000000000
+x23: ffff800002b77378 x22: ffff000014a91ec0 x21: ffff000006c8d600
+x20: 0000000000000000 x19: ffff800002b77740 x18: 0000000000000006
+x17: 736564203634343a x16: 656e694c20657079 x15: 0000000000000143
+x14: 00000000ffffffea x13: ffff80000ef5b8b8 x12: ffff80000ef5b8c8
+x11: ffff80000a591d30 x10: ffff80000a579d40 x9 : c0000000ffffefff
+x8 : 0000000000000003 x7 : 0000000000017fe8 x6 : ffff80000a579ce8
+x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
+x2 : 3a35ec12ed7f8900 x1 : 0000000000000000 x0 : 0000000000000052
+Call trace:
+ ath11k_hw_qcn9074_rx_desc_get_decap_type+0x34/0x60 [ath11k]
+ ath11k_dp_rx_deliver_msdu.isra.42+0xa4/0x3d0 [ath11k]
+ ath11k_dp_rx_mon_deliver.isra.43+0x2f8/0x458 [ath11k]
+ ath11k_dp_rx_process_mon_rings+0x310/0x4c0 [ath11k]
+ ath11k_dp_service_srng+0x234/0x338 [ath11k]
+ ath11k_pcic_ext_grp_napi_poll+0x30/0xb8 [ath11k]
+ __napi_poll+0x5c/0x190
+ napi_threaded_poll+0xf0/0x118
+ kthread+0xf4/0x110
+ ret_from_fork+0x10/0x20
+
+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216573
+---
+ drivers/net/wireless/ath/ath11k/dp_rx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -5022,6 +5022,7 @@ static int ath11k_dp_rx_mon_deliver(stru
+ } else {
+ rxs->flag |= RX_FLAG_ALLOW_SAME_PN;
+ }
++ rxs->flag |= RX_FLAG_ONLY_MONITOR;
+ ath11k_update_radiotap(ar, ppduinfo, mon_skb, rxs);
+
+ ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb, rxs);
--- /dev/null
+From 323d91d4684d238f6bc3693fed93caf795378fe0 Mon Sep 17 00:00:00 2001
+Date: Thu, 22 Dec 2022 19:15:59 +0200
+Subject: [PATCH] wifi: ath11k: debugfs: fix to work with multiple PCI devices
+
+ath11k fails to load if there are multiple ath11k PCI devices with same name:
+
+ ath11k_pci 0000:01:00.0: Hardware name qcn9074 hw1.0
+ debugfs: Directory 'ath11k' with parent '/' already present!
+ ath11k_pci 0000:01:00.0: failed to create ath11k debugfs
+ ath11k_pci 0000:01:00.0: failed to create soc core: -17
+ ath11k_pci 0000:01:00.0: failed to init core: -17
+ ath11k_pci: probe of 0000:01:00.0 failed with error -17
+
+Fix this by creating a directory for each ath11k device using schema
+<bus>-<devname>, for example "pci-0000:06:00.0". This directory created under
+the top-level ath11k directory, for example /sys/kernel/debug/ath11k.
+
+The reference to the toplevel ath11k directory is not stored anymore within ath11k, instead
+it's retrieved using debugfs_lookup(). If the directory does not exist it will
+be created. After the last directory from the ath11k directory is removed, for
+example when doing rmmod ath11k, the empty ath11k directory is left in place,
+it's a minor cosmetic issue anyway.
+
+Here's an example hierarchy with one WCN6855:
+
+ath11k
+`-- pci-0000:06:00.0
+ |-- mac0
+ | |-- dfs_block_radar_events
+ | |-- dfs_simulate_radar
+ | |-- ext_rx_stats
+ | |-- ext_tx_stats
+ | |-- fw_dbglog_config
+ | |-- fw_stats
+ | | |-- beacon_stats
+ | | |-- pdev_stats
+ | | `-- vdev_stats
+ | |-- htt_stats
+ | |-- htt_stats_reset
+ | |-- htt_stats_type
+ | `-- pktlog_filter
+ |-- simulate_fw_crash
+ `-- soc_dp_stats
+
+I didn't have a test setup where I could connect multiple ath11k devices to the
+same the host, so I have only tested this with one device.
+
+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.9
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
+
+---
+ drivers/net/wireless/ath/ath11k/core.h | 1 -
+ drivers/net/wireless/ath/ath11k/debugfs.c | 48 +++++++++++++++++++----
+ 2 files changed, 40 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath11k/core.h
++++ b/drivers/net/wireless/ath/ath11k/core.h
+@@ -921,7 +921,6 @@ struct ath11k_base {
+ enum ath11k_dfs_region dfs_region;
+ #ifdef CPTCFG_ATH11K_DEBUGFS
+ struct dentry *debugfs_soc;
+- struct dentry *debugfs_ath11k;
+ #endif
+ struct ath11k_soc_dp_stats soc_stats;
+
+--- a/drivers/net/wireless/ath/ath11k/debugfs.c
++++ b/drivers/net/wireless/ath/ath11k/debugfs.c
+@@ -976,10 +976,6 @@ int ath11k_debugfs_pdev_create(struct at
+ if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
+ return 0;
+
+- ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k);
+- if (IS_ERR(ab->debugfs_soc))
+- return PTR_ERR(ab->debugfs_soc);
+-
+ debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
+ &fops_simulate_fw_crash);
+
+@@ -1001,15 +997,51 @@ void ath11k_debugfs_pdev_destroy(struct
+
+ int ath11k_debugfs_soc_create(struct ath11k_base *ab)
+ {
+- ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
++ struct dentry *root;
++ bool dput_needed;
++ char name[64];
++ int ret;
++
++ root = debugfs_lookup("ath11k", NULL);
++ if (!root) {
++ root = debugfs_create_dir("ath11k", NULL);
++ if (IS_ERR_OR_NULL(root))
++ return PTR_ERR(root);
++
++ dput_needed = false;
++ } else {
++ /* a dentry from lookup() needs dput() after we don't use it */
++ dput_needed = true;
++ }
++
++ scnprintf(name, sizeof(name), "%s-%s", ath11k_bus_str(ab->hif.bus),
++ dev_name(ab->dev));
++
++ ab->debugfs_soc = debugfs_create_dir(name, root);
++ if (IS_ERR_OR_NULL(ab->debugfs_soc)) {
++ ret = PTR_ERR(ab->debugfs_soc);
++ goto out;
++ }
++
++ ret = 0;
++
++out:
++ if (dput_needed)
++ dput(root);
+
+- return PTR_ERR_OR_ZERO(ab->debugfs_ath11k);
++ return ret;
+ }
+
+ void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
+ {
+- debugfs_remove_recursive(ab->debugfs_ath11k);
+- ab->debugfs_ath11k = NULL;
++ debugfs_remove_recursive(ab->debugfs_soc);
++ ab->debugfs_soc = NULL;
++
++ /* We are not removing ath11k directory on purpose, even if it
++ * would be empty. This simplifies the directory handling and it's
++ * a minor cosmetic issue to leave an empty ath11k directory to
++ * debugfs.
++ */
+ }
+ EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
+
--- /dev/null
+From a27c6a5853eb9d4f293b99be73a6891fe88263c7 Mon Sep 17 00:00:00 2001
+Date: Tue, 10 Jan 2023 15:30:57 +0200
+Subject: [PATCH] wifi: ath11k: Add support to configure FTM responder role
+
+Fine Timing Measurement(FTM) support is used to measure round trip
+time between two nodes.
+
+Enable FTM responder feature using hw_params on supported device.
+Since FTM functionality is offloaded to firmware, adding the
+interface allows user space to enable or disable FTM responder.
+Also add support for advertising the same in extended capabilities.
+
+QCA6390, WCN6855 and WCN6750 do not support this feature.
+
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+
+---
+ drivers/net/wireless/ath/ath11k/core.c | 8 ++++++++
+ drivers/net/wireless/ath/ath11k/core.h | 1 +
+ drivers/net/wireless/ath/ath11k/hw.h | 1 +
+ drivers/net/wireless/ath/ath11k/mac.c | 20 +++++++++++++++++++-
+ drivers/net/wireless/ath/ath11k/wmi.h | 1 +
+ 5 files changed, 30 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -116,6 +116,7 @@ static const struct ath11k_hw_params ath
+ .tcl_ring_retry = true,
+ .tx_ring_size = DP_TCL_DATA_RING_SIZE,
+ .smp2p_wow_exit = false,
++ .ftm_responder = true,
+ },
+ {
+ .hw_rev = ATH11K_HW_IPQ6018_HW10,
+@@ -198,6 +199,7 @@ static const struct ath11k_hw_params ath
+ .tx_ring_size = DP_TCL_DATA_RING_SIZE,
+ .smp2p_wow_exit = false,
+ .support_fw_mac_sequence = false,
++ .ftm_responder = true,
+ },
+ {
+ .name = "qca6390 hw2.0",
+@@ -282,6 +284,7 @@ static const struct ath11k_hw_params ath
+ .tx_ring_size = DP_TCL_DATA_RING_SIZE,
+ .smp2p_wow_exit = false,
+ .support_fw_mac_sequence = true,
++ .ftm_responder = false,
+ },
+ {
+ .name = "qcn9074 hw1.0",
+@@ -363,6 +366,7 @@ static const struct ath11k_hw_params ath
+ .tx_ring_size = DP_TCL_DATA_RING_SIZE,
+ .smp2p_wow_exit = false,
+ .support_fw_mac_sequence = false,
++ .ftm_responder = true,
+ },
+ {
+ .name = "wcn6855 hw2.0",
+@@ -447,6 +451,7 @@ static const struct ath11k_hw_params ath
+ .tx_ring_size = DP_TCL_DATA_RING_SIZE,
+ .smp2p_wow_exit = false,
+ .support_fw_mac_sequence = true,
++ .ftm_responder = false,
+ },
+ {
+ .name = "wcn6855 hw2.1",
+@@ -529,6 +534,7 @@ static const struct ath11k_hw_params ath
+ .tx_ring_size = DP_TCL_DATA_RING_SIZE,
+ .smp2p_wow_exit = false,
+ .support_fw_mac_sequence = true,
++ .ftm_responder = false,
+ },
+ {
+ .name = "wcn6750 hw1.0",
+@@ -609,6 +615,7 @@ static const struct ath11k_hw_params ath
+ .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750,
+ .smp2p_wow_exit = true,
+ .support_fw_mac_sequence = true,
++ .ftm_responder = false,
+ },
+ {
+ .hw_rev = ATH11K_HW_IPQ5018_HW10,
+@@ -688,6 +695,7 @@ static const struct ath11k_hw_params ath
+ .tx_ring_size = DP_TCL_DATA_RING_SIZE,
+ .smp2p_wow_exit = false,
+ .support_fw_mac_sequence = false,
++ .ftm_responder = true,
+ },
+ };
+
+--- a/drivers/net/wireless/ath/ath11k/core.h
++++ b/drivers/net/wireless/ath/ath11k/core.h
+@@ -346,6 +346,7 @@ struct ath11k_vif {
+
+ bool is_started;
+ bool is_up;
++ bool ftm_responder;
+ bool spectral_enabled;
+ bool ps;
+ u32 aid;
+--- a/drivers/net/wireless/ath/ath11k/hw.h
++++ b/drivers/net/wireless/ath/ath11k/hw.h
+@@ -224,6 +224,7 @@ struct ath11k_hw_params {
+ u32 tx_ring_size;
+ bool smp2p_wow_exit;
+ bool support_fw_mac_sequence;
++ bool ftm_responder;
+ };
+
+ struct ath11k_hw_ops {
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -3110,7 +3110,7 @@ static void ath11k_mac_op_bss_info_chang
+ u16 bitrate;
+ int ret = 0;
+ u8 rateidx;
+- u32 rate;
++ u32 rate, param;
+ u32 ipv4_cnt;
+
+ mutex_lock(&ar->conf_mutex);
+@@ -3412,6 +3412,20 @@ static void ath11k_mac_op_bss_info_chang
+ }
+ }
+
++ if (changed & BSS_CHANGED_FTM_RESPONDER &&
++ arvif->ftm_responder != info->ftm_responder &&
++ ar->ab->hw_params.ftm_responder &&
++ (vif->type == NL80211_IFTYPE_AP ||
++ vif->type == NL80211_IFTYPE_MESH_POINT)) {
++ arvif->ftm_responder = info->ftm_responder;
++ param = WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE;
++ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param,
++ arvif->ftm_responder);
++ if (ret)
++ ath11k_warn(ar->ab, "Failed to set ftm responder %i: %d\n",
++ arvif->vdev_id, ret);
++ }
++
+ if (changed & BSS_CHANGED_FILS_DISCOVERY ||
+ changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP)
+ ath11k_mac_fils_discovery(arvif, info);
+@@ -9113,6 +9127,10 @@ static int __ath11k_mac_register(struct
+ wiphy_ext_feature_set(ar->hw->wiphy,
+ NL80211_EXT_FEATURE_SET_SCAN_DWELL);
+
++ if (ab->hw_params.ftm_responder)
++ wiphy_ext_feature_set(ar->hw->wiphy,
++ NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);
++
+ ath11k_reg_init(ar);
+
+ if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) {
+--- a/drivers/net/wireless/ath/ath11k/wmi.h
++++ b/drivers/net/wireless/ath/ath11k/wmi.h
+@@ -1073,6 +1073,7 @@ enum wmi_tlv_vdev_param {
+ WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE,
+ WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME,
+ WMI_VDEV_PARAM_HE_LTF = 0x74,
++ WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE = 0x7d,
+ WMI_VDEV_PARAM_BA_MODE = 0x7e,
+ WMI_VDEV_PARAM_AUTORATE_MISC_CFG = 0x80,
+ WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87,
--- /dev/null
+From e5e94d10c85653609a2893c8d0ef24a27471b68f Mon Sep 17 00:00:00 2001
+Date: Tue, 10 Jan 2023 15:30:58 +0200
+Subject: [PATCH] wifi: ath11k: add channel 177 into 5 GHz channel list
+
+Add support for the 5 GHz channel 177 with center frequency 5885 MHz and
+operating class 125 per IEEE Std 802.11ax-2021, Table E-4.
+
+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
+
+---
+ drivers/net/wireless/ath/ath11k/core.h | 4 ++--
+ drivers/net/wireless/ath/ath11k/mac.c | 1 +
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath11k/core.h
++++ b/drivers/net/wireless/ath/ath11k/core.h
+@@ -521,8 +521,8 @@ struct ath11k_sta {
+ #define ATH11K_MIN_5G_FREQ 4150
+ #define ATH11K_MIN_6G_FREQ 5925
+ #define ATH11K_MAX_6G_FREQ 7115
+-#define ATH11K_NUM_CHANS 101
+-#define ATH11K_MAX_5G_CHAN 173
++#define ATH11K_NUM_CHANS 102
++#define ATH11K_MAX_5G_CHAN 177
+
+ enum ath11k_state {
+ ATH11K_STATE_OFF,
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -96,6 +96,7 @@ static const struct ieee80211_channel at
+ CHAN5G(165, 5825, 0),
+ CHAN5G(169, 5845, 0),
+ CHAN5G(173, 5865, 0),
++ CHAN5G(177, 5885, 0),
+ };
+
+ static const struct ieee80211_channel ath11k_6ghz_channels[] = {
--- /dev/null
+From 53a998c4d7284debd77734d01e1466e59a1d03b2 Mon Sep 17 00:00:00 2001
+Date: Fri, 13 Jan 2023 12:02:09 +0530
+Subject: [PATCH] wifi: ath11k: fix ce memory mapping for ahb devices
+
+Currently ath11k_ahb module is not loaded successfully and the wifi
+interface is not created. Kernel trace is seen while loading the
+ath11k_ahb module. The issue is seen in all ath11k AHB devices except
+in IPQ5018.
+
+This happens because in ath11k_ahb_probe(), ab->mem_ce is initialized
+with the value of ab->mem. However, at this instant ab->mem is not
+yet set.
+
+Later, during write to a particular memory via ath11k_ahb_write32()
+this ab->mem_ce is used with particular offset. Since ab->mem_ce is
+not set properly this possibly leads to memory conflict to handle
+kernel paging request and the below trace is seen.
+
+[ 93.035047] Unable to handle kernel paging request at virtual address ffff800100a00000
+[ 93.035083] Mem abort info:
+[ 93.041869] ESR = 0x0000000096000045
+[ 93.044561] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 93.048377] SET = 0, FnV = 0
+[ 93.053840] EA = 0, S1PTW = 0
+[ 93.056704] FSC = 0x05: level 1 translation fault
+[ 93.059745] Data abort info:
+[ 93.064603] ISV = 0, ISS = 0x00000045
+[ 93.067729] CM = 0, WnR = 1
+[ 93.071287] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000042219000
+[ 93.074409] [ffff800100a00000] pgd=100000007ffff003, p4d=100000007ffff003, pud=0000000000000000
+[ 93.081195] Internal error: Oops: 0000000096000045 [#1] PREEMPT SMP
+[ 93.089598] Modules linked in: ath11k_ahb ath11k_pci ath11k qmi_helpers
+[ 93.095851] CPU: 2 PID: 66 Comm: kworker/u8:3 Not tainted 6.1.0-rc8-wt-ath-658126-g58e4b9df840c-dirty #2
+[ 93.102454] Hardware name: Qualcomm Technologies, Inc. IPQ8074/AP-HK14 (DT)
+[ 93.112171] Workqueue: ath11k_qmi_driver_event ath11k_qmi_driver_event_work [ath11k]
+[ 93.118856] pstate: 40000005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[ 93.126838] pc : ath11k_ahb_write32+0xc/0x18 [ath11k_ahb]
+[ 93.133520] lr : ath11k_hal_srng_setup+0x860/0x8f0 [ath11k]
+[ 93.139075] sp : ffff80000aaebb70
+[ 93.144452] x29: ffff80000aaebb70 x28: 0000000000000020 x27: ffff80000aaebc50
+[ 93.147934] x26: ffff000004923750 x25: ffff000004921200 x24: ffff000004928000
+[ 93.155051] x23: 0000000000000020 x22: ffff000004930000 x21: ffff000004923200
+[ 93.162170] x20: ffff000004920000 x19: 00000000eea00000 x18: ffff0000049200f0
+[ 93.169288] x17: 0000000000000000 x16: 0000000000000000 x15: 000000000000025e
+[ 93.176405] x14: ffff000003c414f0 x13: 0000000000000000 x12: 0000000000000008
+[ 93.183524] x11: ffff000003c41488 x10: 0000000000000040 x9 : 0000000000000000
+[ 93.190641] x8 : ffff80000a9dd100 x7 : 0000000000000000 x6 : 000000000000003f
+[ 93.197759] x5 : ffff800100a00400 x4 : ffff8000031f4018 x3 : 0000000000000004
+[ 93.204877] x2 : 0000000047b62000 x1 : ffff800100a00000 x0 : ffff800012000000
+[ 93.211996] Call trace:
+[ 93.219104] ath11k_ahb_write32+0xc/0x18 [ath11k_ahb]
+[ 93.221366] ath11k_ce_init_ring+0x184/0x278 [ath11k]
+[ 93.226576] ath11k_ce_init_pipes+0x4c/0x1a0 [ath11k]
+[ 93.231610] ath11k_core_qmi_firmware_ready+0x3c/0x568 [ath11k]
+[ 93.236646] ath11k_qmi_driver_event_work+0x168/0x4f8 [ath11k]
+[ 93.242376] process_one_work+0x144/0x350
+[ 93.248275] worker_thread+0x120/0x430
+[ 93.252352] kthread+0xf4/0x110
+[ 93.255997] ret_from_fork+0x10/0x20
+[ 93.259043] Code: d503201f f94e1c00 8b214001 d50332bf (b9000022)
+[ 93.262863] ---[ end trace 0000000000000000 ]---
+
+However, for the device IPQ5018 ath11k_hw_params .ce_remap is
+defined. This parameter is used to recalculate ab->mem_ce and hence,
+this issue is not seen in IPQ5018.
+
+Hence, fix this by initializing ab->mem_ce after ab->mem is set.
+ab->mem is set inside the ath11k_ahb_setup_resources() therefore
+initialize ab->mem_ce after ath11k_ahb_setup_resources().
+
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+
+Fixes: b42b3678c91f ("wifi: ath11k: remap ce register space for IPQ5018")
+
+---
+ drivers/net/wireless/ath/ath11k/ahb.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -1157,12 +1157,16 @@ static int ath11k_ahb_probe(struct platf
+ goto err_core_free;
+ }
+
+- ab->mem_ce = ab->mem;
+-
+ ret = ath11k_core_pre_init(ab);
+ if (ret)
+ goto err_core_free;
+
++ ret = ath11k_ahb_setup_resources(ab);
++ if (ret)
++ goto err_core_free;
++
++ ab->mem_ce = ab->mem;
++
+ if (ab->hw_params.ce_remap) {
+ const struct ce_remap *ce_remap = ab->hw_params.ce_remap;
+ /* ce register space is moved out of wcss unlike ipq8074 or ipq6018
+@@ -1177,10 +1181,6 @@ static int ath11k_ahb_probe(struct platf
+ }
+ }
+
+- ret = ath11k_ahb_setup_resources(ab);
+- if (ret)
+- goto err_core_free;
+-
+ ret = ath11k_ahb_fw_resources_init(ab);
+ if (ret)
+ goto err_core_free;
--- /dev/null
+From ed3f83b3459a67a3ab9d806490ac304b567b1c2d Mon Sep 17 00:00:00 2001
+Date: Mon, 2 Jan 2023 12:11:42 +0400
+Subject: [PATCH] wifi: ath11k: Fix memory leak in ath11k_peer_rx_frag_setup
+
+crypto_alloc_shash() allocates resources, which should be released by
+crypto_free_shash(). When ath11k_peer_find() fails, there has memory
+leak. Add missing crypto_free_shash() to fix this.
+
+Fixes: 243874c64c81 ("ath11k: handle RX fragments")
+---
+ drivers/net/wireless/ath/ath11k/dp_rx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -3126,6 +3126,7 @@ int ath11k_peer_rx_frag_setup(struct ath
+ if (!peer) {
+ ath11k_warn(ab, "failed to find the peer to set up fragment info\n");
+ spin_unlock_bh(&ab->base_lock);
++ crypto_free_shash(tfm);
+ return -ENOENT;
+ }
+
--- /dev/null
+From cf8f3d4deb02a8fdc806c46d4112b69868544697 Mon Sep 17 00:00:00 2001
+Date: Wed, 15 Feb 2023 20:31:36 +0200
+Subject: [PATCH] wifi: ath11k: Set ext passive scan flag to adjust passive
+ scan start time
+
+Set the WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE flag
+while sending the scan command. If this flag is enabled when the
+incoming scan request comes with a strict start time and its duration
+overlaps with next TBTT, then target adjust the start time accordingly
+for passive scan. Target supporting this feature will advertise
+WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE.
+
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01467-QCAHKSWPL_SILICONZ-1
+
+---
+ drivers/net/wireless/ath/ath11k/wmi.c | 8 ++++++++
+ drivers/net/wireless/ath/ath11k/wmi.h | 3 +++
+ 2 files changed, 11 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -2068,6 +2068,12 @@ void ath11k_wmi_start_scan_init(struct a
+ WMI_SCAN_EVENT_FOREIGN_CHAN |
+ WMI_SCAN_EVENT_DEQUEUED;
+ arg->scan_flags |= WMI_SCAN_CHAN_STAT_EVENT;
++
++ if (test_bit(WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE,
++ ar->ab->wmi_ab.svc_map))
++ arg->scan_ctrl_flags_ext |=
++ WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE;
++
+ arg->num_bssid = 1;
+
+ /* fill bssid_list[0] with 0xff, otherwise bssid and RA will be
+@@ -2149,6 +2155,8 @@ ath11k_wmi_copy_scan_event_cntrl_flags(s
+ /* for adaptive scan mode using 3 bits (21 - 23 bits) */
+ WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags,
+ param->adaptive_dwell_time_mode);
++
++ cmd->scan_ctrl_flags_ext = param->scan_ctrl_flags_ext;
+ }
+
+ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
+--- a/drivers/net/wireless/ath/ath11k/wmi.h
++++ b/drivers/net/wireless/ath/ath11k/wmi.h
+@@ -2093,6 +2093,7 @@ enum wmi_tlv_service {
+ WMI_TLV_SERVICE_EXT2_MSG = 220,
+ WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT = 246,
+ WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249,
++ WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE = 263,
+
+ /* The second 128 bits */
+ WMI_MAX_EXT_SERVICE = 256,
+@@ -3223,6 +3224,7 @@ struct wmi_start_scan_cmd {
+
+ #define WMI_SCAN_DWELL_MODE_MASK 0x00E00000
+ #define WMI_SCAN_DWELL_MODE_SHIFT 21
++#define WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE 0x00000800
+
+ enum {
+ WMI_SCAN_DWELL_MODE_DEFAULT = 0,
+@@ -3270,6 +3272,7 @@ struct scan_req_params {
+ };
+ u32 scan_events;
+ };
++ u32 scan_ctrl_flags_ext;
+ u32 dwell_time_active;
+ u32 dwell_time_active_2g;
+ u32 dwell_time_passive;
--- /dev/null
+From 342fcde9d91460f01f65707e16368a1571271a3a Mon Sep 17 00:00:00 2001
+Date: Fri, 17 Feb 2023 11:00:31 +0800
+Subject: [PATCH] wifi: ath11k: fix return value check in ath11k_ahb_probe()
+
+ioremap() returns NULL pointer not PTR_ERR() when it fails,
+so replace the IS_ERR() check with NULL pointer check.
+
+Fixes: b42b3678c91f ("wifi: ath11k: remap ce register space for IPQ5018")
+---
+ drivers/net/wireless/ath/ath11k/ahb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -1174,7 +1174,7 @@ static int ath11k_ahb_probe(struct platf
+ * to a new space for accessing them.
+ */
+ ab->mem_ce = ioremap(ce_remap->base, ce_remap->size);
+- if (IS_ERR(ab->mem_ce)) {
++ if (!ab->mem_ce) {
+ dev_err(&pdev->dev, "ce ioremap error\n");
+ ret = -ENOMEM;
+ goto err_core_free;
--- /dev/null
+From f117276638b7600b981b3fe28550823cfbe1ef23 Mon Sep 17 00:00:00 2001
+Date: Wed, 1 Feb 2023 08:54:42 -0800
+Subject: [PATCH] wifi: ath11k: Use platform_get_irq() to get the interrupt
+
+As of commit a1a2b7125e10 ("of/platform: Drop static setup of IRQ
+resource from DT core"), we need to use platform_get_irq() instead of
+platform_get_resource() to get our IRQs because
+platform_get_resource() simply won't get them anymore.
+
+This was already fixed in several other Atheros WiFi drivers,
+apparently in response to Zeal Robot reports. An example of another
+fix is commit 9503a1fc123d ("ath9k: Use platform_get_irq() to get the
+interrupt"). ath11k seems to have been missed in this effort, though.
+
+Without this change, WiFi wasn't coming up on my Qualcomm sc7280-based
+hardware. Specifically, "platform_get_resource(pdev, IORESOURCE_IRQ,
+i)" was failing even for i=0.
+
+Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1
+
+Fixes: a1a2b7125e10 ("of/platform: Drop static setup of IRQ resource from DT core")
+Fixes: 00402f49d26f ("ath11k: Add support for WCN6750 device")
+Link: https://lore.kernel.org/r/20230201084131.v2.1.I69cf3d56c97098287fe3a70084ee515098390b70@changeid
+---
+ drivers/net/wireless/ath/ath11k/ahb.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -874,11 +874,11 @@ static int ath11k_ahb_setup_msi_resource
+ ab->pci.msi.ep_base_data = int_prop + 32;
+
+ for (i = 0; i < ab->pci.msi.config->total_vectors; i++) {
+- res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
+- if (!res)
+- return -ENODEV;
++ ret = platform_get_irq(pdev, i);
++ if (ret < 0)
++ return ret;
+
+- ab->pci.msi.irqs[i] = res->start;
++ ab->pci.msi.irqs[i] = ret;
+ }
+
+ set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags);
--- /dev/null
+From 60b7d62ba8cdbd073997bff0f1cdae8d844002c0 Mon Sep 17 00:00:00 2001
+Date: Thu, 9 Feb 2023 23:26:22 +0100
+Subject: [PATCH] wifi: ath11k: fix SAC bug on peer addition with sta band
+ migration
+
+Fix sleep in atomic context warning detected by Smatch static checker
+analyzer.
+
+Following the locking pattern for peer_rhash_add lock tbl_mtx_lock mutex
+always even if sta is not transitioning to another band.
+This is peer_add function and a more secure locking should not cause
+performance regression.
+
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
+
+Fixes: d673cb6fe6c0 ("wifi: ath11k: fix peer addition/deletion error on sta band migration")
+---
+ drivers/net/wireless/ath/ath11k/peer.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath11k/peer.c
++++ b/drivers/net/wireless/ath/ath11k/peer.c
+@@ -382,22 +382,23 @@ int ath11k_peer_create(struct ath11k *ar
+ return -ENOBUFS;
+ }
+
++ mutex_lock(&ar->ab->tbl_mtx_lock);
+ spin_lock_bh(&ar->ab->base_lock);
+ peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr);
+ if (peer) {
+ if (peer->vdev_id == param->vdev_id) {
+ spin_unlock_bh(&ar->ab->base_lock);
++ mutex_unlock(&ar->ab->tbl_mtx_lock);
+ return -EINVAL;
+ }
+
+ /* Assume sta is transitioning to another band.
+ * Remove here the peer from rhash.
+ */
+- mutex_lock(&ar->ab->tbl_mtx_lock);
+ ath11k_peer_rhash_delete(ar->ab, peer);
+- mutex_unlock(&ar->ab->tbl_mtx_lock);
+ }
+ spin_unlock_bh(&ar->ab->base_lock);
++ mutex_unlock(&ar->ab->tbl_mtx_lock);
+
+ ret = ath11k_wmi_send_peer_create_cmd(ar, param);
+ if (ret) {
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
-@@ -81,7 +81,7 @@ static const struct ath11k_hw_params ath
+@@ -82,7 +82,7 @@ static const struct ath11k_hw_params ath
.supports_shadow_regs = false,
.idle_ps = false,
.supports_sta_ps = false,
{
.hw_rev = ATH11K_HW_IPQ8074,
.name = "ipq8074 hw2.0",
-@@ -1826,7 +1826,8 @@ static void ath11k_core_reset(struct wor
+@@ -1919,7 +1919,8 @@ static void ath11k_core_reset(struct wor
static int ath11k_init_hw_params(struct ath11k_base *ab)
{
const struct ath11k_hw_params *hw_params = NULL;
for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) {
hw_params = &ath11k_hw_params[i];
-@@ -1842,7 +1843,30 @@ static int ath11k_init_hw_params(struct
+@@ -1935,7 +1936,30 @@ static int ath11k_init_hw_params(struct
ab->hw_params = *hw_params;