mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 10:51:27 +00:00
This series is based on * 2020-07-10 ipq6018-ilq-11-0_qca_oem-034672b0676c37b1f4519e5720e18e95fe6236ef Add support for * qsdk kernel/v4.4 * qsdk ethernet subsystem * v5.7 ath11k backport + QualComm staging patches (wlan_ap_1.0) * ath11k-firmware * hostapd/iw/... Feature support * full boot, system detection * sysupgrade to nand * HE support via latest hostapd * driver support for usb, crypto, hwmon, cpufreq, ... Missing * NSS/HW flow offloading - FW blob is not redistributable Using the qsdk v4.4 is an intermediate solution while the vanilla is being tested. Vanilla kernel is almost on feature par. Work has already started to upstream the ethernet and switch drivers. Once complete the target will be fully upstream. Signed-off-by: John Crispin <john@phrozen.org>
589 lines
15 KiB
Diff
589 lines
15 KiB
Diff
From 70cfdca29588385e56d9ee1247475ba7e06303c9 Mon Sep 17 00:00:00 2001
|
|
From: Govind Singh <govinds@codeaurora.org>
|
|
Date: Thu, 12 Dec 2019 13:10:48 +0200
|
|
Subject: [PATCH 158/164] ath11k: setup resource initialization for QCA6x90
|
|
|
|
Define CE pipe/qmi config and setup pci irq for the
|
|
same.
|
|
|
|
Signed-off-by: Govind Singh <govinds@codeaurora.org>
|
|
Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
|
|
---
|
|
drivers/net/wireless/ath/ath11k/ahb.c | 58 ------
|
|
drivers/net/wireless/ath/ath11k/ahb.h | 57 ++++++
|
|
drivers/net/wireless/ath/ath11k/ce.c | 2 +
|
|
drivers/net/wireless/ath/ath11k/core.c | 1 +
|
|
drivers/net/wireless/ath/ath11k/hal.c | 1 +
|
|
drivers/net/wireless/ath/ath11k/pci.c | 345 ++++++++++++++++++++++++++++++++-
|
|
6 files changed, 399 insertions(+), 65 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/ahb.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
|
|
@@ -267,64 +267,6 @@ static const struct service_to_pipe targ
|
|
{ /* terminator entry */ }
|
|
};
|
|
|
|
-#define ATH11K_IRQ_CE0_OFFSET 4
|
|
-
|
|
-static const char *irq_name[ATH11K_IRQ_NUM_MAX] = {
|
|
- "misc-pulse1",
|
|
- "misc-latch",
|
|
- "sw-exception",
|
|
- "watchdog",
|
|
- "ce0",
|
|
- "ce1",
|
|
- "ce2",
|
|
- "ce3",
|
|
- "ce4",
|
|
- "ce5",
|
|
- "ce6",
|
|
- "ce7",
|
|
- "ce8",
|
|
- "ce9",
|
|
- "ce10",
|
|
- "ce11",
|
|
- "host2wbm-desc-feed",
|
|
- "host2reo-re-injection",
|
|
- "host2reo-command",
|
|
- "host2rxdma-monitor-ring3",
|
|
- "host2rxdma-monitor-ring2",
|
|
- "host2rxdma-monitor-ring1",
|
|
- "reo2ost-exception",
|
|
- "wbm2host-rx-release",
|
|
- "reo2host-status",
|
|
- "reo2host-destination-ring4",
|
|
- "reo2host-destination-ring3",
|
|
- "reo2host-destination-ring2",
|
|
- "reo2host-destination-ring1",
|
|
- "rxdma2host-monitor-destination-mac3",
|
|
- "rxdma2host-monitor-destination-mac2",
|
|
- "rxdma2host-monitor-destination-mac1",
|
|
- "ppdu-end-interrupts-mac3",
|
|
- "ppdu-end-interrupts-mac2",
|
|
- "ppdu-end-interrupts-mac1",
|
|
- "rxdma2host-monitor-status-ring-mac3",
|
|
- "rxdma2host-monitor-status-ring-mac2",
|
|
- "rxdma2host-monitor-status-ring-mac1",
|
|
- "host2rxdma-host-buf-ring-mac3",
|
|
- "host2rxdma-host-buf-ring-mac2",
|
|
- "host2rxdma-host-buf-ring-mac1",
|
|
- "rxdma2host-destination-ring-mac3",
|
|
- "rxdma2host-destination-ring-mac2",
|
|
- "rxdma2host-destination-ring-mac1",
|
|
- "host2tcl-input-ring4",
|
|
- "host2tcl-input-ring3",
|
|
- "host2tcl-input-ring2",
|
|
- "host2tcl-input-ring1",
|
|
- "wbm2host-tx-completions-ring3",
|
|
- "wbm2host-tx-completions-ring2",
|
|
- "wbm2host-tx-completions-ring1",
|
|
- "tcl2host-status-ring",
|
|
-};
|
|
-
|
|
-
|
|
/* enum ext_irq_num - irq numbers that can be used by external modules
|
|
* like datapath
|
|
*/
|
|
--- a/drivers/net/wireless/ath/ath11k/ahb.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/ahb.h
|
|
@@ -10,4 +10,61 @@
|
|
#define ATH11K_AHB_RECOVERY_TIMEOUT (3 * HZ)
|
|
struct ath11k_base;
|
|
|
|
+#define ATH11K_IRQ_CE0_OFFSET 4
|
|
+
|
|
+const char *irq_name[ATH11K_IRQ_NUM_MAX] = {
|
|
+ "misc-pulse1",
|
|
+ "misc-latch",
|
|
+ "sw-exception",
|
|
+ "watchdog",
|
|
+ "ce0",
|
|
+ "ce1",
|
|
+ "ce2",
|
|
+ "ce3",
|
|
+ "ce4",
|
|
+ "ce5",
|
|
+ "ce6",
|
|
+ "ce7",
|
|
+ "ce8",
|
|
+ "ce9",
|
|
+ "ce10",
|
|
+ "ce11",
|
|
+ "host2wbm-desc-feed",
|
|
+ "host2reo-re-injection",
|
|
+ "host2reo-command",
|
|
+ "host2rxdma-monitor-ring3",
|
|
+ "host2rxdma-monitor-ring2",
|
|
+ "host2rxdma-monitor-ring1",
|
|
+ "reo2ost-exception",
|
|
+ "wbm2host-rx-release",
|
|
+ "reo2host-status",
|
|
+ "reo2host-destination-ring4",
|
|
+ "reo2host-destination-ring3",
|
|
+ "reo2host-destination-ring2",
|
|
+ "reo2host-destination-ring1",
|
|
+ "rxdma2host-monitor-destination-mac3",
|
|
+ "rxdma2host-monitor-destination-mac2",
|
|
+ "rxdma2host-monitor-destination-mac1",
|
|
+ "ppdu-end-interrupts-mac3",
|
|
+ "ppdu-end-interrupts-mac2",
|
|
+ "ppdu-end-interrupts-mac1",
|
|
+ "rxdma2host-monitor-status-ring-mac3",
|
|
+ "rxdma2host-monitor-status-ring-mac2",
|
|
+ "rxdma2host-monitor-status-ring-mac1",
|
|
+ "host2rxdma-host-buf-ring-mac3",
|
|
+ "host2rxdma-host-buf-ring-mac2",
|
|
+ "host2rxdma-host-buf-ring-mac1",
|
|
+ "rxdma2host-destination-ring-mac3",
|
|
+ "rxdma2host-destination-ring-mac2",
|
|
+ "rxdma2host-destination-ring-mac1",
|
|
+ "host2tcl-input-ring4",
|
|
+ "host2tcl-input-ring3",
|
|
+ "host2tcl-input-ring2",
|
|
+ "host2tcl-input-ring1",
|
|
+ "wbm2host-tx-completions-ring3",
|
|
+ "wbm2host-tx-completions-ring2",
|
|
+ "wbm2host-tx-completions-ring1",
|
|
+ "tcl2host-status-ring",
|
|
+};
|
|
+
|
|
#endif
|
|
--- a/drivers/net/wireless/ath/ath11k/ce.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/ce.c
|
|
@@ -638,6 +638,7 @@ void ath11k_ce_cleanup_pipes(struct ath1
|
|
/* NOTE: Should we also clean up tx buffer in all pipes? */
|
|
}
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_ce_cleanup_pipes);
|
|
|
|
void ath11k_ce_rx_post_buf(struct ath11k_base *ab)
|
|
{
|
|
@@ -799,6 +800,7 @@ int ath11k_ce_alloc_pipes(struct ath11k_
|
|
|
|
return 0;
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_ce_alloc_pipes);
|
|
|
|
/* For Big Endian Host, Copy Engine byte_swap is enabled
|
|
* When Copy Engine does byte_swap, need to byte swap again for the
|
|
--- a/drivers/net/wireless/ath/ath11k/core.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
|
@@ -909,6 +909,7 @@ int ath11k_core_init(struct ath11k_base
|
|
|
|
return 0;
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_core_init);
|
|
|
|
void ath11k_core_deinit(struct ath11k_base *ab)
|
|
{
|
|
--- a/drivers/net/wireless/ath/ath11k/hal.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/hal.c
|
|
@@ -1127,6 +1127,7 @@ err_free_cont_rdp:
|
|
err_hal:
|
|
return ret;
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_hal_srng_init);
|
|
|
|
void ath11k_hal_srng_deinit(struct ath11k_base *ab)
|
|
{
|
|
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
|
@@ -33,6 +33,192 @@ static struct ath11k_msi_config msi_conf
|
|
},
|
|
};
|
|
|
|
+/* Target firmware's Copy Engine configuration. */
|
|
+static const struct ce_pipe_config target_ce_config_wlan[] = {
|
|
+ /* CE0: host->target HTC control and raw streams */
|
|
+ {
|
|
+ .pipenum = __cpu_to_le32(0),
|
|
+ .pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
|
+ .nentries = __cpu_to_le32(32),
|
|
+ .nbytes_max = __cpu_to_le32(2048),
|
|
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
|
+ .reserved = __cpu_to_le32(0),
|
|
+ },
|
|
+
|
|
+ /* CE1: target->host HTT + HTC control */
|
|
+ {
|
|
+ .pipenum = __cpu_to_le32(1),
|
|
+ .pipedir = __cpu_to_le32(PIPEDIR_IN),
|
|
+ .nentries = __cpu_to_le32(32),
|
|
+ .nbytes_max = __cpu_to_le32(2048),
|
|
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
|
+ .reserved = __cpu_to_le32(0),
|
|
+ },
|
|
+
|
|
+ /* CE2: target->host WMI */
|
|
+ {
|
|
+ .pipenum = __cpu_to_le32(2),
|
|
+ .pipedir = __cpu_to_le32(PIPEDIR_IN),
|
|
+ .nentries = __cpu_to_le32(32),
|
|
+ .nbytes_max = __cpu_to_le32(2048),
|
|
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
|
+ .reserved = __cpu_to_le32(0),
|
|
+ },
|
|
+
|
|
+ /* CE3: host->target WMI */
|
|
+ {
|
|
+ .pipenum = __cpu_to_le32(3),
|
|
+ .pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
|
+ .nentries = __cpu_to_le32(32),
|
|
+ .nbytes_max = __cpu_to_le32(2048),
|
|
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
|
+ .reserved = __cpu_to_le32(0),
|
|
+ },
|
|
+
|
|
+ /* CE4: host->target HTT */
|
|
+ {
|
|
+ .pipenum = __cpu_to_le32(4),
|
|
+ .pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
|
+ .nentries = __cpu_to_le32(256),
|
|
+ .nbytes_max = __cpu_to_le32(256),
|
|
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
|
|
+ .reserved = __cpu_to_le32(0),
|
|
+ },
|
|
+
|
|
+ /* CE5: target->host Pktlog */
|
|
+ {
|
|
+ .pipenum = __cpu_to_le32(5),
|
|
+ .pipedir = __cpu_to_le32(PIPEDIR_IN),
|
|
+ .nentries = __cpu_to_le32(32),
|
|
+ .nbytes_max = __cpu_to_le32(2048),
|
|
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
|
+ .reserved = __cpu_to_le32(0),
|
|
+ },
|
|
+
|
|
+ /* CE6: Reserved for target autonomous hif_memcpy */
|
|
+ {
|
|
+ .pipenum = __cpu_to_le32(6),
|
|
+ .pipedir = __cpu_to_le32(PIPEDIR_INOUT),
|
|
+ .nentries = __cpu_to_le32(32),
|
|
+ .nbytes_max = __cpu_to_le32(16384),
|
|
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
|
+ .reserved = __cpu_to_le32(0),
|
|
+ },
|
|
+
|
|
+ /* CE7 used only by Host */
|
|
+ {
|
|
+ .pipenum = __cpu_to_le32(7),
|
|
+ .pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H),
|
|
+ .nentries = __cpu_to_le32(0),
|
|
+ .nbytes_max = __cpu_to_le32(0),
|
|
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
|
|
+ .reserved = __cpu_to_le32(0),
|
|
+ },
|
|
+
|
|
+ /* CE8 target->host used only by IPA */
|
|
+ {
|
|
+ .pipenum = __cpu_to_le32(8),
|
|
+ .pipedir = __cpu_to_le32(PIPEDIR_INOUT),
|
|
+ .nentries = __cpu_to_le32(32),
|
|
+ .nbytes_max = __cpu_to_le32(16384),
|
|
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
|
+ .reserved = __cpu_to_le32(0),
|
|
+ },
|
|
+ /* CE 9, 10, 11 are used by MHI driver */
|
|
+};
|
|
+
|
|
+/* Map from service/endpoint to Copy Engine.
|
|
+ * This table is derived from the CE_PCI TABLE, above.
|
|
+ * It is passed to the Target at startup for use by firmware.
|
|
+ */
|
|
+static const struct service_to_pipe target_service_to_ce_map_wlan[] = {
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
|
|
+ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
|
+ __cpu_to_le32(3),
|
|
+ },
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
|
|
+ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
|
+ __cpu_to_le32(2),
|
|
+ },
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
|
|
+ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
|
+ __cpu_to_le32(3),
|
|
+ },
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
|
|
+ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
|
+ __cpu_to_le32(2),
|
|
+ },
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
|
|
+ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
|
+ __cpu_to_le32(3),
|
|
+ },
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
|
|
+ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
|
+ __cpu_to_le32(2),
|
|
+ },
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
|
|
+ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
|
+ __cpu_to_le32(3),
|
|
+ },
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
|
|
+ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
|
+ __cpu_to_le32(2),
|
|
+ },
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
|
|
+ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
|
+ __cpu_to_le32(3),
|
|
+ },
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
|
|
+ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
|
+ __cpu_to_le32(2),
|
|
+ },
|
|
+
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
|
|
+ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
|
+ __cpu_to_le32(0),
|
|
+ },
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
|
|
+ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
|
+ __cpu_to_le32(2),
|
|
+ },
|
|
+
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
|
|
+ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
|
+ __cpu_to_le32(4),
|
|
+ },
|
|
+ {
|
|
+ __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
|
|
+ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
|
+ __cpu_to_le32(1),
|
|
+ },
|
|
+
|
|
+ /* (Additions here) */
|
|
+
|
|
+ { /* must be last */
|
|
+ __cpu_to_le32(0),
|
|
+ __cpu_to_le32(0),
|
|
+ __cpu_to_le32(0),
|
|
+ },
|
|
+};
|
|
+
|
|
+static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab)
|
|
+{
|
|
+ return (struct ath11k_pci *)ab->drv_priv;
|
|
+}
|
|
+
|
|
int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector)
|
|
{
|
|
struct pci_dev *pci_dev = to_pci_dev(dev);
|
|
@@ -78,6 +264,105 @@ int ath11k_pci_get_user_msi_assignment(s
|
|
return -EINVAL;
|
|
}
|
|
|
|
+static void ath11k_pci_free_irq(struct ath11k_base *ab)
|
|
+{
|
|
+ int irq_idx;
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < CE_COUNT; i++) {
|
|
+ if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR)
|
|
+ continue;
|
|
+ irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
|
|
+ free_irq(ab->irq_num[irq_idx], &ab->ce.ce_pipe[i]);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void ath11k_pci_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
|
|
+{
|
|
+ u32 irq_idx;
|
|
+
|
|
+ irq_idx = ATH11K_IRQ_CE0_OFFSET + ce_id;
|
|
+ disable_irq_nosync(ab->irq_num[irq_idx]);
|
|
+}
|
|
+
|
|
+static irqreturn_t ath11k_pci_ce_interrupt_handler(int irq, void *arg)
|
|
+{
|
|
+ struct ath11k_ce_pipe *ce_pipe = arg;
|
|
+
|
|
+ ath11k_pci_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num);
|
|
+
|
|
+ return IRQ_HANDLED;
|
|
+}
|
|
+
|
|
+static int ath11k_pci_config_irq(struct ath11k_base *ab)
|
|
+{
|
|
+ struct ath11k_ce_pipe *ce_pipe;
|
|
+ u32 msi_data_start;
|
|
+ u32 msi_data_count;
|
|
+ u32 msi_irq_start;
|
|
+ unsigned int msi_data;
|
|
+ int irq, i, ret, irq_idx;
|
|
+
|
|
+ ret = ath11k_pci_get_user_msi_assignment(ath11k_pci_priv(ab),
|
|
+ "CE", &msi_data_count,
|
|
+ &msi_data_start, &msi_irq_start);
|
|
+
|
|
+ /* Configure CE irqs */
|
|
+ for (i = 0; i < CE_COUNT; i++) {
|
|
+ msi_data = (i % msi_data_count) +
|
|
+ msi_irq_start;
|
|
+ irq = ath11k_pci_get_msi_irq(ab->dev, msi_data);
|
|
+ ce_pipe = &ab->ce.ce_pipe[i];
|
|
+
|
|
+ if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR)
|
|
+ continue;
|
|
+
|
|
+ irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
|
|
+
|
|
+ ret = request_irq(irq, ath11k_pci_ce_interrupt_handler,
|
|
+ IRQF_SHARED, irq_name[irq_idx],
|
|
+ ce_pipe);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ ab->irq_num[irq_idx] = irq;
|
|
+ }
|
|
+
|
|
+ /* To Do Configure external interrupts */
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab)
|
|
+{
|
|
+ struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
|
|
+
|
|
+ cfg->tgt_ce = target_ce_config_wlan;
|
|
+ cfg->tgt_ce_len = sizeof(target_ce_config_wlan);
|
|
+
|
|
+ cfg->svc_to_ce_map = target_service_to_ce_map_wlan;
|
|
+ cfg->svc_to_ce_map_len = sizeof(target_service_to_ce_map_wlan);
|
|
+}
|
|
+
|
|
+static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
|
|
+{
|
|
+ u32 irq_idx;
|
|
+
|
|
+ irq_idx = ATH11K_IRQ_CE0_OFFSET + ce_id;
|
|
+ enable_irq(ab->irq_num[irq_idx]);
|
|
+}
|
|
+
|
|
+static void ath11k_pci_ce_irqs_enable(struct ath11k_base *ab)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < CE_COUNT; i++) {
|
|
+ if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR)
|
|
+ continue;
|
|
+ ath11k_pci_ce_irq_enable(ab, i);
|
|
+ }
|
|
+}
|
|
+
|
|
int ath11k_pci_qca6x90_powerup(struct ath11k_pci *ar_pci)
|
|
{
|
|
return ath11k_pci_start_mhi(ar_pci);
|
|
@@ -95,11 +380,6 @@ static int ath11k_pci_get_msi_assignment
|
|
return 0;
|
|
}
|
|
|
|
-static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab)
|
|
-{
|
|
- return (struct ath11k_pci *)ab->drv_priv;
|
|
-}
|
|
-
|
|
static int ath11k_pci_enable_msi(struct ath11k_pci *ar_pci)
|
|
{
|
|
struct ath11k_base *ab = ar_pci->ab;
|
|
@@ -262,7 +542,23 @@ static void ath11k_pci_power_down(struct
|
|
ath11k_pci_qca6x90_powerdown(ar_pci);
|
|
}
|
|
|
|
+static void ath11k_pci_stop(struct ath11k_base *ab)
|
|
+{
|
|
+ ath11k_ce_cleanup_pipes(ab);
|
|
+ /* Shutdown other components as appropriate */
|
|
+}
|
|
+
|
|
+static int ath11k_pci_start(struct ath11k_base *ab)
|
|
+{
|
|
+ ath11k_pci_ce_irqs_enable(ab);
|
|
+ /* Bring up other components as appropriate */
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static const struct ath11k_hif_ops ath11k_pci_hif_ops = {
|
|
+ .start = ath11k_pci_start,
|
|
+ .stop = ath11k_pci_stop,
|
|
.power_down = ath11k_pci_power_down,
|
|
.power_up = ath11k_pci_power_up,
|
|
};
|
|
@@ -304,6 +600,7 @@ static int ath11k_pci_probe(struct pci_d
|
|
ar_pci->pdev = pdev;
|
|
ab->dev = &pdev->dev;
|
|
ab->hw_rev = hw_rev;
|
|
+ ab->hif.ops = &ath11k_pci_hif_ops;
|
|
pci_set_drvdata(pdev, ab);
|
|
|
|
ret = ath11k_pci_claim(ar_pci, pdev);
|
|
@@ -325,11 +622,44 @@ static int ath11k_pci_probe(struct pci_d
|
|
goto err_pci_disable_msi;
|
|
}
|
|
|
|
-err_pci_disable_msi:
|
|
- ath11k_pci_disable_msi(ar_pci);
|
|
+ ret = ath11k_hal_srng_init(ab);
|
|
+ if (ret)
|
|
+ goto err_pci_unregister_mhi;
|
|
|
|
+ ret = ath11k_ce_alloc_pipes(ab);
|
|
+ if (ret) {
|
|
+ ath11k_err(ab, "failed to allocate ce pipes: %d\n", ret);
|
|
+ goto err_hal_srng_deinit;
|
|
+ }
|
|
+
|
|
+ ath11k_pci_init_qmi_ce_config(ab);
|
|
+ ath11k_pci_config_irq(ab);
|
|
+ if (ret) {
|
|
+ ath11k_err(ab, "failed to config irq: %d\n", ret);
|
|
+ goto err_ce_free;
|
|
+ }
|
|
+ ret = ath11k_core_init(ab);
|
|
+ if (ret) {
|
|
+ ath11k_err(ab, "failed to init core: %d\n", ret);
|
|
+ goto err_free_irq;
|
|
+ }
|
|
return 0;
|
|
|
|
+err_free_irq:
|
|
+ ath11k_pci_free_irq(ab);
|
|
+
|
|
+err_ce_free:
|
|
+ ath11k_ce_free_pipes(ab);
|
|
+
|
|
+err_hal_srng_deinit:
|
|
+ ath11k_hal_srng_deinit(ab);
|
|
+
|
|
+err_pci_unregister_mhi:
|
|
+ ath11k_pci_unregister_mhi(ar_pci);
|
|
+
|
|
+err_pci_disable_msi:
|
|
+ ath11k_pci_disable_msi(ar_pci);
|
|
+
|
|
err_pci_free_region:
|
|
ath11k_pci_free_region(ar_pci);
|
|
|
|
@@ -348,6 +678,7 @@ static void ath11k_pci_remove(struct pci
|
|
ath11k_pci_unregister_mhi(ar_pci);
|
|
ath11k_pci_disable_msi(ar_pci);
|
|
ath11k_pci_free_region(ar_pci);
|
|
+ ath11k_pci_free_irq(ab);
|
|
ath11k_core_free(ab);
|
|
}
|
|
|