--- /dev/null
+From: George Moussalem <george.moussalem@outlook.com>
+Date: Wed, 27 Oct 2024 16:34:11 +0400
+Subject: [PATCH] wifi: ath11k: add hw params for QCN6122
+
+Add QCN6122 platform support.
+
+QCN6122 is a PCIe based solution that is attached to and enumerated
+by the WPSS (Wireless Processor SubSystem) Q6 processor.
+
+Though it is a PCIe device, since it is not attached to APSS processor
+(Application Processor SubSystem), APSS will be unaware of such a decice
+and hence it is registered to the APSS processor as a platform device(AHB).
+Because of this hybrid nature, it is called as a hybrid bus device.
+
+As such, QCN6122 is a hybrid bus type device and follows the same codepath
+as for WCN6750.
+
+This is a heavily simplified version of below downstream patch:
+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
+
+Co-developed-by: George Moussalem <george.moussalem@outlook.com>
+Signed-off-by: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org>
+Signed-off-by: George Moussalem <george.moussalem@outlook.com>
+---
+
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -809,6 +809,67 @@ 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,
++ .hw_ops = &ipq5018_ops,
++ .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_rxdma_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 = true,
++ .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,6 +22,7 @@
+ #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
--- /dev/null
+From: George Moussalem <george.moussalem@outlook.com>
+Date: Wed, 27 Oct 2024 16:34:11 +0400
+Subject: [PATCH] wifi: ath11k: add hal regs for QCN6122
+
+Add HAL changes required to support QCN6122. Offsets are similar to those of
+WCN6750 but QCN6122 does not use the hal_shadow_base_addr, so add platform
+specific ath11k_hw_regs and register them in hw params.
+
+Signed-off-by: George Moussalem <george.moussalem@outlook.com>
+---
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -822,6 +822,7 @@ static struct ath11k_hw_params ath11k_hw
+ .bdf_addr = 0x4D200000,
+ .hw_ops = &ipq5018_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,
+ .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 = 0x01b80000,
++ .hal_seq_wcss_umac_ce0_dst_reg = 0x01b81000,
++ .hal_seq_wcss_umac_ce1_src_reg = 0x01b82000,
++ .hal_seq_wcss_umac_ce1_dst_reg = 0x01b83000,
++
++ /* 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)
+ {
--- /dev/null
+From: George Moussalem <george.moussalem@outlook.com>
+Date: Wed, 27 Oct 2024 16:34:11 +0400
+Subject: [PATCH] wifi: ath11k: add hw ring mask for QCN6122
+
+Add ring mask for QCN6122 and register them in hw params.
+
+Signed-off-by: George Moussalem <george.moussalem@outlook.com>
+---
+--- 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,
+ .hw_ops = &ipq5018_ops,
++ .ring_mask = &ath11k_hw_ring_mask_qcn6122,
+ .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
+@@ -2070,6 +2070,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
+@@ -289,6 +289,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;
--- /dev/null
+From: George Moussalem <george.moussalem@outlook.com>
+Date: Wed, 27 Oct 2024 16:34:11 +0400
+Subject: [PATCH] wifi: ath11k: update hif and pci ops for QCN6122
+
+Add HIF and PCI ops for QCN6122. QCN6122 by default uses DP window 3.
+However, this is configurable, so let's introduce a function to do that and
+follow the existing register access code for (hybrid)AHB devices and use
+DP window 1.
+
+Signed-off-by: George Moussalem <george.moussalem@outlook.com>
+---
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -768,6 +768,18 @@ static int ath11k_ahb_hif_resume(struct
+ return 0;
+ }
+
++static void ath11k_ahb_config_static_window_qcn6122(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) | (ce_window << 6);
++
++ iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window,
++ ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS);
++}
++
+ static const struct ath11k_hif_ops ath11k_ahb_hif_ops_ipq8074 = {
+ .start = ath11k_ahb_start,
+ .stop = ath11k_ahb_stop,
+@@ -800,6 +812,24 @@ 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,
++ .read = NULL,
++ .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,
++ .power_down = ath11k_ahb_power_down,
++ .power_up = ath11k_ahb_power_up,
++ .ce_irq_enable = ath11k_pci_enable_ce_irqs_except_wake_irq,
++ .ce_irq_disable = ath11k_pci_disable_ce_irqs_except_wake_irq,
++ .config_static_window = ath11k_ahb_config_static_window_qcn6122,
++};
++
+ static int ath11k_core_get_rproc(struct ath11k_base *ab)
+ {
+ struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
+@@ -1144,6 +1174,10 @@ static int ath11k_ahb_probe(struct platf
+ hif_ops = &ath11k_ahb_hif_ops_wcn6750;
+ pci_ops = &ath11k_ahb_pci_ops_wcn6750;
+ break;
++ case ATH11K_HW_QCN6122_HW10:
++ hif_ops = &ath11k_ahb_hif_ops_qcn6122;
++ pci_ops = &ath11k_ahb_pci_ops_wcn6750;
++ 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->hw_params.static_window_map || !ab->hif.ops->config_static_window)
++ return;
++
++ ab->hif.ops->config_static_window(ab);
++}
++
+ #endif /* _HIF_H_ */
+--- a/drivers/net/wireless/ath/ath11k/qmi.c
++++ b/drivers/net/wireless/ath/ath11k/qmi.c
+@@ -2184,6 +2184,8 @@ static int ath11k_qmi_request_device_inf
+ ab->mem = bar_addr_va;
+ ab->mem_len = resp.bar_size;
+
++ ath11k_hif_config_static_window(ab);
++
+ return 0;
+ out:
+ return ret;
--- /dev/null
+From: George Moussalem <george.moussalem@outlook.com>
+Date: Wed, 27 Oct 2024 16:34:11 +0400
+Subject: [PATCH] wifi: ath11k: add multipd support for QCN6122
+
+IPQ5018/QCN6122 platforms use multi PD (protection domains) to avoid having
+one instance of the running Q6 firmware crashing resulting in crashing the
+others. See below patch for more info:
+https://lore.kernel.org/all/20231110091939.3025413-1-quic_mmanikan@quicinc.com/
+
+The IPQ5018 platform can have multiple (2) QCN6122 wifi cards. To differentiate
+the two, the PD instance number (1 or 2) is added to the QMI service instance
+ID, which the QCN6122 firmware also expects. IPQ5018 is always the first PD, so
+the QCN6122 cards should be the second or third.
+
+Signed-off-by: George Moussalem <george.moussalem@outlook.com>
+---
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -435,6 +435,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)
+@@ -1118,6 +1119,27 @@ 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)
++ 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;
++ dev_info(dev, "Multipd architecture - userpd: %d\n", userpd_id + 1);
++
++ return userpd_id;
++}
++
+ static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab)
+ {
+ struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
+@@ -1159,7 +1181,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);
+
+@@ -1183,6 +1205,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");
+@@ -1199,6 +1222,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
+
+@@ -945,6 +948,7 @@ struct ath11k_base {
+ struct list_head peers;
+ wait_queue_head_t peer_mapping_wq;
+ u8 mac_addr[ETH_ALEN];
++ int userpd_id;
+ 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/pci.c
++++ b/drivers/net/wireless/ath/ath11k/pci.c
+@@ -389,6 +389,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);
+ }
--- /dev/null
+From: George Moussalem <george.moussalem@outlook.com>
+Date: Wed, 27 Oct 2024 16:34:11 +0400
+Subject: [PATCH] wifi: ath11k: add QCN6122 device support
+
+QCN6122 is a 2x2 11AX PCIe based chipset, but it is attached to the WPSS
+(Wireless Processor SubSystem) Q6 processor, hence it is enumerated
+by the Q6 processor. It is registered to the APSS processor
+(Application Processor SubSystem) as a platform device (AHB) and remoteproc
+APIs are used to boot up or shutdown the device like other AHB devices.
+
+Also, device information like BAR and its size is not known to the
+APSS processor as the chip is enumerated by WPSS Q6. These details
+are fetched over QMI.
+
+STA, AP, and MESH modes are supported.
+Tested on: Linksys MX2000 and GLiNET B3000 access points for prolonged duration
+tests spanning multiple days with multiple clients connected with firmware
+WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+
+An important point to note is that though QCN6122 is a PCIe device,
+it is an IPQ5018 SoC specific solution and cannot be attached to any other
+platform.
+
+Signed-off-by: George Moussalem <george.moussalem@outlook.com>
+---
+--- 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/pcic.c
++++ b/drivers/net/wireless/ath/ath11k/pcic.c
+@@ -126,6 +126,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)
--- /dev/null
+From 64f6f6cdde0b6b763181145a698207fad4536c06 Mon Sep 17 00:00:00 2001
+From: Ziyang Huang <hzyitc@outlook.com>
+Date: Wed, 9 Aug 2023 17:44:49 +0000
+Subject: [PATCH] wifi: ath11k: Support to assign m3 dump memory
+
+Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
+---
+ 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);
--- /dev/null
+From: George Moussalem <george.moussalem@outlook.com>
+Date: Wed, 27 Oct 2024 16:34:11 +0400
+Subject: [PATCH] dt: bindings: net: add bindings for QCN6122
+
+QCN6122 is a PCIe based solution that is attached to and enumerated
+by the WPSS (Wireless Processor SubSystem) Q6 processor.
+
+Though it is a PCIe device, since it is not attached to APSS processor
+(Application Processor SubSystem), APSS will be unaware of such a decice
+and hence it is registered to the APSS processor as a platform device(AHB).
+Because of this hybrid nature, it is called as a hybrid bus device.
+
+As such, QCN6122 is a hybrid bus type device and follows the same codepath
+as for WCN6750.
+
+This is a reversed engineered and heavily simplified version of below
+downstream patch:
+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 <george.moussalem@outlook.com>
+---
+--- a/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml
++++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml
+@@ -21,6 +21,7 @@ properties:
+ - qcom,ipq6018-wifi
+ - qcom,wcn6750-wifi
+ - qcom,ipq5018-wifi
++ - qcom,qcn6122-wifi
+
+ reg:
+ maxItems: 1
+@@ -258,6 +259,29 @@ allOf:
+ - description: interrupt event for ring DP20
+ - description: interrupt event for ring DP21
+ - description: interrupt event for ring DP22
++ - if:
++ properties:
++ compatible:
++ contains:
++ enum:
++ - qcom,qcn6122-wifi
++ then:
++ properties:
++ interrupts:
++ items:
++ - description: interrupt event for ring CE1
++ - description: interrupt event for ring CE2
++ - description: interrupt event for ring CE3
++ - description: interrupt event for ring CE4
++ - description: interrupt event for ring CE5
++ - description: interrupt event for ring DP1
++ - description: interrupt event for ring DP2
++ - description: interrupt event for ring DP3
++ - description: interrupt event for ring DP4
++ - description: interrupt event for ring DP5
++ - description: interrupt event for ring DP6
++ - description: interrupt event for ring DP7
++ - description: interrupt event for ring DP8
+
+ examples:
+ - |