QCN6432 is a PCIe-based device attached to the WCSS Q6 processor, but it is registered as a platform (AHB) device. It uses AHB APIs for probe and boot, while relying on PCI APIs for device setup and register access. To leverage the PCI API usage in QCN6432, refactor the existing PCI operations and MSI configuration structures. Move ATH12K_PCI_IRQ_CE0_OFFSET to ce.h from pci.c and ahb.h and rename it to ATH12K_MSI_IRQ_CE0_OFFSET. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1 Signed-off-by: Aaradhana Sahu --- drivers/net/wireless/ath/ath12k/ahb.h | 1 - drivers/net/wireless/ath/ath12k/ce.h | 2 + drivers/net/wireless/ath/ath12k/core.h | 9 +++++ drivers/net/wireless/ath/ath12k/pci.c | 60 +++++++++++++---------------- drivers/net/wireless/ath/ath12k/pci.h | 18 ++++++++- drivers/net/wireless/ath/ath12k/wifi7/pci.c | 9 ++--- 6 files changed, 56 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.h b/drivers/net/wireless/ath/ath12k/ahb.h index 46a4420d41bd..ecc4054f8742 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.h +++ b/drivers/net/wireless/ath/ath12k/ahb.h @@ -17,7 +17,6 @@ #define ATH12K_AHB_SMP2P_SMEM_SEQ_NO GENMASK(31, 16) #define ATH12K_AHB_SMP2P_SMEM_VALUE_MASK 0xFFFFFFFF #define ATH12K_PCI_CE_WAKE_IRQ 2 -#define ATH12K_PCI_IRQ_CE0_OFFSET 3 #define ATH12K_ROOTPD_READY_TIMEOUT (5 * HZ) #define ATH12K_RPROC_AFTER_POWERUP QCOM_SSR_AFTER_POWERUP #define ATH12K_AHB_FW_PREFIX "q6_fw" diff --git a/drivers/net/wireless/ath/ath12k/ce.h b/drivers/net/wireless/ath/ath12k/ce.h index 009cddf2d68d..cd913a885470 100644 --- a/drivers/net/wireless/ath/ath12k/ce.h +++ b/drivers/net/wireless/ath/ath12k/ce.h @@ -9,6 +9,8 @@ #define CE_COUNT_MAX 16 +#define ATH12K_MSI_IRQ_CE0_OFFSET 3 + /* Byte swap data words */ #define CE_ATTR_BYTE_SWAP_DATA 2 diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 99d71dab7c04..993aa3f350aa 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -186,6 +186,10 @@ enum ath12k_smbios_cc_type { ATH12K_SMBIOS_CC_WW = 2, }; +enum ath12k_msi_supported_hw { + ATH12K_MSI_CONFIG_PCI, +}; + struct ath12k_smbios_bdf { struct dmi_header hdr; u8 features_disabled; @@ -1152,6 +1156,11 @@ struct ath12k_base { struct rhashtable *rhead_sta_addr; struct rhashtable_params rhash_sta_addr_param; + struct { + const struct ath12k_msi_config *config; + u32 ep_base_data; + } msi; + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 12bbb75570f1..736e40492b41 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -22,14 +22,6 @@ #define ATH12K_PCI_BAR_NUM 0 #define ATH12K_PCI_DMA_MASK 36 -#define ATH12K_PCI_IRQ_CE0_OFFSET 3 - -#define WINDOW_ENABLE_BIT 0x40000000 -#define WINDOW_VALUE_MASK GENMASK(24, 19) -#define WINDOW_START 0x80000 -#define WINDOW_RANGE_MASK GENMASK(18, 0) -#define WINDOW_STATIC_MASK GENMASK(31, 6) - /* BAR0 + 4k is always accessible, and no * need to force wakeup. * 4K - 32 = 0xFE0 @@ -313,7 +305,7 @@ static void ath12k_pci_sw_reset(struct ath12k_base *ab, bool power_on) ath12k_mhi_set_mhictrl_reset(ab); } -static void ath12k_pci_free_ce_irq(struct ath12k_base *ab, int num_ce) +void ath12k_pci_free_ce_irq(struct ath12k_base *ab, int num_ce) { int i, irq_idx; @@ -321,12 +313,12 @@ static void ath12k_pci_free_ce_irq(struct ath12k_base *ab, int num_ce) if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) continue; - irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + i; + irq_idx = ATH12K_MSI_IRQ_CE0_OFFSET + i; free_irq(ab->irq_num[irq_idx], &ab->ce.ce_pipe[i]); } } -static void ath12k_pci_free_ext_irq(struct ath12k_base *ab, int num_ext_irq_grp) +void ath12k_pci_free_ext_irq(struct ath12k_base *ab, int num_ext_irq_grp) { int i, j; @@ -358,7 +350,7 @@ static void ath12k_pci_ce_irq_enable(struct ath12k_base *ab, u16 ce_id) if (!test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) return; - irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + ce_id; + irq_idx = ATH12K_MSI_IRQ_CE0_OFFSET + ce_id; enable_irq(ab->irq_num[irq_idx]); } @@ -373,7 +365,7 @@ static void ath12k_pci_ce_irq_disable(struct ath12k_base *ab, u16 ce_id) if (!test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) return; - irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + ce_id; + irq_idx = ATH12K_MSI_IRQ_CE0_OFFSET + ce_id; disable_irq_nosync(ab->irq_num[irq_idx]); } @@ -390,7 +382,7 @@ static void ath12k_pci_ce_irqs_disable(struct ath12k_base *ab) } } -static void ath12k_pci_sync_ce_irqs(struct ath12k_base *ab) +void ath12k_pci_sync_ce_irqs(struct ath12k_base *ab) { int i; int irq_idx; @@ -399,15 +391,15 @@ static void ath12k_pci_sync_ce_irqs(struct ath12k_base *ab) if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) continue; - irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + i; + irq_idx = ATH12K_MSI_IRQ_CE0_OFFSET + i; synchronize_irq(ab->irq_num[irq_idx]); } } -static void ath12k_pci_ce_workqueue(struct work_struct *work) +void ath12k_pci_ce_workqueue(struct work_struct *work) { struct ath12k_ce_pipe *ce_pipe = from_work(ce_pipe, work, intr_wq); - int irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + ce_pipe->pipe_num; + int irq_idx = ATH12K_MSI_IRQ_CE0_OFFSET + ce_pipe->pipe_num; ath12k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num); @@ -418,7 +410,7 @@ static irqreturn_t ath12k_pci_ce_interrupt_handler(int irq, void *arg) { struct ath12k_ce_pipe *ce_pipe = arg; struct ath12k_base *ab = ce_pipe->ab; - int irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + ce_pipe->pipe_num; + int irq_idx = ATH12K_MSI_IRQ_CE0_OFFSET + ce_pipe->pipe_num; if (!test_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags)) return IRQ_HANDLED; @@ -520,7 +512,7 @@ static int ath12k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget) return work_done; } -static irqreturn_t ath12k_pci_ext_interrupt_handler(int irq, void *arg) +irqreturn_t ath12k_pci_ext_interrupt_handler(int irq, void *arg) { struct ath12k_ext_irq_grp *irq_grp = arg; struct ath12k_base *ab = irq_grp->ab; @@ -551,7 +543,7 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab) bool threaded_napi = false; int irq; - base_idx = ATH12K_PCI_IRQ_CE0_OFFSET + CE_COUNT_MAX; + base_idx = ATH12K_MSI_IRQ_CE0_OFFSET + CE_COUNT_MAX; ret = ath12k_pci_get_user_msi_assignment(ab, "DP", &num_vectors, &user_base_data, @@ -666,7 +658,7 @@ static int ath12k_pci_config_irq(struct ath12k_base *ab) irq = ath12k_pci_get_msi_irq(ab->dev, msi_data); ce_pipe = &ab->ce.ce_pipe[i]; - irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + i; + irq_idx = ATH12K_MSI_IRQ_CE0_OFFSET + i; INIT_WORK(&ce_pipe->intr_wq, ath12k_pci_ce_workqueue); @@ -718,7 +710,7 @@ static void ath12k_pci_init_qmi_ce_config(struct ath12k_base *ab) } } -static void ath12k_pci_ce_irqs_enable(struct ath12k_base *ab) +void ath12k_pci_ce_irqs_enable(struct ath12k_base *ab) { int i; @@ -759,7 +751,7 @@ static void ath12k_pci_msi_disable(struct ath12k_pci *ab_pci) static int ath12k_pci_msi_alloc(struct ath12k_pci *ab_pci) { struct ath12k_base *ab = ab_pci->ab; - const struct ath12k_msi_config *msi_config = ab_pci->msi_config; + const struct ath12k_msi_config *msi_config = ab->msi.config; struct msi_desc *msi_desc; int num_vectors; int ret; @@ -782,7 +774,7 @@ static int ath12k_pci_msi_alloc(struct ath12k_pci *ab_pci) goto reset_msi_config; } clear_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags); - ab_pci->msi_config = &msi_config_one_msi; + ab->msi.config = &msi_config_one_msi; ab_pci->irq_flags = IRQF_SHARED | IRQF_NOBALANCING; ath12k_dbg(ab, ATH12K_DBG_PCI, "request MSI one vector\n"); } @@ -798,11 +790,11 @@ static int ath12k_pci_msi_alloc(struct ath12k_pci *ab_pci) goto free_msi_vector; } - ab_pci->msi_ep_base_data = msi_desc->msg.data; + ab->msi.ep_base_data = msi_desc->msg.data; if (msi_desc->pci.msi_attrib.is_64) set_bit(ATH12K_PCI_FLAG_IS_MSI_64, &ab_pci->flags); - ath12k_dbg(ab, ATH12K_DBG_PCI, "msi base data is %d\n", ab_pci->msi_ep_base_data); + ath12k_dbg(ab, ATH12K_DBG_PCI, "msi base data is %u\n", ab->msi.ep_base_data); return 0; @@ -820,6 +812,7 @@ static void ath12k_pci_msi_free(struct ath12k_pci *ab_pci) static int ath12k_pci_config_msi_data(struct ath12k_pci *ab_pci) { + struct ath12k_base *ab = ab_pci->ab; struct msi_desc *msi_desc; msi_desc = irq_get_msi_desc(ab_pci->pdev->irq); @@ -829,10 +822,10 @@ static int ath12k_pci_config_msi_data(struct ath12k_pci *ab_pci) return -EINVAL; } - ab_pci->msi_ep_base_data = msi_desc->msg.data; + ab->msi.ep_base_data = msi_desc->msg.data; - ath12k_dbg(ab_pci->ab, ATH12K_DBG_PCI, "pci after request_irq msi_ep_base_data %d\n", - ab_pci->msi_ep_base_data); + ath12k_dbg(ab, ATH12K_DBG_PCI, "pci after request_irq msi_ep_base_data %u\n", + ab->msi.ep_base_data); return 0; } @@ -955,7 +948,7 @@ static void ath12k_pci_aspm_restore(struct ath12k_pci *ab_pci) PCI_EXP_LNKCTL_ASPMC); } -static void ath12k_pci_cancel_workqueue(struct ath12k_base *ab) +void ath12k_pci_cancel_workqueue(struct ath12k_base *ab) { int i; @@ -969,7 +962,7 @@ static void ath12k_pci_cancel_workqueue(struct ath12k_base *ab) } } -static void ath12k_pci_ce_irq_disable_sync(struct ath12k_base *ab) +void ath12k_pci_ce_irq_disable_sync(struct ath12k_base *ab) { ath12k_pci_ce_irqs_disable(ab); ath12k_pci_sync_ce_irqs(ab); @@ -1030,15 +1023,14 @@ int ath12k_pci_get_user_msi_assignment(struct ath12k_base *ab, char *user_name, int *num_vectors, u32 *user_base_data, u32 *base_vector) { - struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); - const struct ath12k_msi_config *msi_config = ab_pci->msi_config; + const struct ath12k_msi_config *msi_config = ab->msi.config; int idx; for (idx = 0; idx < msi_config->total_users; idx++) { if (strcmp(user_name, msi_config->users[idx].name) == 0) { *num_vectors = msi_config->users[idx].num_vectors; *base_vector = msi_config->users[idx].base_vector; - *user_base_data = *base_vector + ab_pci->msi_ep_base_data; + *user_base_data = *base_vector + ab->msi.ep_base_data; ath12k_dbg(ab, ATH12K_DBG_PCI, "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n", diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index 0e0e2020c6ae..47c8760536e4 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -76,6 +76,14 @@ #define QRTR_PCI_DOMAIN_NR_MASK GENMASK(7, 4) #define QRTR_PCI_BUS_NUMBER_MASK GENMASK(3, 0) +#define WINDOW_ENABLE_BIT 0x40000000 +#define WINDOW_REG_ADDRESS 0x310c +#define WINDOW_REG_ADDRESS_QCC2072 0x3278 +#define WINDOW_VALUE_MASK GENMASK(24, 19) +#define WINDOW_START 0x80000 +#define WINDOW_RANGE_MASK GENMASK(18, 0) +#define WINDOW_STATIC_MASK GENMASK(31, 6) + struct ath12k_msi_user { const char *name; int num_vectors; @@ -116,9 +124,7 @@ struct ath12k_pci { struct ath12k_base *ab; u16 dev_id; char amss_path[100]; - u32 msi_ep_base_data; struct mhi_controller *mhi_ctrl; - const struct ath12k_msi_config *msi_config; unsigned long mhi_state; enum mhi_callback mhi_pre_cb; u32 register_window; @@ -177,4 +183,12 @@ void ath12k_pci_power_down(struct ath12k_base *ab, bool is_suspend); int ath12k_pci_register_driver(const enum ath12k_device_family device_id, struct ath12k_pci_driver *driver); void ath12k_pci_unregister_driver(const enum ath12k_device_family device_id); +irqreturn_t ath12k_pci_ext_interrupt_handler(int irq, void *arg); +void ath12k_pci_ce_irq_disable_sync(struct ath12k_base *ab); +void ath12k_pci_ce_irqs_enable(struct ath12k_base *ab); +void ath12k_pci_sync_ce_irqs(struct ath12k_base *ab); +void ath12k_pci_cancel_workqueue(struct ath12k_base *ab); +void ath12k_pci_ce_workqueue(struct work_struct *work); +void ath12k_pci_free_ce_irq(struct ath12k_base *ab, int num_ce); +void ath12k_pci_free_ext_irq(struct ath12k_base *ab, int num_ext_irq_grp); #endif /* ATH12K_PCI_H */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index 6c96b52dec13..bb617bb6b71a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -28,9 +28,6 @@ #define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8) #define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 4) -#define WINDOW_REG_ADDRESS 0x310c -#define WINDOW_REG_ADDRESS_QCC2072 0x3278 - static const struct pci_device_id ath12k_wifi7_pci_id_table[] = { { PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) }, { PCI_VDEVICE(QCOM, WCN7850_DEVICE_ID) }, @@ -106,7 +103,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, switch (pci_dev->device) { case QCN9274_DEVICE_ID: - ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; + ab->msi.config = &ath12k_wifi7_msi_config[ATH12K_MSI_CONFIG_PCI]; ab->static_window_map = true; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_qcn9274; /* @@ -133,7 +130,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, break; case WCN7850_DEVICE_ID: ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD; - ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; + ab->msi.config = &ath12k_wifi7_msi_config[ATH12K_MSI_CONFIG_PCI]; ab->static_window_map = false; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850; /* @@ -157,7 +154,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, break; case QCC2072_DEVICE_ID: ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD; - ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; + ab->msi.config = &ath12k_wifi7_msi_config[ATH12K_MSI_CONFIG_PCI]; ab->static_window_map = false; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850; ab_pci->window_reg_addr = WINDOW_REG_ADDRESS_QCC2072; -- 2.34.1