> -----Original Message----- > From: ath11k <ath11k-bounces@xxxxxxxxxxxxxxxxxxx> On Behalf Of Govind > Singh > Sent: Friday, May 8, 2020 4:59 PM > To: ath11k@xxxxxxxxxxxxxxxxxxx > Cc: Govind Singh <govinds@xxxxxxxxxxxxxx>; linux- > wireless@xxxxxxxxxxxxxxx > Subject: [EXT] [PATCH 4/4] ath11k: Register mhi controller device for > qca6390 > > MHI is a communication protocol to communicate with external Qualcomm > modems and Wi-Fi chipsets over high speed peripheral buses. Even though > MHI doesn’t dictate underlying physical layer, protocol and mhi stack is > structured for PCIe based devices. > > Register directly with mhi core layer as a mhi device driver for firmware > download. > > Tested QCA6390 on X86 platform. > Tested firmware WLAN.HST.1.0.1.c1-00440-QCAHSTSWPLZ_V2_TO_X86-1. > > Signed-off-by: Govind Singh <govinds@xxxxxxxxxxxxxx> > --- > drivers/net/wireless/ath/ath11k/Kconfig | 5 +- > drivers/net/wireless/ath/ath11k/Makefile | 2 +- > drivers/net/wireless/ath/ath11k/mhi.c | 379 +++++++++++++++++++++++ > drivers/net/wireless/ath/ath11k/mhi.h | 28 ++ > drivers/net/wireless/ath/ath11k/pci.c | 97 ++++++ > drivers/net/wireless/ath/ath11k/pci.h | 13 + > 6 files changed, 520 insertions(+), 4 deletions(-) create mode 100644 > drivers/net/wireless/ath/ath11k/mhi.c > create mode 100644 drivers/net/wireless/ath/ath11k/mhi.h > > diff --git a/drivers/net/wireless/ath/ath11k/Kconfig > b/drivers/net/wireless/ath/ath11k/Kconfig > index 320b3b151bce..bd48796742bb 100644 > --- a/drivers/net/wireless/ath/ath11k/Kconfig > +++ b/drivers/net/wireless/ath/ath11k/Kconfig > @@ -2,7 +2,6 @@ > config ATH11K > tristate "Qualcomm Technologies 802.11ax chipset support" > depends on MAC80211 && HAS_DMA > -depends on REMOTEPROC > depends on CRYPTO_MICHAEL_MIC > depends on ARCH_QCOM || COMPILE_TEST > select ATH_COMMON > @@ -15,13 +14,13 @@ config ATH11K > > config ATH11K_AHB > tristate "Qualcomm Technologies 802.11ax chipset AHB support" > -depends on ATH11K > +depends on ATH11K && REMOTEPROC > ---help--- > This module adds support for AHB bus > > config ATH11K_PCI > tristate "Qualcomm Technologies 802.11ax chipset PCI support" > -depends on ATH11K && PCI > +depends on ATH11K && PCI && MHI_BUS > ---help--- > This module adds support for PCIE bus > > diff --git a/drivers/net/wireless/ath/ath11k/Makefile > b/drivers/net/wireless/ath/ath11k/Makefile > index 933fcb2fd55d..8343c7dfaae3 100644 > --- a/drivers/net/wireless/ath/ath11k/Makefile > +++ b/drivers/net/wireless/ath/ath11k/Makefile > @@ -25,7 +25,7 @@ obj-$(CONFIG_ATH11K_AHB) += ath11k_ahb.o > ath11k_ahb-y += ahb.o > > obj-$(CONFIG_ATH11K_PCI) += ath11k_pci.o -ath11k_pci-y += pci.o > +ath11k_pci-y += mhi.o pci.o > > # for tracing framework to find trace.h CFLAGS_trace.o := -I$(src) diff --git > a/drivers/net/wireless/ath/ath11k/mhi.c > b/drivers/net/wireless/ath/ath11k/mhi.c > new file mode 100644 > index 000000000000..1ca43243e265 > --- /dev/null > +++ b/drivers/net/wireless/ath/ath11k/mhi.c > @@ -0,0 +1,379 @@ > +// SPDX-License-Identifier: BSD-3-Clause-Clear > +/* Copyright (c) 2020 The Linux Foundation. All rights reserved. */ > + > +#include <linux/msi.h> > +#include <linux/pci.h> > + > +#include "debug.h" > +#include "mhi.h" > + > +#define MHI_TIMEOUT_DEFAULT_MS90000 > + > +static struct mhi_channel_config ath11k_mhi_channels[] = { > +{ > +.num = 0, > +.name = "LOOPBACK", > +.num_elements = 32, > +.event_ring = 0, > +.dir = DMA_TO_DEVICE, > +.ee_mask = 0x4, > +.pollcfg = 0, > +.doorbell = MHI_DB_BRST_DISABLE, > +.lpm_notify = false, > +.offload_channel = false, > +.doorbell_mode_switch = false, > +.auto_queue = false, > +.auto_start = false, > +}, > +{ > +.num = 1, > +.name = "LOOPBACK", > +.num_elements = 32, > +.event_ring = 0, > +.dir = DMA_FROM_DEVICE, > +.ee_mask = 0x4, > +.pollcfg = 0, > +.doorbell = MHI_DB_BRST_DISABLE, > +.lpm_notify = false, > +.offload_channel = false, > +.doorbell_mode_switch = false, > +.auto_queue = false, > +.auto_start = false, > +}, > +{ > +.num = 20, > +.name = "IPCR", > +.num_elements = 64, > +.event_ring = 1, > +.dir = DMA_TO_DEVICE, > +.ee_mask = 0x4, > +.pollcfg = 0, > +.doorbell = MHI_DB_BRST_DISABLE, > +.lpm_notify = false, > +.offload_channel = false, > +.doorbell_mode_switch = false, > +.auto_queue = false, > +.auto_start = true, > +}, > +{ > +.num = 21, > +.name = "IPCR", > +.num_elements = 64, > +.event_ring = 1, > +.dir = DMA_FROM_DEVICE, > +.ee_mask = 0x4, > +.pollcfg = 0, > +.doorbell = MHI_DB_BRST_DISABLE, > +.lpm_notify = false, > +.offload_channel = false, > +.doorbell_mode_switch = false, > +.auto_queue = true, > +.auto_start = true, > +}, > +}; > + > +static struct mhi_event_config ath11k_mhi_events[] = { > +{ > +.num_elements = 32, > +.irq_moderation_ms = 0, > +.irq = 1, > +.mode = MHI_DB_BRST_DISABLE, For this evern ring, need to specify .data_type = MHI_ER_CTRL, > +.hardware_event = false, > +.client_managed = false, > +.offload_channel = false, > +}, > +{ > +.num_elements = 256, > +.irq_moderation_ms = 1, > +.irq = 2, > +.mode = MHI_DB_BRST_DISABLE, > +.priority = 1, > +.hardware_event = false, > +.client_managed = false, > +.offload_channel = false, > +}, > +}; > + > +static struct mhi_controller_config ath11k_mhi_config = { > +.max_channels = 128, > +.timeout_ms = 2000, > +.use_bounce_buf = false, > +.buf_len = 0, > +.num_channels = ARRAY_SIZE(ath11k_mhi_channels), > +.ch_cfg = ath11k_mhi_channels, > +.num_events = ARRAY_SIZE(ath11k_mhi_events), > +.event_cfg = ath11k_mhi_events, > +}; > + > +static int ath11k_pci_get_mhi_msi(struct ath11k_pci *ab_pci) { > +struct ath11k_base *ab = ab_pci->ab; > +u32 user_base_data, base_vector; > +int ret, num_vectors, i; > +int *irq; > + > +ret = ath11k_pci_get_user_msi_assignment(ab_pci, > + "MHI", &num_vectors, > + &user_base_data, > &base_vector); > +if (ret) > +return ret; > + > +ath11k_dbg(ab, ATH11K_DBG_PCI, "Number of assigned MSI for MHI > is %d, base vector is %d\n", > + num_vectors, base_vector); > + > +irq = kcalloc(num_vectors, sizeof(int), GFP_KERNEL); > +if (!irq) > +return -ENOMEM; > + > +for (i = 0; i < num_vectors; i++) > +irq[i] = ath11k_pci_get_msi_irq(ab_pci->dev, > +base_vector + i); > + > +ab_pci->mhi_ctrl->irq = irq; > +ab_pci->mhi_ctrl->nr_irqs = num_vectors; > + > +return 0; > +} > + > +int ath11k_pci_register_mhi(struct ath11k_pci *ab_pci) { > +struct ath11k_base *ab = ab_pci->ab; > +struct mhi_controller *mhi_ctrl; > +int ret; > + > +mhi_ctrl = kzalloc(sizeof(*mhi_ctrl), GFP_KERNEL); > +if (!mhi_ctrl) > +return PTR_ERR(mhi_ctrl); > + > +ab_pci->mhi_ctrl = mhi_ctrl; > +mhi_ctrl->fw_image = ATH11K_PCI_FW_FILE_NAME; > +mhi_ctrl->regs = ab_pci->mem; > + > +ret = ath11k_pci_get_mhi_msi(ab_pci); > +if (ret) { > +ath11k_err(ab, "failed to get msi for mhi\n"); > +kfree(mhi_ctrl); > +return ret; > +} > + > +mhi_ctrl->iova_start = 0; > +mhi_ctrl->iova_stop = 0xffffffff; > +mhi_ctrl->sbl_size = SZ_512K; > +mhi_ctrl->seg_len = SZ_512K; > +mhi_ctrl->fbc_download = true; > + > +ret = mhi_register_controller(mhi_ctrl, &ath11k_mhi_config); > +if (ret) { > +ath11k_err(ab, "failed to register to mhi bus, err = %d\n", ret); > +kfree(mhi_ctrl); > +return ret; > +} > + > +return 0; > +} > + > +void ath11k_pci_unregister_mhi(struct ath11k_pci *ab_pci) { > +struct mhi_controller *mhi_ctrl = ab_pci->mhi_ctrl; > + > +mhi_unregister_controller(mhi_ctrl); > +kfree(mhi_ctrl->irq); > +} > + > +static char *ath11k_mhi_state_to_str(enum ath11k_mhi_state mhi_state) { > +switch (mhi_state) { > +case ATH11K_MHI_INIT: > +return "INIT"; > +case ATH11K_MHI_DEINIT: > +return "DEINIT"; > +case ATH11K_MHI_POWER_ON: > +return "POWER_ON"; > +case ATH11K_MHI_POWER_OFF: > +return "POWER_OFF"; > +case ATH11K_MHI_FORCE_POWER_OFF: > +return "FORCE_POWER_OFF"; > +case ATH11K_MHI_SUSPEND: > +return "SUSPEND"; > +case ATH11K_MHI_RESUME: > +return "RESUME"; > +case ATH11K_MHI_TRIGGER_RDDM: > +return "TRIGGER_RDDM"; > +case ATH11K_MHI_RDDM_DONE: > +return "RDDM_DONE"; > +default: > +return "UNKNOWN"; > +} > +}; > + > +static void ath11k_pci_set_mhi_state_bit(struct ath11k_pci *ab_pci, > + enum ath11k_mhi_state mhi_state) > +{ > +struct ath11k_base *ab = ab_pci->ab; > + > +switch (mhi_state) { > +case ATH11K_MHI_INIT: > +set_bit(ATH11K_MHI_INIT, &ab_pci->mhi_state); > +break; > +case ATH11K_MHI_DEINIT: > +clear_bit(ATH11K_MHI_INIT, &ab_pci->mhi_state); > +break; > +case ATH11K_MHI_POWER_ON: > +set_bit(ATH11K_MHI_POWER_ON, &ab_pci->mhi_state); > +break; > +case ATH11K_MHI_POWER_OFF: > +case ATH11K_MHI_FORCE_POWER_OFF: > +clear_bit(ATH11K_MHI_POWER_ON, &ab_pci->mhi_state); > +clear_bit(ATH11K_MHI_TRIGGER_RDDM, &ab_pci- > >mhi_state); > +clear_bit(ATH11K_MHI_RDDM_DONE, &ab_pci->mhi_state); > +break; > +case ATH11K_MHI_SUSPEND: > +set_bit(ATH11K_MHI_SUSPEND, &ab_pci->mhi_state); > +break; > +case ATH11K_MHI_RESUME: > +clear_bit(ATH11K_MHI_SUSPEND, &ab_pci->mhi_state); > +break; > +case ATH11K_MHI_TRIGGER_RDDM: > +set_bit(ATH11K_MHI_TRIGGER_RDDM, &ab_pci->mhi_state); > +break; > +case ATH11K_MHI_RDDM_DONE: > +set_bit(ATH11K_MHI_RDDM_DONE, &ab_pci->mhi_state); > +break; > +default: > +ath11k_err(ab, "unhandled mhi state (%d)\n", mhi_state); > +} > +} > + > +static int ath11k_pci_check_mhi_state_bit(struct ath11k_pci *ab_pci, > + enum ath11k_mhi_state mhi_state) > { > +struct ath11k_base *ab = ab_pci->ab; > + > +switch (mhi_state) { > +case ATH11K_MHI_INIT: > +if (!test_bit(ATH11K_MHI_INIT, &ab_pci->mhi_state)) > +return 0; > +break; > +case ATH11K_MHI_DEINIT: > +case ATH11K_MHI_POWER_ON: > +if (test_bit(ATH11K_MHI_INIT, &ab_pci->mhi_state) && > + !test_bit(ATH11K_MHI_POWER_ON, &ab_pci->mhi_state)) > +return 0; > +break; > +case ATH11K_MHI_FORCE_POWER_OFF: > +if (test_bit(ATH11K_MHI_POWER_ON, &ab_pci->mhi_state)) > +return 0; > +break; > +case ATH11K_MHI_POWER_OFF: > +case ATH11K_MHI_SUSPEND: > +if (test_bit(ATH11K_MHI_POWER_ON, &ab_pci->mhi_state) > && > + !test_bit(ATH11K_MHI_SUSPEND, &ab_pci->mhi_state)) > +return 0; > +break; > +case ATH11K_MHI_RESUME: > +if (test_bit(ATH11K_MHI_SUSPEND, &ab_pci->mhi_state)) > +return 0; > +break; > +case ATH11K_MHI_TRIGGER_RDDM: > +if (test_bit(ATH11K_MHI_POWER_ON, &ab_pci->mhi_state) > && > + !test_bit(ATH11K_MHI_TRIGGER_RDDM, &ab_pci- > >mhi_state)) > +return 0; > +break; > +case ATH11K_MHI_RDDM_DONE: > +return 0; > +default: > +ath11k_err(ab, "unhandled mhi state: %s(%d)\n", > + ath11k_mhi_state_to_str(mhi_state), mhi_state); > +} > + > +ath11k_err(ab, "failed to set mhi state %s(%d) in current mhi state > (0x%lx)\n", > + ath11k_mhi_state_to_str(mhi_state), mhi_state, > + ab_pci->mhi_state); > + > +return -EINVAL; > +} > + > +static int ath11k_pci_set_mhi_state(struct ath11k_pci *ab_pci, > + enum ath11k_mhi_state mhi_state) { > +struct ath11k_base *ab = ab_pci->ab; > +int ret; > + > +ret = ath11k_pci_check_mhi_state_bit(ab_pci, mhi_state); > +if (ret) > +goto out; > + > +ath11k_dbg(ab, ATH11K_DBG_PCI, "setting mhi state: %s(%d)\n", > + ath11k_mhi_state_to_str(mhi_state), mhi_state); > + > +switch (mhi_state) { > +case ATH11K_MHI_INIT: > +ret = mhi_prepare_for_power_up(ab_pci->mhi_ctrl); > +break; > +case ATH11K_MHI_DEINIT: > +mhi_unprepare_after_power_down(ab_pci->mhi_ctrl); > +ret = 0; > +break; > +case ATH11K_MHI_POWER_ON: > +ret = mhi_async_power_up(ab_pci->mhi_ctrl); > +break; > +case ATH11K_MHI_POWER_OFF: > +mhi_power_down(ab_pci->mhi_ctrl, true); > +ret = 0; > +break; > +case ATH11K_MHI_FORCE_POWER_OFF: > +mhi_power_down(ab_pci->mhi_ctrl, false); > +ret = 0; > +break; > +case ATH11K_MHI_SUSPEND: > +break; > +case ATH11K_MHI_RESUME: > +break; > +case ATH11K_MHI_TRIGGER_RDDM: > +ret = mhi_force_rddm_mode(ab_pci->mhi_ctrl); > +break; > +case ATH11K_MHI_RDDM_DONE: > +break; > +default: > +ath11k_err(ab, "unhandled MHI state (%d)\n", mhi_state); > +ret = -EINVAL; > +} > + > +if (ret) > +goto out; > + > +ath11k_pci_set_mhi_state_bit(ab_pci, mhi_state); > + > +return 0; > + > +out: > +ath11k_err(ab, "failed to set mhi state: %s(%d)\n", > + ath11k_mhi_state_to_str(mhi_state), mhi_state); > +return ret; > +} > + > +int ath11k_pci_start_mhi(struct ath11k_pci *ab_pci) { > +struct ath11k_base *ab = ab_pci->ab; > +int ret; > + > +ab_pci->mhi_ctrl->timeout_ms = MHI_TIMEOUT_DEFAULT_MS; > + > +ret = ath11k_pci_set_mhi_state(ab_pci, ATH11K_MHI_INIT); > +if (ret) > +ath11k_err(ab, "failed to set mhi init state: %d\n", ret); > + > +ret = ath11k_pci_set_mhi_state(ab_pci, ATH11K_MHI_POWER_ON); > +if (ret) > +ath11k_err(ab, "failed to set mhi power on state: %d\n", ret); > + > +return ret; > +} > + > +void ath11k_pci_stop_mhi(struct ath11k_pci *ab_pci) { > +ath11k_pci_set_mhi_state(ab_pci, ATH11K_MHI_RESUME); > +ath11k_pci_set_mhi_state(ab_pci, ATH11K_MHI_POWER_OFF); > +ath11k_pci_set_mhi_state(ab_pci, ATH11K_MHI_DEINIT); } > + > diff --git a/drivers/net/wireless/ath/ath11k/mhi.h > b/drivers/net/wireless/ath/ath11k/mhi.h > new file mode 100644 > index 000000000000..355de5a2c241 > --- /dev/null > +++ b/drivers/net/wireless/ath/ath11k/mhi.h > @@ -0,0 +1,28 @@ > +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ > +/* > + * Copyright (c) 2020 The Linux Foundation. All rights reserved. > + */ > +#ifndef _ATH11K_MHI_H > +#define _ATH11K_MHI_H > + > +#include "pci.h" > +#define ATH11K_PCI_FW_FILE_NAME"amss.bin" > + > +enum ath11k_mhi_state { > +ATH11K_MHI_INIT, > +ATH11K_MHI_DEINIT, > +ATH11K_MHI_POWER_ON, > +ATH11K_MHI_POWER_OFF, > +ATH11K_MHI_FORCE_POWER_OFF, > +ATH11K_MHI_SUSPEND, > +ATH11K_MHI_RESUME, > +ATH11K_MHI_TRIGGER_RDDM, > +ATH11K_MHI_RDDM, > +ATH11K_MHI_RDDM_DONE, > +}; > + > +int ath11k_pci_start_mhi(struct ath11k_pci *ar_pci); void > +ath11k_pci_stop_mhi(struct ath11k_pci *ar_pci); int > +ath11k_pci_register_mhi(struct ath11k_pci *ar_pci); void > +ath11k_pci_unregister_mhi(struct ath11k_pci *ar_pci); #endif > diff --git a/drivers/net/wireless/ath/ath11k/pci.c > b/drivers/net/wireless/ath/ath11k/pci.c > index d89dcb5fe81e..938078ee8d80 100644 > --- a/drivers/net/wireless/ath/ath11k/pci.c > +++ b/drivers/net/wireless/ath/ath11k/pci.c > @@ -9,6 +9,8 @@ > > #include "ahb.h" > #include "core.h" > +#include "hif.h" > +#include "mhi.h" > #include "pci.h" > #include "debug.h" > > @@ -31,6 +33,60 @@ static struct ath11k_msi_config msi_config = { > }, > }; > > +int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector) { > +struct pci_dev *pci_dev = to_pci_dev(dev); > +int irq_num; > + > +irq_num = pci_irq_vector(pci_dev, vector); > + > +return irq_num; > +} > + > +int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ab_pci, char > *user_name, > + int *num_vectors, u32 *user_base_data, > + u32 *base_vector) > +{ > +struct ath11k_base *ab = ab_pci->ab; > +struct ath11k_msi_config *msi_config; > +int idx; > + > +msi_config = ab_pci->msi_config; > +if (!msi_config) { > +ath11k_err(ab, "MSI is not supported.\n"); > +return -EINVAL; > +} > + > +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; > +*user_base_data = msi_config- > >users[idx].base_vector > ++ ab_pci->msi_ep_base_data; > +*base_vector = msi_config->users[idx].base_vector; > + > +ath11k_dbg(ab, ATH11K_DBG_PCI, "Assign MSI to > user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n", > + user_name, *num_vectors, > *user_base_data, > + *base_vector); > + > +return 0; > +} > +} > + > +ath11k_err(ab, "Failed to find MSI assignment for %s!\n", > user_name); > + > +return -EINVAL; > +} > + > +static int ath11k_pci_qca6x90_powerup(struct ath11k_pci *ab_pci) { > +return ath11k_pci_start_mhi(ab_pci); > +} > + > +static void ath11k_pci_qca6x90_powerdown(struct ath11k_pci *ab_pci) { > +ath11k_pci_stop_mhi(ab_pci); > +} > + > static int ath11k_pci_get_msi_assignment(struct ath11k_pci *ab_pci) { > ab_pci->msi_config = &msi_config; > @@ -184,6 +240,34 @@ static void ath11k_pci_free_region(struct > ath11k_pci *ab_pci) > pci_disable_device(pci_dev); > } > > +static int ath11k_pci_power_up(struct ath11k_base *ab) { > +struct ath11k_pci *ab_pci; > +int ret; > + > +ab_pci = ath11k_pci_priv(ab); > +ret = ath11k_pci_qca6x90_powerup(ab_pci); > +if (ret) { > +ath11k_err(ab, "failed to power on mhi: %d\n", ret); > +return ret; > +} > + > +return 0; > +} > + > +static void ath11k_pci_power_down(struct ath11k_base *ab) { > +struct ath11k_pci *ab_pci; > + > +ab_pci = ath11k_pci_priv(ab); > +ath11k_pci_qca6x90_powerdown(ab_pci); > +} > + > +static const struct ath11k_hif_ops ath11k_pci_hif_ops = { > +.power_down = ath11k_pci_power_down, > +.power_up = ath11k_pci_power_up, > +}; > + > static int ath11k_pci_probe(struct pci_dev *pdev, > const struct pci_device_id *pci_dev) { @@ -229,14 > +313,26 @@ static int ath11k_pci_probe(struct pci_dev *pdev, > goto err_free_core; > } > > +ab->mem = ab_pci->mem; > +ab->mem_len = ab_pci->mem_len; > + > ret = ath11k_pci_enable_msi(ab_pci); > if (ret) { > ath11k_err(ab, "failed to enable msi: %d\n", ret); > goto err_pci_free_region; > } > > +ret = ath11k_pci_register_mhi(ab_pci); > +if (ret) { > +ath11k_err(ab, "failed to register mhi: %d\n", ret); > +goto err_pci_disable_msi; > +} > + > return 0; > > +err_pci_disable_msi: > +ath11k_pci_disable_msi(ab_pci); > + > err_pci_free_region: > ath11k_pci_free_region(ab_pci); > > @@ -252,6 +348,7 @@ static void ath11k_pci_remove(struct pci_dev *pdev) > struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); > > set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags); > +ath11k_pci_unregister_mhi(ab_pci); > ath11k_pci_disable_msi(ab_pci); > ath11k_pci_free_region(ab_pci); > ath11k_core_free(ab); > diff --git a/drivers/net/wireless/ath/ath11k/pci.h > b/drivers/net/wireless/ath/ath11k/pci.h > index 7c7fa1965aa6..83b485be6c50 100644 > --- a/drivers/net/wireless/ath/ath11k/pci.h > +++ b/drivers/net/wireless/ath/ath11k/pci.h > @@ -2,6 +2,10 @@ > /* > * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. > */ > +#ifndef _ATH11K_PCI_H > +#define _ATH11K_PCI_H > + > +#include <linux/mhi.h> > > #define QCA6290_VENDOR_ID0x17CB > #define QCA6290_DEVICE_ID0x1100 > @@ -33,4 +37,13 @@ struct ath11k_pci { > u32 chip_id; > struct ath11k_msi_config *msi_config; > u32 msi_ep_base_data; > +struct mhi_controller *mhi_ctrl; > +unsigned long mhi_state; > }; > + > +int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ar_pci, char > *user_name, > + int *num_vectors, u32 *user_base_data, > + u32 *base_vector); > + > +int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector); > +#endif > -- > 2.22.0 > > _______________________________________________ > ath11k mailing list > ath11k@xxxxxxxxxxxxxxxxxxx > http://lists.infradead.org/mailman/listinfo/ath11k