|
@@ -20,6 +20,7 @@
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/interrupt.h>
|
|
|
#include <linux/if_arp.h>
|
|
|
+#include <linux/of_pci.h>
|
|
|
#ifdef CONFIG_PCI_MSM
|
|
|
#include <linux/msm_pcie.h>
|
|
|
#endif
|
|
@@ -63,23 +64,117 @@
|
|
|
* use TargetCPU warm reset * instead of SOC_GLOBAL_RESET
|
|
|
*/
|
|
|
#define CPU_WARM_RESET_WAR
|
|
|
-
|
|
|
-const char *dp_irqname[WLAN_CFG_INT_NUM_CONTEXTS] = {
|
|
|
-"WLAN_GRP_DP_0",
|
|
|
-"WLAN_GRP_DP_1",
|
|
|
-"WLAN_GRP_DP_2",
|
|
|
-"WLAN_GRP_DP_3",
|
|
|
-"WLAN_GRP_DP_4",
|
|
|
-"WLAN_GRP_DP_5",
|
|
|
-"WLAN_GRP_DP_6",
|
|
|
+#define WLAN_CFG_MAX_PCIE_GROUPS 2
|
|
|
+#define WLAN_CFG_MAX_CE_COUNT 12
|
|
|
+
|
|
|
+const char *dp_irqname[WLAN_CFG_MAX_PCIE_GROUPS][WLAN_CFG_INT_NUM_CONTEXTS] = {
|
|
|
+{
|
|
|
+"pci0_wlan_grp_dp_0",
|
|
|
+"pci0_wlan_grp_dp_1",
|
|
|
+"pci0_wlan_grp_dp_2",
|
|
|
+"pci0_wlan_grp_dp_3",
|
|
|
+"pci0_wlan_grp_dp_4",
|
|
|
+"pci0_wlan_grp_dp_5",
|
|
|
+"pci0_wlan_grp_dp_6",
|
|
|
+#if !defined(WLAN_MAX_PDEVS)
|
|
|
+"pci0_wlan_grp_dp_7",
|
|
|
+"pci0_wlan_grp_dp_8",
|
|
|
+"pci0_wlan_grp_dp_9",
|
|
|
+"pci0_wlan_grp_dp_10",
|
|
|
+#endif
|
|
|
+},
|
|
|
+{
|
|
|
+"pci1_wlan_grp_dp_0",
|
|
|
+"pci1_wlan_grp_dp_1",
|
|
|
+"pci1_wlan_grp_dp_2",
|
|
|
+"pci1_wlan_grp_dp_3",
|
|
|
+"pci1_wlan_grp_dp_4",
|
|
|
+"pci1_wlan_grp_dp_5",
|
|
|
+"pci1_wlan_grp_dp_6",
|
|
|
#if !defined(WLAN_MAX_PDEVS)
|
|
|
-"WLAN_GRP_DP_7",
|
|
|
-"WLAN_GRP_DP_8",
|
|
|
-"WLAN_GRP_DP_9",
|
|
|
-"WLAN_GRP_DP_10",
|
|
|
+"pci1_wlan_grp_dp_7",
|
|
|
+"pci1_wlan_grp_dp_8",
|
|
|
+"pci1_wlan_grp_dp_9",
|
|
|
+"pci1_wlan_grp_dp_10",
|
|
|
#endif
|
|
|
+}
|
|
|
+};
|
|
|
+
|
|
|
+const char *ce_irqname[WLAN_CFG_MAX_PCIE_GROUPS][WLAN_CFG_MAX_CE_COUNT] = {
|
|
|
+{
|
|
|
+"pci0_wlan_ce_0",
|
|
|
+"pci0_wlan_ce_1",
|
|
|
+"pci0_wlan_ce_2",
|
|
|
+"pci0_wlan_ce_3",
|
|
|
+"pci0_wlan_ce_4",
|
|
|
+"pci0_wlan_ce_5",
|
|
|
+"pci0_wlan_ce_6",
|
|
|
+"pci0_wlan_ce_7",
|
|
|
+"pci0_wlan_ce_8",
|
|
|
+"pci0_wlan_ce_9",
|
|
|
+"pci0_wlan_ce_10",
|
|
|
+"pci0_wlan_ce_11",
|
|
|
+},
|
|
|
+{
|
|
|
+"pci1_wlan_ce_0",
|
|
|
+"pci1_wlan_ce_1",
|
|
|
+"pci1_wlan_ce_2",
|
|
|
+"pci1_wlan_ce_3",
|
|
|
+"pci1_wlan_ce_4",
|
|
|
+"pci1_wlan_ce_5",
|
|
|
+"pci1_wlan_ce_6",
|
|
|
+"pci1_wlan_ce_7",
|
|
|
+"pci1_wlan_ce_8",
|
|
|
+"pci1_wlan_ce_9",
|
|
|
+"pci1_wlan_ce_10",
|
|
|
+"pci1_wlan_ce_11",
|
|
|
+}
|
|
|
};
|
|
|
|
|
|
+#if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1)
|
|
|
+static inline int hif_get_pci_slot(struct hif_softc *scn)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * If WLAN_MAX_PDEVS is defined as 1, always return pci slot 0
|
|
|
+ * since there is only one pci device attached.
|
|
|
+ */
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline int hif_get_pci_slot(struct hif_softc *scn)
|
|
|
+{
|
|
|
+ uint32_t pci_id;
|
|
|
+ struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(scn);
|
|
|
+ struct hif_target_info *tgt_info = hif_get_target_info_handle(hif_hdl);
|
|
|
+ uint32_t target_type = tgt_info->target_type;
|
|
|
+ struct device_node *mhi_node;
|
|
|
+ struct device_node *pcierp_node;
|
|
|
+ struct device_node *pcie_node;
|
|
|
+
|
|
|
+ switch (target_type) {
|
|
|
+ case TARGET_TYPE_QCN9000:
|
|
|
+ /* of_node stored in qdf_dev points to the mhi node */
|
|
|
+ mhi_node = scn->qdf_dev->dev->of_node;
|
|
|
+ /*
|
|
|
+ * pcie id is stored in the main pci node which has to be taken
|
|
|
+ * from the second parent of mhi_node.
|
|
|
+ */
|
|
|
+ pcierp_node = mhi_node->parent;
|
|
|
+ pcie_node = pcierp_node->parent;
|
|
|
+ pci_id = of_get_pci_domain_nr(pcie_node);
|
|
|
+ if (pci_id < 0 || pci_id >= WLAN_CFG_MAX_PCIE_GROUPS) {
|
|
|
+ HIF_ERROR("pci_id:%d is invalid", pci_id);
|
|
|
+ QDF_ASSERT(0);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return pci_id;
|
|
|
+ default:
|
|
|
+ /* Send pci_id 0 for all other targets */
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* Top-level interrupt handler for all PCI interrupts from a Target.
|
|
|
* When a block of MSI interrupts is allocated, this top-level handler
|
|
@@ -3493,6 +3588,7 @@ static int hif_ce_msi_configure_irq(struct hif_softc *scn)
|
|
|
struct HIF_CE_state *ce_sc = HIF_GET_CE_STATE(scn);
|
|
|
struct hif_pci_softc *pci_sc = HIF_GET_PCI_SOFTC(scn);
|
|
|
struct CE_attr *host_ce_conf = ce_sc->host_ce_config;
|
|
|
+ int pci_slot;
|
|
|
|
|
|
if (!scn->disable_wake_irq) {
|
|
|
/* do wake irq assignment */
|
|
@@ -3534,6 +3630,7 @@ static int hif_ce_msi_configure_irq(struct hif_softc *scn)
|
|
|
/* needs to match the ce_id -> irq data mapping
|
|
|
* used in the srng parameter configuration
|
|
|
*/
|
|
|
+ pci_slot = hif_get_pci_slot(scn);
|
|
|
for (ce_id = 0; ce_id < scn->ce_count; ce_id++) {
|
|
|
unsigned int msi_data = (ce_id % msi_data_count) +
|
|
|
msi_irq_start;
|
|
@@ -3552,7 +3649,7 @@ static int hif_ce_msi_configure_irq(struct hif_softc *scn)
|
|
|
ret = pfrm_request_irq(scn->qdf_dev->dev,
|
|
|
irq, hif_ce_interrupt_handler,
|
|
|
IRQF_SHARED,
|
|
|
- ce_name[ce_id],
|
|
|
+ ce_irqname[pci_slot][ce_id],
|
|
|
&ce_sc->tasklets[ce_id]);
|
|
|
if (ret)
|
|
|
goto free_irq;
|
|
@@ -3695,12 +3792,14 @@ int hif_pci_configure_grp_irq(struct hif_softc *scn,
|
|
|
int ret = 0;
|
|
|
int irq = 0;
|
|
|
int j;
|
|
|
+ int pci_slot;
|
|
|
|
|
|
hif_ext_group->irq_enable = &hif_exec_grp_irq_enable;
|
|
|
hif_ext_group->irq_disable = &hif_exec_grp_irq_disable;
|
|
|
hif_ext_group->irq_name = &hif_pci_get_irq_name;
|
|
|
hif_ext_group->work_complete = &hif_dummy_grp_done;
|
|
|
|
|
|
+ pci_slot = hif_get_pci_slot(scn);
|
|
|
for (j = 0; j < hif_ext_group->numirq; j++) {
|
|
|
irq = hif_ext_group->irq[j];
|
|
|
|
|
@@ -3710,7 +3809,7 @@ int hif_pci_configure_grp_irq(struct hif_softc *scn,
|
|
|
scn->qdf_dev->dev, irq,
|
|
|
hif_ext_group_interrupt_handler,
|
|
|
IRQF_SHARED | IRQF_NO_SUSPEND,
|
|
|
- dp_irqname[hif_ext_group->grp_id],
|
|
|
+ dp_irqname[pci_slot][hif_ext_group->grp_id],
|
|
|
hif_ext_group);
|
|
|
if (ret) {
|
|
|
HIF_ERROR("%s: request_irq failed ret = %d",
|