mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-21 03:13:17 +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>
222 lines
5.8 KiB
Diff
222 lines
5.8 KiB
Diff
From 2589ffa83b65e2f9e8cb8bc0c8c3303fff51d136 Mon Sep 17 00:00:00 2001
|
|
From: Anilkumar Kolli <akolli@codeaurora.org>
|
|
Date: Mon, 23 Mar 2020 14:25:19 +0530
|
|
Subject: [PATCH 156/164] ath11k: Add msi config init for QCA6x90
|
|
|
|
QCA6x90 uses PCI msi for CE/MHI/DP interrupt.
|
|
Add msi vector mapping and msi enable/disable ops.
|
|
|
|
Signed-off-by: Govind Singh <govinds@codeaurora.org>
|
|
Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
|
|
---
|
|
drivers/net/wireless/ath/ath11k/debug.h | 1 +
|
|
drivers/net/wireless/ath/ath11k/pci.c | 104 ++++++++++++++++++++++++++++++++
|
|
drivers/net/wireless/ath/ath11k/pci.h | 14 +++++
|
|
3 files changed, 119 insertions(+)
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath11k/debug.h b/drivers/net/wireless/ath/ath11k/debug.h
|
|
index 32b541eeb220..3e620f07647d 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/debug.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/debug.h
|
|
@@ -27,6 +27,7 @@ enum ath11k_debug_mask {
|
|
ATH11k_DBG_HAL = 0x00000800,
|
|
ATH11K_DBG_DP_TX = 0x00001000,
|
|
ATH11K_DBG_DP_RX = 0x00002000,
|
|
+ ATH11K_DBG_PCI = 0x00004000,
|
|
ATH11K_DBG_ANY = 0xffffffff,
|
|
};
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
|
|
index fad919201047..509ed39ba4fb 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
|
@@ -4,6 +4,7 @@
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
+#include <linux/msi.h>
|
|
#include <linux/pci.h>
|
|
|
|
#include "ahb.h"
|
|
@@ -19,11 +20,88 @@ static const struct pci_device_id ath11k_pci_id_table[] = {
|
|
|
|
MODULE_DEVICE_TABLE(pci, ath11k_pci_id_table);
|
|
|
|
+static struct ath11k_msi_config msi_config = {
|
|
+ .total_vectors = 32,
|
|
+ .total_users = 4,
|
|
+ .users = (struct ath11k_msi_user[]) {
|
|
+ { .name = "MHI", .num_vectors = 3, .base_vector = 0 },
|
|
+ { .name = "CE", .num_vectors = 10, .base_vector = 3 },
|
|
+ { .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
|
|
+ { .name = "DP", .num_vectors = 18, .base_vector = 14 },
|
|
+ },
|
|
+};
|
|
+
|
|
+static int ath11k_pci_get_msi_assignment(struct ath11k_pci *ar_pci)
|
|
+{
|
|
+ ar_pci->msi_config = &msi_config;
|
|
+
|
|
+ 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;
|
|
+ struct ath11k_msi_config *msi_config;
|
|
+ struct msi_desc *msi_desc;
|
|
+ int num_vectors;
|
|
+ int ret;
|
|
+
|
|
+ ret = ath11k_pci_get_msi_assignment(ar_pci);
|
|
+ if (ret) {
|
|
+ ath11k_err(ab, "failed to get MSI assignment, err = %d\n", ret);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ msi_config = ar_pci->msi_config;
|
|
+ if (!msi_config) {
|
|
+ ath11k_err(ab, "msi_config is NULL!\n");
|
|
+ ret = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ num_vectors = pci_alloc_irq_vectors(ar_pci->pdev,
|
|
+ msi_config->total_vectors,
|
|
+ msi_config->total_vectors,
|
|
+ PCI_IRQ_MSI);
|
|
+ if (num_vectors != msi_config->total_vectors) {
|
|
+ ath11k_err(ab, "failed to get enough MSI vectors (%d), available vectors = %d",
|
|
+ msi_config->total_vectors, num_vectors);
|
|
+ if (num_vectors >= 0)
|
|
+ ret = -EINVAL;
|
|
+ goto reset_msi_config;
|
|
+ }
|
|
+
|
|
+ msi_desc = irq_get_msi_desc(ar_pci->pdev->irq);
|
|
+ if (!msi_desc) {
|
|
+ ath11k_err(ab, "msi_desc is NULL!\n");
|
|
+ ret = -EINVAL;
|
|
+ goto free_msi_vector;
|
|
+ }
|
|
+
|
|
+ ar_pci->msi_ep_base_data = msi_desc->msg.data;
|
|
+
|
|
+ ath11k_dbg(ab, ATH11K_DBG_PCI, "msi base data is %d\n", ar_pci->msi_ep_base_data);
|
|
+
|
|
+ return 0;
|
|
+
|
|
+free_msi_vector:
|
|
+ pci_free_irq_vectors(ar_pci->pdev);
|
|
+reset_msi_config:
|
|
+ ar_pci->msi_config = NULL;
|
|
+out:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static void ath11k_pci_disable_msi(struct ath11k_pci *ar_pci)
|
|
+{
|
|
+ pci_free_irq_vectors(ar_pci->pdev);
|
|
+}
|
|
+
|
|
static int ath11k_pci_claim(struct ath11k_pci *ar_pci, struct pci_dev *pdev)
|
|
{
|
|
u32 pci_dma_mask = PCI_DMA_MASK_32_BIT;
|
|
@@ -94,6 +172,17 @@ out:
|
|
return ret;
|
|
}
|
|
|
|
+static void ath11k_pci_free_region(struct ath11k_pci *ar_pci)
|
|
+{
|
|
+ struct pci_dev *pci_dev = ar_pci->pdev;
|
|
+
|
|
+ pci_iounmap(pci_dev, ar_pci->mem);
|
|
+ ar_pci->mem = NULL;
|
|
+ pci_clear_master(pci_dev);
|
|
+ pci_release_region(pci_dev, PCI_BAR_NUM);
|
|
+ if (pci_is_enabled(pci_dev))
|
|
+ pci_disable_device(pci_dev);
|
|
+}
|
|
static int ath11k_pci_probe(struct pci_dev *pdev,
|
|
const struct pci_device_id *pci_dev)
|
|
{
|
|
@@ -127,6 +216,8 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
|
|
ar_pci = ath11k_pci_priv(ab);
|
|
ar_pci->dev_id = pci_dev->device;
|
|
ar_pci->ab = ab;
|
|
+ ar_pci->dev = &pdev->dev;
|
|
+ ar_pci->pdev = pdev;
|
|
ab->dev = &pdev->dev;
|
|
ab->hw_rev = hw_rev;
|
|
pci_set_drvdata(pdev, ab);
|
|
@@ -137,18 +228,31 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
|
|
goto err_free_core;
|
|
}
|
|
|
|
+ ret = ath11k_pci_enable_msi(ar_pci);
|
|
+ if (ret) {
|
|
+ ath11k_err(ab, "failed to enable msi: %d\n", ret);
|
|
+ goto err_pci_free_region;
|
|
+ }
|
|
+
|
|
return 0;
|
|
|
|
+err_pci_free_region:
|
|
+ ath11k_pci_free_region(ar_pci);
|
|
+
|
|
err_free_core:
|
|
ath11k_core_free(ab);
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
static void ath11k_pci_remove(struct pci_dev *pdev)
|
|
{
|
|
struct ath11k_base *ab = pci_get_drvdata(pdev);
|
|
+ struct ath11k_pci *ar_pci = ath11k_pci_priv(ab);
|
|
|
|
set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
|
|
+ ath11k_pci_disable_msi(ar_pci);
|
|
+ ath11k_pci_free_region(ar_pci);
|
|
ath11k_core_free(ab);
|
|
}
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h
|
|
index d9785cea8d89..196a84a14e30 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/pci.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/pci.h
|
|
@@ -11,6 +11,18 @@
|
|
#define PCI_DMA_MASK_64_BIT 64
|
|
#define PCI_DMA_MASK_32_BIT 32
|
|
|
|
+struct ath11k_msi_user {
|
|
+ char *name;
|
|
+ int num_vectors;
|
|
+ u32 base_vector;
|
|
+};
|
|
+
|
|
+struct ath11k_msi_config {
|
|
+ int total_vectors;
|
|
+ int total_users;
|
|
+ struct ath11k_msi_user *users;
|
|
+};
|
|
+
|
|
struct ath11k_pci {
|
|
struct pci_dev *pdev;
|
|
struct device *dev;
|
|
@@ -19,4 +31,6 @@ struct ath11k_pci {
|
|
size_t mem_len;
|
|
u16 dev_id;
|
|
u32 chip_id;
|
|
+ struct ath11k_msi_config *msi_config;
|
|
+ u32 msi_ep_base_data;
|
|
};
|
|
--
|
|
2.7.4
|
|
|