diff --git a/Kbuild b/Kbuild index 7ac440ef4ebd..151bc58f6d62 100644 --- a/Kbuild +++ b/Kbuild @@ -1815,12 +1815,17 @@ PLD_INC := -I$(WLAN_ROOT)/$(PLD_INC_DIR) \ PLD_OBJS := $(PLD_SRC_DIR)/pld_common.o -ifeq ($(CONFIG_HIF_PCI), y) -PLD_OBJS += $(PLD_SRC_DIR)/pld_pcie.o +ifeq ($(CONFIG_PCIE_FW_SIM), y) +PLD_OBJS += $(PLD_SRC_DIR)/pld_pcie_fw_sim.o +else ifeq ($(CONFIG_HIF_PCI), y) +PLD_OBJS += $(PLD_SRC_DIR)/pld_pcie.o endif -ifeq ($(CONFIG_ICNSS), y) -PLD_OBJS += $(PLD_SRC_DIR)/pld_snoc.o +ifeq ($(CONFIG_SNOC_FW_SIM),y) +PLD_OBJS += $(PLD_SRC_DIR)/pld_snoc_fw_sim.o +else ifeq ($(CONFIG_ICNSS),y) +PLD_OBJS += $(PLD_SRC_DIR)/pld_snoc.o endif + ifeq ($(CONFIG_QCA_WIFI_SDIO), y) PLD_OBJS += $(PLD_SRC_DIR)/pld_sdio.o endif @@ -2134,7 +2139,15 @@ cppflags-$(CONFIG_WLAN_FW_OFFLOAD) += -DWLAN_FW_OFFLOAD cppflags-$(CONFIG_WLAN_FEATURE_ELNA) += -DWLAN_FEATURE_ELNA cppflags-$(CONFIG_PLD_SDIO_CNSS_FLAG) += -DCONFIG_PLD_SDIO_CNSS -cppflags-$(CONFIG_PLD_PCIE_CNSS_FLAG) += -DCONFIG_PLD_PCIE_CNSS + +ifeq ($(CONFIG_PLD_PCIE_CNSS_FLAG), y) +ifeq ($(CONFIG_PCIE_FW_SIM), y) +cppflags-y += -DCONFIG_PLD_PCIE_FW_SIM +else +cppflags-y += -DCONFIG_PLD_PCIE_CNSS +endif +endif + cppflags-$(CONFIG_PLD_PCIE_INIT_FLAG) += -DCONFIG_PLD_PCIE_INIT cppflags-$(CONFIG_WLAN_FEATURE_DP_RX_THREADS) += -DFEATURE_WLAN_DP_RX_THREADS cppflags-$(CONFIG_WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT) += -DWLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT @@ -2159,7 +2172,13 @@ cppflags-y += -DFEATURE_RUNTIME_PM endif endif -cppflags-$(CONFIG_ICNSS) += -DCONFIG_PLD_SNOC_ICNSS +ifeq ($(CONFIG_ICNSS), y) +ifeq ($(CONFIG_SNOC_FW_SIM), y) +cppflags-y += -DCONFIG_PLD_SNOC_FW_SIM +else +cppflags-y += -DCONFIG_PLD_SNOC_ICNSS +endif +endif cppflags-$(CONFIG_WIFI_3_0_ADRASTEA) += -DQCA_WIFI_3_0_ADRASTEA cppflags-$(CONFIG_WIFI_3_0_ADRASTEA) += -DQCA_WIFI_3_0 diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index 86158b0412a2..6d2354bf995c 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -211,8 +211,10 @@ static void hdd_deinit_cds_hif_context(void) static enum qdf_bus_type to_bus_type(enum pld_bus_type bus_type) { switch (bus_type) { + case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: return QDF_BUS_TYPE_PCI; + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: return QDF_BUS_TYPE_SNOC; case PLD_BUS_TYPE_SDIO: diff --git a/core/pld/inc/pld_common.h b/core/pld/inc/pld_common.h index de22d85fc557..1a2e20a1245b 100644 --- a/core/pld/inc/pld_common.h +++ b/core/pld/inc/pld_common.h @@ -47,13 +47,19 @@ * @PLD_BUS_TYPE_NONE: invalid bus type, only return in error cases * @PLD_BUS_TYPE_PCIE: PCIE bus * @PLD_BUS_TYPE_SNOC: SNOC bus + * @PLD_BUS_TYPE_SDIO: SDIO bus + * @PLD_BUS_TYPE_USB : USB bus + * @PLD_BUS_TYPE_SNOC_FW_SIM : SNOC FW SIM bus + * @PLD_BUS_TYPE_PCIE_FW_SIM : PCIE FW SIM bus */ enum pld_bus_type { PLD_BUS_TYPE_NONE = -1, PLD_BUS_TYPE_PCIE = 0, PLD_BUS_TYPE_SNOC, PLD_BUS_TYPE_SDIO, - PLD_BUS_TYPE_USB + PLD_BUS_TYPE_USB, + PLD_BUS_TYPE_SNOC_FW_SIM, + PLD_BUS_TYPE_PCIE_FW_SIM, }; #define PLD_MAX_FIRMWARE_SIZE (1 * 1024 * 1024) @@ -698,7 +704,94 @@ int pld_idle_shutdown(struct device *dev, */ int pld_idle_restart(struct device *dev, int (*restart_cb)(struct device *dev)); +/** + * pld_srng_request_irq() - Register IRQ for SRNG + * @dev: device + * @irq: IRQ number + * @handler: IRQ callback function + * @irqflags: IRQ flags + * @name: IRQ name + * @ctx: IRQ context + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_srng_request_irq(struct device *dev, int irq, irq_handler_t handler, + unsigned long irqflags, + const char *name, + void *ctx); +/** + * pld_srng_free_irq() - Free IRQ for SRNG + * @dev: device + * @irq: IRQ number + * @ctx: IRQ context + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_srng_free_irq(struct device *dev, int irq, void *ctx); +/** + * pld_srng_enable_irq() - Enable IRQ for SRNG + * @dev: device + * @irq: IRQ number + * + * Return: void + */ +void pld_srng_enable_irq(struct device *dev, int irq); + +/** + * pld_disable_irq() - Disable IRQ for SRNG + * @dev: device + * @irq: IRQ number + * + * Return: void + */ +void pld_srng_disable_irq(struct device *dev, int irq); + +/** + * pld_pci_read_config_word() - Read PCI config + * @pdev: pci device + * @offset: Config space offset + * @val : Value + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pci_read_config_word(struct pci_dev *pdev, int offset, uint16_t *val); + +/** + * pld_pci_write_config_word() - Write PCI config + * @pdev: pci device + * @offset: Config space offset + * @val : Value + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pci_write_config_word(struct pci_dev *pdev, int offset, uint16_t val); + +/** + * pld_pci_read_config_dword() - Read PCI config + * @pdev: pci device + * @offset: Config space offset + * @val : Value + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pci_read_config_dword(struct pci_dev *pdev, int offset, uint32_t *val); + +/** + * pld_pci_write_config_dword() - Write PCI config + * @pdev: pci device + * @offset: Config space offset + * @val : Value + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pci_write_config_dword(struct pci_dev *pdev, int offset, uint32_t val); #if defined(CONFIG_WCNSS_MEM_PRE_ALLOC) && defined(FEATURE_SKB_PRE_ALLOC) /** diff --git a/core/pld/src/pld_common.c b/core/pld/src/pld_common.c index ce690fed64df..46dd193f715c 100644 --- a/core/pld/src/pld_common.c +++ b/core/pld/src/pld_common.c @@ -36,6 +36,8 @@ #endif #include "pld_pcie.h" +#include "pld_pcie_fw_sim.h" +#include "pld_snoc_fw_sim.h" #include "pld_snoc.h" #include "pld_sdio.h" #include "pld_usb.h" @@ -45,6 +47,8 @@ #define PLD_SNOC_REGISTERED BIT(1) #define PLD_SDIO_REGISTERED BIT(2) #define PLD_USB_REGISTERED BIT(3) +#define PLD_SNOC_FW_SIM_REGISTERED BIT(4) +#define PLD_PCIE_FW_SIM_REGISTERED BIT(5) #define PLD_BUS_MASK 0xf static struct pld_context *pld_ctx; @@ -288,6 +292,20 @@ int pld_register_driver(struct pld_driver_ops *ops) } pld_context->pld_driver_state |= PLD_SDIO_REGISTERED; + ret = pld_snoc_fw_sim_register_driver(); + if (ret) { + pr_err("Fail to register snoc fw sim driver\n"); + goto fail_snoc_fw_sim; + } + pld_context->pld_driver_state |= PLD_SNOC_FW_SIM_REGISTERED; + + ret = pld_pcie_fw_sim_register_driver(); + if (ret) { + pr_err("Fail to register pcie fw sim driver\n"); + goto fail_pcie_fw_sim; + } + pld_context->pld_driver_state |= PLD_PCIE_FW_SIM_REGISTERED; + ret = pld_usb_register_driver(); if (ret) { pr_err("Fail to register usb driver\n"); @@ -298,6 +316,10 @@ int pld_register_driver(struct pld_driver_ops *ops) return ret; fail_usb: + pld_pcie_fw_sim_unregister_driver(); +fail_pcie_fw_sim: + pld_snoc_fw_sim_unregister_driver(); +fail_snoc_fw_sim: pld_sdio_unregister_driver(); fail_sdio: pld_snoc_unregister_driver(); @@ -336,6 +358,8 @@ void pld_unregister_driver(void) } pld_pcie_unregister_driver(); + pld_snoc_fw_sim_unregister_driver(); + pld_pcie_fw_sim_unregister_driver(); pld_snoc_unregister_driver(); pld_sdio_unregister_driver(); pld_usb_unregister_driver(); @@ -370,6 +394,14 @@ int pld_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config, case PLD_BUS_TYPE_SNOC: ret = pld_snoc_wlan_enable(dev, config, mode, QWLAN_VERSIONSTR); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + ret = pld_snoc_fw_sim_wlan_enable(dev, config, mode, + QWLAN_VERSIONSTR); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + ret = pld_pcie_fw_sim_wlan_enable(dev, config, mode, + QWLAN_VERSIONSTR); + break; case PLD_BUS_TYPE_SDIO: ret = pld_sdio_wlan_enable(dev, config, mode, QWLAN_VERSIONSTR); break; @@ -407,6 +439,12 @@ int pld_wlan_disable(struct device *dev, enum pld_driver_mode mode) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_wlan_disable(dev, mode); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + ret = pld_snoc_fw_sim_wlan_disable(dev, mode); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + ret = pld_pcie_fw_sim_wlan_disable(dev, mode); + break; case PLD_BUS_TYPE_SDIO: break; default: @@ -438,6 +476,8 @@ int pld_set_fw_log_mode(struct device *dev, u8 fw_log_mode) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_set_fw_log_mode(dev, fw_log_mode); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SDIO: break; default: @@ -500,6 +540,8 @@ int pld_get_fw_files_for_target(struct device *dev, target_type, target_version); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -531,9 +573,12 @@ int pld_get_fw_files_for_target(struct device *dev, void pld_is_pci_link_down(struct device *dev) { switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE_FW_SIM: + break; case PLD_BUS_TYPE_PCIE: pld_pcie_link_down(dev); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; default: @@ -558,6 +603,8 @@ void pld_schedule_recovery_work(struct device *dev, case PLD_BUS_TYPE_PCIE: pld_pcie_schedule_recovery_work(dev, reason); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; default: @@ -586,6 +633,8 @@ int pld_wlan_pm_control(struct device *dev, bool vote) case PLD_BUS_TYPE_PCIE: ret = pld_pcie_wlan_pm_control(dev, vote); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -613,6 +662,8 @@ void *pld_get_virt_ramdump_mem(struct device *dev, unsigned long *size) case PLD_BUS_TYPE_PCIE: mem = pld_pcie_get_virt_ramdump_mem(dev, size); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -632,6 +683,8 @@ void pld_release_virt_ramdump_mem(struct device *dev, void *address) case PLD_BUS_TYPE_PCIE: pld_pcie_release_virt_ramdump_mem(address); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -658,6 +711,8 @@ void pld_device_crashed(struct device *dev) case PLD_BUS_TYPE_PCIE: pld_pcie_device_crashed(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -683,6 +738,8 @@ void pld_device_self_recovery(struct device *dev, case PLD_BUS_TYPE_PCIE: pld_pcie_device_self_recovery(dev, reason); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -708,6 +765,8 @@ void pld_intr_notify_q6(struct device *dev) case PLD_BUS_TYPE_PCIE: pld_pcie_intr_notify_q6(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; default: @@ -731,6 +790,8 @@ void pld_request_pm_qos(struct device *dev, u32 qos_val) case PLD_BUS_TYPE_PCIE: pld_pcie_request_pm_qos(dev, qos_val); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -758,6 +819,8 @@ void pld_remove_pm_qos(struct device *dev) case PLD_BUS_TYPE_PCIE: pld_pcie_remove_pm_qos(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -787,6 +850,8 @@ int pld_request_bus_bandwidth(struct device *dev, int bandwidth) case PLD_BUS_TYPE_PCIE: ret = pld_pcie_request_bus_bandwidth(dev, bandwidth); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -818,6 +883,10 @@ int pld_get_platform_cap(struct device *dev, struct pld_platform_cap *cap) case PLD_BUS_TYPE_PCIE: ret = pld_pcie_get_platform_cap(dev, cap); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + ret = pld_pcie_fw_sim_get_platform_cap(dev, cap); + break; + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -853,6 +922,8 @@ int pld_get_sha_hash(struct device *dev, const u8 *data, ret = pld_pcie_get_sha_hash(dev, data, data_len, hash_idx, out); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -879,6 +950,8 @@ void *pld_get_fw_ptr(struct device *dev) case PLD_BUS_TYPE_PCIE: ptr = pld_pcie_get_fw_ptr(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -906,6 +979,8 @@ int pld_auto_suspend(struct device *dev) case PLD_BUS_TYPE_PCIE: ret = pld_pcie_auto_suspend(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -933,6 +1008,8 @@ int pld_auto_resume(struct device *dev) case PLD_BUS_TYPE_PCIE: ret = pld_pcie_auto_resume(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -961,6 +1038,8 @@ int pld_force_wake_request(struct device *dev) case PLD_BUS_TYPE_PCIE: ret = pld_pcie_force_wake_request(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: @@ -991,6 +1070,8 @@ int pld_is_device_awake(struct device *dev) case PLD_BUS_TYPE_PCIE: ret = pld_pcie_is_device_awake(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: @@ -1020,6 +1101,8 @@ int pld_force_wake_release(struct device *dev) case PLD_BUS_TYPE_PCIE: ret = pld_pcie_force_wake_release(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: @@ -1056,6 +1139,11 @@ int pld_ce_request_irq(struct device *dev, unsigned int ce_id, ret = pld_snoc_ce_request_irq(dev, ce_id, handler, flags, name, ctx); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + ret = pld_snoc_fw_sim_ce_request_irq(dev, ce_id, + handler, flags, name, ctx); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: break; default: @@ -1083,6 +1171,10 @@ int pld_ce_free_irq(struct device *dev, unsigned int ce_id, void *ctx) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_ce_free_irq(dev, ce_id, ctx); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + ret = pld_snoc_fw_sim_ce_free_irq(dev, ce_id, ctx); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: break; default: @@ -1106,6 +1198,10 @@ void pld_enable_irq(struct device *dev, unsigned int ce_id) case PLD_BUS_TYPE_SNOC: pld_snoc_enable_irq(dev, ce_id); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + pld_snoc_fw_sim_enable_irq(dev, ce_id); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: break; case PLD_BUS_TYPE_SDIO: @@ -1129,6 +1225,10 @@ void pld_disable_irq(struct device *dev, unsigned int ce_id) case PLD_BUS_TYPE_SNOC: pld_snoc_disable_irq(dev, ce_id); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + pld_snoc_fw_sim_disable_irq(dev, ce_id); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: break; case PLD_BUS_TYPE_SDIO: @@ -1157,6 +1257,12 @@ int pld_get_soc_info(struct device *dev, struct pld_soc_info *info) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_get_soc_info(dev, info); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + ret = pld_snoc_fw_sim_get_soc_info(dev, info); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + ret = pld_pcie_fw_sim_get_soc_info(dev, info); + break; case PLD_BUS_TYPE_PCIE: ret = pld_pcie_get_soc_info(dev, info); break; @@ -1185,9 +1291,14 @@ int pld_get_ce_id(struct device *dev, int irq) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_get_ce_id(dev, irq); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + ret = pld_snoc_fw_sim_get_ce_id(dev, irq); + break; case PLD_BUS_TYPE_PCIE: ret = pld_pcie_get_ce_id(dev, irq); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + break; default: ret = -EINVAL; break; @@ -1211,6 +1322,10 @@ int pld_get_irq(struct device *dev, int ce_id) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_get_irq(dev, ce_id); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + ret = pld_snoc_fw_sim_get_irq(dev, ce_id); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: default: ret = -EINVAL; @@ -1232,6 +1347,8 @@ void pld_lock_pm_sem(struct device *dev) case PLD_BUS_TYPE_PCIE: pld_pcie_lock_pm_sem(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -1256,6 +1373,8 @@ void pld_release_pm_sem(struct device *dev) case PLD_BUS_TYPE_PCIE: pld_pcie_release_pm_sem(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -1286,6 +1405,9 @@ int pld_power_on(struct device *dev) * handle the power on sequence for PCIe SoC */ break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; case PLD_BUS_TYPE_SNOC: ret = pld_snoc_power_on(dev); break; @@ -1315,6 +1437,9 @@ int pld_power_off(struct device *dev) * handle the power off sequence for PCIe SoC */ break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; case PLD_BUS_TYPE_SNOC: ret = pld_snoc_power_off(dev); break; @@ -1354,6 +1479,8 @@ int pld_athdiag_read(struct device *dev, uint32_t offset, break; case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: break; default: ret = -EINVAL; @@ -1391,6 +1518,8 @@ int pld_athdiag_write(struct device *dev, uint32_t offset, break; case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: break; default: ret = -EINVAL; @@ -1419,6 +1548,9 @@ void *pld_smmu_get_domain(struct device *dev) case PLD_BUS_TYPE_PCIE: ptr = pld_pcie_smmu_get_domain(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: pr_err("Not supported on type %d\n", type); @@ -1446,6 +1578,9 @@ void *pld_smmu_get_mapping(struct device *dev) case PLD_BUS_TYPE_SNOC: ptr = pld_snoc_smmu_get_mapping(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; case PLD_BUS_TYPE_PCIE: ptr = pld_pcie_smmu_get_mapping(dev); break; @@ -1478,6 +1613,9 @@ int pld_smmu_map(struct device *dev, phys_addr_t paddr, case PLD_BUS_TYPE_SNOC: ret = pld_snoc_smmu_map(dev, paddr, iova_addr, size); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; case PLD_BUS_TYPE_PCIE: ret = pld_pcie_smmu_map(dev, paddr, iova_addr, size); break; @@ -1516,9 +1654,16 @@ int pld_get_user_msi_assignment(struct device *dev, char *user_name, user_base_data, base_vector); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + ret = pld_pcie_fw_sim_get_user_msi_assignment(dev, user_name, + num_vectors, + user_base_data, + base_vector); + break; case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_SNOC_FW_SIM: pr_err("Not supported on type %d\n", type); ret = -ENODEV; break; @@ -1531,6 +1676,273 @@ int pld_get_user_msi_assignment(struct device *dev, char *user_name, return ret; } +/** + * pld_srng_request_irq() - Register IRQ for SRNG + * @dev: device + * @irq: IRQ number + * @handler: IRQ callback function + * @flags: IRQ flags + * @name: IRQ name + * @ctx: IRQ context + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_srng_request_irq(struct device *dev, int irq, irq_handler_t handler, + unsigned long irqflags, + const char *devname, + void *dev_data) +{ + int ret = 0; + enum pld_bus_type type = pld_get_bus_type(dev); + + switch (type) { + case PLD_BUS_TYPE_PCIE: + ret = request_irq(irq, handler, irqflags, devname, dev_data); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + ret = pld_pcie_fw_sim_request_irq(dev, irq, handler, + irqflags, devname, + dev_data); + break; + case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_SDIO: + case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_SNOC_FW_SIM: + pr_err("Not supported on type %d\n", type); + ret = -ENODEV; + break; + default: + pr_err("Invalid device type %d\n", type); + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_srng_free_irq() - Free IRQ for SRNG + * @dev: device + * @irq: IRQ number + * @handler: IRQ callback function + * @flags: IRQ flags + * @name: IRQ name + * @ctx: IRQ context + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_srng_free_irq(struct device *dev, int irq, void *dev_data) +{ + int ret = 0; + enum pld_bus_type type = pld_get_bus_type(dev); + + switch (type) { + case PLD_BUS_TYPE_PCIE: + free_irq(irq, dev_data); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + ret = pld_pcie_fw_sim_free_irq(dev, irq, dev_data); + break; + case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_SDIO: + case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_SNOC_FW_SIM: + pr_err("Not supported on type %d\n", type); + ret = -ENODEV; + break; + default: + pr_err("Invalid device type %d\n", type); + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_srng_enable_irq() - Enable IRQ for SRNG + * @dev: device + * @irq: IRQ number + * + * Return: void + */ +void pld_srng_enable_irq(struct device *dev, int irq) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + pld_pcie_fw_sim_enable_irq(dev, irq); + break; + case PLD_BUS_TYPE_PCIE: + enable_irq(irq); + break; + case PLD_BUS_TYPE_SDIO: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_disable_irq() - Disable IRQ for SRNG + * @dev: device + * @irq: IRQ number + * + * Return: void + */ +void pld_srng_disable_irq(struct device *dev, int irq) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + pld_pcie_fw_sim_disable_irq(dev, irq); + break; + case PLD_BUS_TYPE_PCIE: + disable_irq_nosync(irq); + break; + case PLD_BUS_TYPE_SDIO: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_pci_read_config_word() - Read PCI config + * @pdev: pci device + * @offset: Config space offset + * @val : Value + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pci_read_config_word(struct pci_dev *pdev, int offset, uint16_t *val) +{ + int ret = 0; + + switch (pld_get_bus_type(&pdev->dev)) { + case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE: + ret = pci_read_config_word(pdev, offset, val); + break; + case PLD_BUS_TYPE_SDIO: + break; + default: + pr_err("Invalid device type\n"); + break; + } + + return ret; +} + +/** + * pld_pci_write_config_word() - Write PCI config + * @pdev: pci device + * @offset: Config space offset + * @val : Value + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pci_write_config_word(struct pci_dev *pdev, int offset, uint16_t val) +{ + int ret = 0; + + switch (pld_get_bus_type(&pdev->dev)) { + case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE: + ret = pci_write_config_word(pdev, offset, val); + break; + case PLD_BUS_TYPE_SDIO: + break; + default: + pr_err("Invalid device type\n"); + break; + } + + return ret; +} + +/** + * pld_pci_read_config_dword() - Read PCI config + * @pdev: pci device + * @offset: Config space offset + * @val : Value + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pci_read_config_dword(struct pci_dev *pdev, int offset, uint32_t *val) +{ + int ret = 0; + + switch (pld_get_bus_type(&pdev->dev)) { + case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE: + ret = pci_read_config_dword(pdev, offset, val); + break; + case PLD_BUS_TYPE_SDIO: + break; + default: + pr_err("Invalid device type\n"); + break; + } + + return ret; +} + +/** + * pld_pci_write_config_dword() - Write PCI config + * @pdev: pci device + * @offset: Config space offset + * @val : Value + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pci_write_config_dword(struct pci_dev *pdev, int offset, uint32_t val) +{ + int ret = 0; + + switch (pld_get_bus_type(&pdev->dev)) { + case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE: + ret = pci_write_config_dword(pdev, offset, val); + break; + case PLD_BUS_TYPE_SDIO: + break; + default: + pr_err("Invalid device type\n"); + break; + } + + return ret; +} + /** * pld_get_msi_irq() - Get MSI IRQ number used for request_irq() * @dev: device structure @@ -1548,9 +1960,13 @@ int pld_get_msi_irq(struct device *dev, unsigned int vector) case PLD_BUS_TYPE_PCIE: ret = pld_pcie_get_msi_irq(dev, vector); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + ret = pld_pcie_fw_sim_get_msi_irq(dev, vector); + break; case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_SNOC_FW_SIM: pr_err("Not supported on type %d\n", type); ret = -ENODEV; break; @@ -1580,9 +1996,14 @@ void pld_get_msi_address(struct device *dev, uint32_t *msi_addr_low, case PLD_BUS_TYPE_PCIE: pld_pcie_get_msi_address(dev, msi_addr_low, msi_addr_high); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + pld_pcie_fw_sim_get_msi_address(dev, msi_addr_low, + msi_addr_high); + break; case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_SNOC_FW_SIM: pr_err("Not supported on type %d\n", type); break; default: @@ -1608,6 +2029,8 @@ int pld_is_drv_connected(struct device *dev) case PLD_BUS_TYPE_PCIE: ret = pld_pcie_is_drv_connected(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: @@ -1636,9 +2059,12 @@ unsigned int pld_socinfo_get_serial_number(struct device *dev) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_socinfo_get_serial_number(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: pr_err("Not supported on type %d\n", type); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; default: pr_err("Invalid device type %d\n", type); break; @@ -1664,6 +2090,9 @@ int pld_is_qmi_disable(struct device *dev) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_is_qmi_disable(dev); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: case PLD_BUS_TYPE_SDIO: pr_err("Not supported on type %d\n", type); @@ -1699,6 +2128,11 @@ int pld_is_fw_down(struct device *dev) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_is_fw_down(dev); break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + ret = pld_snoc_fw_sim_is_fw_down(dev); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + break; case PLD_BUS_TYPE_PCIE: ret = pld_pcie_is_fw_down(dev); break; @@ -1735,6 +2169,9 @@ int pld_force_assert_target(struct device *dev) return pld_snoc_force_assert_target(dev); case PLD_BUS_TYPE_PCIE: return pld_pcie_force_assert_target(dev); + case PLD_BUS_TYPE_PCIE_FW_SIM: + return -EOPNOTSUPP; + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SDIO: return -EINVAL; default: @@ -1758,6 +2195,8 @@ int pld_collect_rddm(struct device *dev) switch (type) { case PLD_BUS_TYPE_PCIE: return pld_pcie_collect_rddm(dev); + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: @@ -1873,6 +2312,8 @@ bool pld_is_fw_dump_skipped(struct device *dev) case PLD_BUS_TYPE_SDIO: ret = pld_sdio_is_fw_dump_skipped(); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: default: break; } @@ -1888,6 +2329,8 @@ int pld_is_pdr(struct device *dev) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_is_pdr(); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: default: break; } @@ -1903,6 +2346,8 @@ int pld_is_fw_rejuvenate(struct device *dev) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_is_fw_rejuvenate(); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: default: break; } @@ -1917,6 +2362,10 @@ bool pld_have_platform_driver_support(struct device *dev) case PLD_BUS_TYPE_PCIE: ret = pld_pcie_platform_driver_support(); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + ret = true; + break; + case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; case PLD_BUS_TYPE_SDIO: @@ -1949,6 +2398,12 @@ int pld_idle_shutdown(struct device *dev, case PLD_BUS_TYPE_PCIE: errno = pld_pcie_idle_shutdown(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + errno = pld_pcie_fw_sim_idle_shutdown(dev); + break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + errno = pld_snoc_fw_sim_idle_shutdown(dev); + break; default: pr_err("Invalid device type %d\n", type); break; @@ -1976,6 +2431,12 @@ int pld_idle_restart(struct device *dev, case PLD_BUS_TYPE_PCIE: errno = pld_pcie_idle_restart(dev); break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + errno = pld_pcie_fw_sim_idle_restart(dev); + break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + errno = pld_snoc_fw_sim_idle_restart(dev); + break; default: pr_err("Invalid device type %d\n", type); break; diff --git a/core/pld/src/pld_pcie.h b/core/pld/src/pld_pcie.h index aab8196ba54a..8abc885859b2 100644 --- a/core/pld/src/pld_pcie.h +++ b/core/pld/src/pld_pcie.h @@ -22,6 +22,7 @@ #ifdef CONFIG_PLD_PCIE_CNSS #include #endif +#include #include "pld_internal.h" #ifdef DYNAMIC_SINGLE_CHIP @@ -36,7 +37,7 @@ #endif -#ifndef HIF_PCI +#ifndef CONFIG_PLD_PCIE_CNSS static inline int pld_pcie_register_driver(void) { return 0; diff --git a/core/pld/src/pld_pcie_fw_sim.c b/core/pld/src/pld_pcie_fw_sim.c new file mode 100644 index 000000000000..46f9ac281fe0 --- /dev/null +++ b/core/pld/src/pld_pcie_fw_sim.c @@ -0,0 +1,453 @@ +/* + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include "osif_psoc_sync.h" + +#include "pld_pcie_fw_sim.h" + +#ifdef CONFIG_PLD_PCIE_FW_SIM + +#ifdef QCA_WIFI_3_0_ADRASTEA +#define CE_COUNT_MAX 12 +#else +#define CE_COUNT_MAX 8 +#endif + +/** + * pld_pcie_fw_sim_probe() - Probe function for PCIE platform driver + * @pdev: PCIE device + * @id: PCIE device ID table + * + * The probe function will be called when PCIE device provided + * in the ID table is detected. + * + * Return: int + */ +static int pld_pcie_fw_sim_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct pld_context *pld_context; + int ret = 0; + + pld_context = pld_get_global_context(); + if (!pld_context) { + ret = -ENODEV; + goto out; + } + + ret = pld_add_dev(pld_context, &pdev->dev, NULL, + PLD_BUS_TYPE_PCIE_FW_SIM); + if (ret) + goto out; + + return pld_context->ops->probe(&pdev->dev, + PLD_BUS_TYPE_PCIE_FW_SIM, pdev, (void *)id); + +out: + return ret; +} + +/** + * pld_pcie_fw_sim_remove() - Remove function for PCIE device + * @pdev: PCIE device + * + * The remove function will be called when PCIE device is disconnected + * + * Return: void + */ +static void pld_pcie_fw_sim_remove(struct pci_dev *pdev) +{ + struct pld_context *pld_context; + int errno; + struct osif_psoc_sync *psoc_sync; + + errno = osif_psoc_sync_trans_start_wait(&pdev->dev, &psoc_sync); + if (errno) + return; + + osif_psoc_sync_unregister(&pdev->dev); + osif_psoc_sync_wait_for_ops(psoc_sync); + + pld_context = pld_get_global_context(); + + if (!pld_context) + goto out; + + pld_context->ops->remove(&pdev->dev, PLD_BUS_TYPE_PCIE_FW_SIM); + + pld_del_dev(pld_context, &pdev->dev); + +out: + osif_psoc_sync_trans_stop(psoc_sync); + osif_psoc_sync_destroy(psoc_sync); +} + +/** + * pld_pcie_fw_sim_idle_restart_cb() - Perform idle restart + * @pdev: PCIE device + * @id: PCIE device ID + * + * This function will be called if there is an idle restart request + * + * Return: int + */ +static int pld_pcie_fw_sim_idle_restart_cb(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->idle_restart) + return pld_context->ops->idle_restart(&pdev->dev, + PLD_BUS_TYPE_PCIE_FW_SIM); + + return -ENODEV; +} + +/** + * pld_pcie_fw_sim_idle_shutdown_cb() - Perform idle shutdown + * @pdev: PCIE device + * @id: PCIE device ID + * + * This function will be called if there is an idle shutdown request + * + * Return: int + */ +static int pld_pcie_fw_sim_idle_shutdown_cb(struct pci_dev *pdev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->shutdown) + return pld_context->ops->idle_shutdown(&pdev->dev, + PLD_BUS_TYPE_PCIE_FW_SIM); + + return -ENODEV; +} + +/** + * pld_pcie_fw_sim_reinit() - SSR re-initialize function for PCIE device + * @pdev: PCIE device + * @id: PCIE device ID + * + * During subsystem restart(SSR), this function will be called to + * re-initialize pcie device. + * + * Return: int + */ +static int pld_pcie_fw_sim_reinit(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->reinit) + return pld_context->ops->reinit(&pdev->dev, + PLD_BUS_TYPE_PCIE_FW_SIM, pdev, (void *)id); + + return -ENODEV; +} + +/** + * pld_pcie_fw_sim_shutdown() - SSR shutdown function for PCIE device + * @pdev: PCIE device + * + * During SSR, this function will be called to shutdown PCIE device. + * + * Return: void + */ +static void pld_pcie_fw_sim_shutdown(struct pci_dev *pdev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->shutdown) + pld_context->ops->shutdown(&pdev->dev, + PLD_BUS_TYPE_PCIE_FW_SIM); +} + +/** + * pld_pcie_fw_sim_crash_shutdown() - Crash shutdown function for PCIE device + * @pdev: PCIE device + * + * This function will be called when a crash is detected, it will shutdown + * the PCIE device. + * + * Return: void + */ +static void pld_pcie_fw_sim_crash_shutdown(struct pci_dev *pdev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->crash_shutdown) + pld_context->ops->crash_shutdown(&pdev->dev, + PLD_BUS_TYPE_PCIE_FW_SIM); +} + +/** + * pld_pcie_fw_sim_notify_handler() - Modem state notification callback function + * @pdev: PCIE device + * @state: modem power state + * + * This function will be called when there's a modem power state change. + * + * Return: void + */ +static void pld_pcie_fw_sim_notify_handler(struct pci_dev *pdev, int state) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->modem_status) + pld_context->ops->modem_status(&pdev->dev, + PLD_BUS_TYPE_PCIE_FW_SIM, state); +} + +/** + * pld_pcie_fw_sim_uevent() - update wlan driver status callback function + * @pdev: PCIE device + * @status driver uevent status + * + * This function will be called when platform driver wants to update wlan + * driver's status. + * + * Return: void + */ +static void pld_pcie_fw_sim_uevent(struct pci_dev *pdev, uint32_t status) +{ + struct pld_context *pld_context; + struct pld_uevent_data data; + + pld_context = pld_get_global_context(); + if (!pld_context) + return; + + switch (status) { + case CNSS_RECOVERY: + data.uevent = PLD_FW_RECOVERY_START; + break; + case CNSS_FW_DOWN: + data.uevent = PLD_FW_DOWN; + break; + default: + goto out; + } + + if (pld_context->ops->uevent) + pld_context->ops->uevent(&pdev->dev, &data); + +out: + return; +} + +static struct pci_device_id pld_pcie_fw_sim_id_table[] = { + { 0x168c, 0x003c, PCI_ANY_ID, PCI_ANY_ID }, + { 0x168c, 0x003e, PCI_ANY_ID, PCI_ANY_ID }, + { 0x168c, 0x0041, PCI_ANY_ID, PCI_ANY_ID }, + { 0x168c, 0xabcd, PCI_ANY_ID, PCI_ANY_ID }, + { 0x168c, 0x7021, PCI_ANY_ID, PCI_ANY_ID }, + { 0 } +}; + +#ifdef MULTI_IF_NAME +#define PLD_PCIE_FW_SIM_OPS_NAME "pld_pcie_fw_sim_" MULTI_IF_NAME +#else +#define PLD_PCIE_FW_SIM_OPS_NAME "pld_pcie_fw_sim" +#endif + +struct cnss_wlan_driver pld_pcie_fw_sim_ops = { + .name = PLD_PCIE_FW_SIM_OPS_NAME, + .id_table = pld_pcie_fw_sim_id_table, + .probe = pld_pcie_fw_sim_probe, + .remove = pld_pcie_fw_sim_remove, + .idle_restart = pld_pcie_fw_sim_idle_restart_cb, + .idle_shutdown = pld_pcie_fw_sim_idle_shutdown_cb, + .reinit = pld_pcie_fw_sim_reinit, + .shutdown = pld_pcie_fw_sim_shutdown, + .crash_shutdown = pld_pcie_fw_sim_crash_shutdown, + .modem_status = pld_pcie_fw_sim_notify_handler, + .update_status = pld_pcie_fw_sim_uevent, +}; + +/** + * pld_pcie_fw_sim_register_driver() - Register PCIE device callback functions + * + * Return: int + */ +int pld_pcie_fw_sim_register_driver(void) +{ + return cnss_fw_sim_wlan_register_driver(&pld_pcie_fw_sim_ops); +} + +/** + * pld_pcie_fw_sim_unregister_driver() - Unregister PCIE device callback + * functions + * + * Return: void + */ +void pld_pcie_fw_sim_unregister_driver(void) +{ + cnss_fw_sim_wlan_unregister_driver(&pld_pcie_fw_sim_ops); +} + +/** + * pld_pcie_fw_sim_wlan_enable() - Enable WLAN + * @dev: device + * @config: WLAN configuration data + * @mode: WLAN mode + * @host_version: host software version + * + * This function enables WLAN FW. It passed WLAN configuration data, + * WLAN mode and host software version to FW. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pcie_fw_sim_wlan_enable(struct device *dev, + struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, + const char *host_version) +{ + struct cnss_wlan_enable_cfg cfg; + enum cnss_driver_mode cnss_mode; + + cfg.num_ce_tgt_cfg = config->num_ce_tgt_cfg; + cfg.ce_tgt_cfg = (struct cnss_ce_tgt_pipe_cfg *) + config->ce_tgt_cfg; + cfg.num_ce_svc_pipe_cfg = config->num_ce_svc_pipe_cfg; + cfg.ce_svc_cfg = (struct cnss_ce_svc_pipe_cfg *) + config->ce_svc_cfg; + cfg.num_shadow_reg_cfg = config->num_shadow_reg_cfg; + cfg.shadow_reg_cfg = (struct cnss_shadow_reg_cfg *) + config->shadow_reg_cfg; + cfg.num_shadow_reg_v2_cfg = config->num_shadow_reg_v2_cfg; + cfg.shadow_reg_v2_cfg = (struct cnss_shadow_reg_v2_cfg *) + config->shadow_reg_v2_cfg; + cfg.rri_over_ddr_cfg_valid = config->rri_over_ddr_cfg_valid; + if (config->rri_over_ddr_cfg_valid) { + cfg.rri_over_ddr_cfg.base_addr_low = + config->rri_over_ddr_cfg.base_addr_low; + cfg.rri_over_ddr_cfg.base_addr_high = + config->rri_over_ddr_cfg.base_addr_high; + } + + switch (mode) { + case PLD_FTM: + cnss_mode = CNSS_FTM; + break; + case PLD_EPPING: + cnss_mode = CNSS_EPPING; + break; + default: + cnss_mode = CNSS_MISSION; + break; + } + return cnss_fw_sim_wlan_enable(dev, &cfg, cnss_mode, host_version); +} + +/** + * pld_pcie_fw_sim_wlan_disable() - Disable WLAN + * @dev: device + * @mode: WLAN mode + * + * This function disables WLAN FW. It passes WLAN mode to FW. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pcie_fw_sim_wlan_disable(struct device *dev, enum pld_driver_mode mode) +{ + return cnss_fw_sim_wlan_disable(dev, CNSS_OFF); +} + +/** + * pld_pcie_fw_sim_get_soc_info() - Get SOC information + * @dev: device + * @info: buffer to SOC information + * + * Return SOC info to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pcie_fw_sim_get_soc_info(struct device *dev, struct pld_soc_info *info) +{ + int ret = 0; + struct cnss_soc_info cnss_info = {0}; + + if (!info) + return -ENODEV; + + ret = cnss_fw_sim_get_soc_info(dev, &cnss_info); + if (ret) + return ret; + + info->v_addr = cnss_info.va; + info->p_addr = cnss_info.pa; + info->chip_id = cnss_info.chip_id; + info->chip_family = cnss_info.chip_family; + info->board_id = cnss_info.board_id; + info->soc_id = cnss_info.soc_id; + info->fw_version = cnss_info.fw_version; + strlcpy(info->fw_build_timestamp, cnss_info.fw_build_timestamp, + sizeof(info->fw_build_timestamp)); + info->device_version.family_number = + cnss_info.device_version.family_number; + info->device_version.device_number = + cnss_info.device_version.device_number; + info->device_version.major_version = + cnss_info.device_version.major_version; + info->device_version.minor_version = + cnss_info.device_version.minor_version; + + return 0; +} + +/** + * pld_pcie_fw_sim_get_platform_cap() - Get platform capabilities + * @dev: device + * @cap: buffer to the capabilities + * + * Return capabilities to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pcie_fw_sim_get_platform_cap(struct device *dev, + struct pld_platform_cap *cap) +{ + int ret = 0; + struct cnss_platform_cap cnss_cap; + + if (!cap) + return -ENODEV; + + ret = cnss_fw_sim_get_platform_cap(dev, &cnss_cap); + if (ret) + return ret; + + memcpy(cap, &cnss_cap, sizeof(*cap)); + return 0; +} + +#endif diff --git a/core/pld/src/pld_pcie_fw_sim.h b/core/pld/src/pld_pcie_fw_sim.h new file mode 100644 index 000000000000..0eed0d5ab743 --- /dev/null +++ b/core/pld/src/pld_pcie_fw_sim.h @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __PLD_PCIE_FW_SIM_H__ +#define __PLD_PCIE_FW_SIM_H__ + +#include "pld_internal.h" + +#ifndef CONFIG_PLD_PCIE_FW_SIM + +static inline int pld_pcie_fw_sim_register_driver(void) +{ + return 0; +} + +static inline void pld_pcie_fw_sim_unregister_driver(void) +{ +} + +static inline int pld_pcie_fw_sim_wlan_enable(struct device *dev, + struct pld_wlan_enable_cfg *cfg, + enum pld_driver_mode mode, + const char *host_version) +{ + return 0; +} + +static inline int pld_pcie_fw_sim_wlan_disable(struct device *dev, + enum pld_driver_mode mode) +{ + return 0; +} + +static inline void pld_pcie_fw_sim_link_down(struct device *dev) +{ +} + +static inline int pld_pcie_fw_sim_is_fw_down(struct device *dev) +{ + return 0; +} + +static inline int pld_pcie_fw_sim_get_platform_cap(struct device *dev, + struct pld_platform_cap *cap) +{ + return 0; +} + +static inline int pld_pcie_fw_sim_get_soc_info(struct device *dev, + struct pld_soc_info *info) +{ + return 0; +} + +static inline int pld_pcie_fw_sim_get_user_msi_assignment(struct device *dev, + char *user_name, + int *num_vectors, + uint32_t *base_data, + uint32_t *base_vector) +{ + return -EINVAL; +} + +static inline int pld_pcie_fw_sim_get_msi_irq(struct device *dev, + unsigned int vector) +{ + return 0; +} + +static inline void pld_pcie_fw_sim_get_msi_address(struct device *dev, + uint32_t *msi_addr_low, + uint32_t *msi_addr_high) +{ +} + +static inline int pld_pcie_fw_sim_request_irq(struct device *dev, int irq, + irq_handler_t handler, + unsigned long irqflags, + const char *devname, + void *dev_data) +{ + return 0; +} + +static inline int pld_pcie_fw_sim_free_irq(struct device *dev, + unsigned int ce_id, void *ctx) +{ + return 0; +} + +static inline void pld_pcie_fw_sim_enable_irq(struct device *dev, + unsigned int irq) +{ +} + +static inline void pld_pcie_fw_sim_disable_irq(struct device *dev, + unsigned int irq) +{ +} + +static inline int pld_pcie_fw_sim_idle_shutdown(struct device *dev) +{ + return 0; +} + +static inline int pld_pcie_fw_sim_idle_restart(struct device *dev) +{ + return 0; +} +#else +#include + +int pld_pcie_fw_sim_wlan_enable(struct device *dev, + struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, + const char *host_version); +int pld_pcie_fw_sim_wlan_disable(struct device *dev, enum pld_driver_mode mode); +int pld_pcie_fw_sim_register_driver(void); +void pld_pcie_fw_sim_unregister_driver(void); +int pld_pcie_fw_sim_get_platform_cap(struct device *dev, + struct pld_platform_cap *cap); +int pld_pcie_fw_sim_get_soc_info(struct device *dev, struct pld_soc_info *info); + +static inline int pld_pcie_fw_sim_get_user_msi_assignment(struct device *dev, + char *user_name, + int *num_vectors, + uint32_t *base_data, + uint32_t *base_vector) +{ + return cnss_fw_sim_get_user_msi_assignment(dev, user_name, num_vectors, + base_data, base_vector); +} + +static inline int pld_pcie_fw_sim_get_msi_irq(struct device *dev, + unsigned int vector) +{ + return cnss_fw_sim_get_msi_irq(dev, vector); +} + +static inline void pld_pcie_fw_sim_get_msi_address(struct device *dev, + uint32_t *msi_addr_low, + uint32_t *msi_addr_high) +{ + cnss_fw_sim_get_msi_address(dev, msi_addr_low, msi_addr_high); +} + +static inline int pld_pcie_fw_sim_request_irq(struct device *dev, int irq, + irq_handler_t handler, + unsigned long irqflags, + const char *devname, + void *dev_data) +{ + return cnss_fw_sim_request_irq(dev, irq, handler, + irqflags, devname, dev_data); +} + +static inline int pld_pcie_fw_sim_free_irq(struct device *dev, + int irq, void *dev_data) +{ + return cnss_fw_sim_free_irq(dev, irq, dev_data); +} + +static inline void pld_pcie_fw_sim_enable_irq(struct device *dev, int irq) +{ + cnss_fw_sim_enable_irq(dev, irq); +} + +static inline void pld_pcie_fw_sim_disable_irq(struct device *dev, int irq) +{ + cnss_fw_sim_disable_irq(dev, irq); +} + +static inline int pld_pcie_fw_sim_idle_shutdown(struct device *dev) +{ + return cnss_fw_sim_idle_shutdown(dev); +} + +static inline int pld_pcie_fw_sim_idle_restart(struct device *dev) +{ + return cnss_fw_sim_idle_restart(dev); +} +#endif +#endif diff --git a/core/pld/src/pld_snoc_fw_sim.c b/core/pld/src/pld_snoc_fw_sim.c new file mode 100644 index 000000000000..94c235971d9e --- /dev/null +++ b/core/pld/src/pld_snoc_fw_sim.c @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include "pld_snoc_fw_sim.h" + +#ifdef CONFIG_PLD_SNOC_FW_SIM +/** + * pld_snoc_fw_sim_probe() - Probe function for platform driver + * @dev: device + * + * The probe function will be called when platform device + * is detected. + * + * Return: int + */ +static int pld_snoc_fw_sim_probe(struct device *dev) +{ + struct pld_context *pld_context; + int ret = 0; + + pld_context = pld_get_global_context(); + if (!pld_context) { + ret = -ENODEV; + goto out; + } + + ret = pld_add_dev(pld_context, dev, NULL, PLD_BUS_TYPE_SNOC_FW_SIM); + if (ret) + goto out; + + return pld_context->ops->probe(dev, PLD_BUS_TYPE_SNOC_FW_SIM, + NULL, NULL); + +out: + return ret; +} + +/** + * pld_snoc_fw_sim_remove() - Remove function for platform device + * @dev: device + * + * The remove function will be called when platform device + * is disconnected + * + * Return: void + */ +static void pld_snoc_fw_sim_remove(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + + if (!pld_context) + return; + + pld_context->ops->remove(dev, PLD_BUS_TYPE_SNOC_FW_SIM); + + pld_del_dev(pld_context, dev); +} + +/** + * pld_snoc_fw_sim_reinit() - SSR re-initialize function for platform device + * @dev: device + * + * During subsystem restart(SSR), this function will be called to + * re-initialize platform device. + * + * Return: int + */ +static int pld_snoc_fw_sim_reinit(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->reinit) + return pld_context->ops->reinit(dev, PLD_BUS_TYPE_SNOC_FW_SIM, + NULL, NULL); + + return -ENODEV; +} + +/** + * pld_snoc_fw_sim_shutdown() - SSR shutdown function for platform device + * @dev: device + * + * During SSR, this function will be called to shutdown platform device. + * + * Return: void + */ +static void pld_snoc_fw_sim_shutdown(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->shutdown) + pld_context->ops->shutdown(dev, PLD_BUS_TYPE_SNOC_FW_SIM); +} + +/** + * pld_snoc_fw_sim_crash_shutdown() -Crash shutdown function for platform device + * @dev: device + * + * This function will be called when a crash is detected, it will shutdown + * platform device. + * + * Return: void + */ +static void pld_snoc_fw_sim_crash_shutdown(void *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->crash_shutdown) + pld_context->ops->crash_shutdown(dev, PLD_BUS_TYPE_SNOC_FW_SIM); +} + +/** + * pld_snoc_fw_sim_pm_suspend() - PM suspend callback function for power + * management + * @dev: device + * + * This function is to suspend the platform device when power management + * is enabled. + * + * Return: void + */ +static int pld_snoc_fw_sim_pm_suspend(struct device *dev) +{ + struct pld_context *pld_context; + pm_message_t state; + + state.event = PM_EVENT_SUSPEND; + pld_context = pld_get_global_context(); + return pld_context->ops->suspend(dev, PLD_BUS_TYPE_SNOC_FW_SIM, state); +} + +/** + * pld_snoc_fw_sim_pm_resume() -PM resume callback function for power management + * @pdev: device + * + * This function is to resume the platform device when power management + * is enabled. + * + * Return: void + */ +static int pld_snoc_fw_sim_pm_resume(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + return pld_context->ops->resume(dev, PLD_BUS_TYPE_SNOC_FW_SIM); +} + +/** + * pld_snoc_fw_sim_suspend_noirq() - Complete the actions started by suspend() + * @dev: device + * + * Complete the actions started by suspend(). Carry out any + * additional operations required for suspending the device that might be + * racing with its driver's interrupt handler, which is guaranteed not to + * run while suspend_noirq() is being executed. + * + * Return: 0 for success + * Non zero failure code for errors + */ +static int pld_snoc_fw_sim_suspend_noirq(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (!pld_context) + return -EINVAL; + + if (pld_context->ops->suspend_noirq) + return pld_context->ops->suspend_noirq(dev, + PLD_BUS_TYPE_SNOC_FW_SIM); + return 0; +} + +/** + * pld_snoc_fw_sim_resume_noirq() - Prepare for the execution of resume() + * @pdev: device + * + * Prepare for the execution of resume() by carrying out any + * operations required for resuming the device that might be racing with + * its driver's interrupt handler, which is guaranteed not to run while + * resume_noirq() is being executed. + * + * Return: 0 for success + * Non zero failure code for errors + */ +static int pld_snoc_fw_sim_resume_noirq(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (!pld_context) + return -EINVAL; + + if (pld_context->ops->resume_noirq) + return pld_context->ops->resume_noirq(dev, + PLD_BUS_TYPE_SNOC_FW_SIM); + + return 0; +} + +static int pld_snoc_fw_sim_uevent(struct device *dev, + struct icnss_uevent_data *uevent) +{ + struct pld_context *pld_context; + struct icnss_uevent_fw_down_data *uevent_data = NULL; + struct pld_uevent_data data; + + pld_context = pld_get_global_context(); + if (!pld_context) + return -EINVAL; + + if (!pld_context->ops->uevent) + return 0; + + if (!uevent) + return -EINVAL; + + switch (uevent->uevent) { + case ICNSS_UEVENT_FW_CRASHED: + data.uevent = PLD_FW_CRASHED; + break; + case ICNSS_UEVENT_FW_DOWN: + if (!uevent->data) + return -EINVAL; + uevent_data = (struct icnss_uevent_fw_down_data *)uevent->data; + data.uevent = PLD_FW_DOWN; + data.fw_down.crashed = uevent_data->crashed; + break; + default: + return 0; + } + + pld_context->ops->uevent(dev, &data); + return 0; +} + +#ifdef MULTI_IF_NAME +#define PLD_SNOC_FW_SIM_OPS_NAME "pld_snoc_fw_sim_" MULTI_IF_NAME +#else +#define PLD_SNOC_FW_SIM_OPS_NAME "pld_snoc_fw_sim" +#endif + +struct icnss_driver_ops pld_snoc_fw_sim_ops = { + .name = PLD_SNOC_FW_SIM_OPS_NAME, + .probe = pld_snoc_fw_sim_probe, + .remove = pld_snoc_fw_sim_remove, + .shutdown = pld_snoc_fw_sim_shutdown, + .reinit = pld_snoc_fw_sim_reinit, + .crash_shutdown = pld_snoc_fw_sim_crash_shutdown, + .pm_suspend = pld_snoc_fw_sim_pm_suspend, + .pm_resume = pld_snoc_fw_sim_pm_resume, + .suspend_noirq = pld_snoc_fw_sim_suspend_noirq, + .resume_noirq = pld_snoc_fw_sim_resume_noirq, + .uevent = pld_snoc_fw_sim_uevent, +}; + +/** + * pld_snoc_fw_sim_register_driver() - Register platform device callback + * functions + * + * Return: int + */ +int pld_snoc_fw_sim_register_driver(void) +{ + return icnss_register_driver(&pld_snoc_fw_sim_ops); +} + +/** + * pld_snoc_fw_sim_unregister_driver() - Unregister platform device callback + * functions + * + * Return: void + */ +void pld_snoc_fw_sim_unregister_driver(void) +{ + icnss_unregister_driver(&pld_snoc_fw_sim_ops); +} + +/** + * pld_snoc_fw_sim_wlan_enable() - Enable WLAN + * @dev: device + * @config: WLAN configuration data + * @mode: WLAN mode + * @host_version: host software version + * + * This function enables WLAN FW. It passed WLAN configuration data, + * WLAN mode and host software version to FW. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_snoc_fw_sim_wlan_enable(struct device *dev, + struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, + const char *host_version) +{ + struct icnss_wlan_enable_cfg cfg; + enum icnss_driver_mode icnss_mode; + + if (!dev) + return -ENODEV; + + cfg.num_ce_tgt_cfg = config->num_ce_tgt_cfg; + cfg.ce_tgt_cfg = (struct ce_tgt_pipe_cfg *) + config->ce_tgt_cfg; + cfg.num_ce_svc_pipe_cfg = config->num_ce_svc_pipe_cfg; + cfg.ce_svc_cfg = (struct ce_svc_pipe_cfg *) + config->ce_svc_cfg; + cfg.num_shadow_reg_cfg = config->num_shadow_reg_cfg; + cfg.shadow_reg_cfg = (struct icnss_shadow_reg_cfg *) + config->shadow_reg_cfg; + + switch (mode) { + case PLD_FTM: + icnss_mode = ICNSS_FTM; + break; + case PLD_EPPING: + icnss_mode = ICNSS_EPPING; + break; + default: + icnss_mode = ICNSS_MISSION; + break; + } + + return icnss_wlan_enable(dev, &cfg, icnss_mode, host_version); +} + +/** + * pld_snoc_fw_sim_wlan_disable() - Disable WLAN + * @dev: device + * @mode: WLAN mode + * + * This function disables WLAN FW. It passes WLAN mode to FW. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_snoc_fw_sim_wlan_disable(struct device *dev, enum pld_driver_mode mode) +{ + if (!dev) + return -ENODEV; + + return icnss_wlan_disable(dev, ICNSS_OFF); +} + +/** + * pld_snoc_fw_sim_get_soc_info() - Get SOC information + * @dev: device + * @info: buffer to SOC information + * + * Return SOC info to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_snoc_fw_sim_get_soc_info(struct device *dev, struct pld_soc_info *info) +{ + int ret = 0; + struct icnss_soc_info icnss_info; + + if (!info || !dev) + return -ENODEV; + + ret = icnss_get_soc_info(dev, &icnss_info); + if (0 != ret) + return ret; + + memcpy(info, &icnss_info, sizeof(*info)); + return 0; +} +#endif diff --git a/core/pld/src/pld_snoc_fw_sim.h b/core/pld/src/pld_snoc_fw_sim.h new file mode 100644 index 000000000000..5f68eb278207 --- /dev/null +++ b/core/pld/src/pld_snoc_fw_sim.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __PLD_SNOC_FW_SIM_H__ +#define __PLD_SNOC_FW_SIM_H__ + +#include "pld_internal.h" + +#ifndef CONFIG_PLD_SNOC_FW_SIM +static inline int pld_snoc_fw_sim_register_driver(void) +{ + return 0; +} + +static inline void pld_snoc_fw_sim_unregister_driver(void) +{ +} + +static inline int pld_snoc_fw_sim_wlan_enable(struct device *dev, + struct pld_wlan_enable_cfg *cfg, + enum pld_driver_mode mode, + const char *host_version) +{ + return 0; +} + +static inline int pld_snoc_fw_sim_wlan_disable(struct device *dev, + enum pld_driver_mode mode) +{ + return 0; +} + +static inline int pld_snoc_fw_sim_ce_request_irq(struct device *dev, + unsigned int ce_id, + irqreturn_t (*handler)(int, void *), + unsigned long flags, + const char *name, void *ctx) +{ + return 0; +} + +static inline int pld_snoc_fw_sim_ce_free_irq(struct device *dev, + unsigned int ce_id, void *ctx) +{ + return 0; +} + +static inline void pld_snoc_fw_sim_enable_irq(struct device *dev, + unsigned int ce_id) +{ +} + +static inline void pld_snoc_fw_sim_disable_irq(struct device *dev, + unsigned int ce_id) +{ +} + +static inline int pld_snoc_fw_sim_get_soc_info(struct device *dev, + struct pld_soc_info *info) +{ + return 0; +} + +static inline int pld_snoc_fw_sim_get_ce_id(struct device *dev, int irq) +{ + return 0; +} + +static inline int pld_snoc_fw_sim_get_irq(struct device *dev, int ce_id) +{ + return 0; +} + +static inline int pld_snoc_fw_sim_is_fw_down(struct device *dev) +{ + return 0; +} + +static inline int pld_snoc_fw_sim_idle_shutdown(struct device *dev) +{ + return 0; +} + +static inline int pld_snoc_fw_sim_idle_restart(struct device *dev) +{ + return 0; +} + +#else +#include + +int pld_snoc_fw_sim_register_driver(void); +void pld_snoc_fw_sim_unregister_driver(void); +int pld_snoc_fw_sim_wlan_enable(struct device *dev, + struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, + const char *host_version); +int pld_snoc_fw_sim_wlan_disable(struct device *dev, enum pld_driver_mode mode); +int pld_snoc_fw_sim_get_soc_info(struct device *dev, struct pld_soc_info *info); + +static inline int pld_snoc_fw_sim_ce_request_irq(struct device *dev, + unsigned int ce_id, + irqreturn_t (*handler)(int, void *), + unsigned long flags, + const char *name, void *ctx) +{ + if (!dev) + return -ENODEV; + + return icnss_ce_request_irq(dev, ce_id, handler, flags, name, ctx); +} + +static inline int pld_snoc_fw_sim_ce_free_irq(struct device *dev, + unsigned int ce_id, void *ctx) +{ + if (!dev) + return -ENODEV; + + return icnss_ce_free_irq(dev, ce_id, ctx); +} + +static inline void pld_snoc_fw_sim_enable_irq(struct device *dev, + unsigned int ce_id) +{ + if (dev) + icnss_enable_irq(dev, ce_id); +} + +static inline void pld_snoc_fw_sim_disable_irq(struct device *dev, + unsigned int ce_id) +{ + if (dev) + icnss_disable_irq(dev, ce_id); +} + +static inline int pld_snoc_fw_sim_get_ce_id(struct device *dev, int irq) +{ + if (!dev) + return -ENODEV; + + return icnss_get_ce_id(dev, irq); +} + +static inline int pld_snoc_fw_sim_get_irq(struct device *dev, int ce_id) +{ + if (!dev) + return -ENODEV; + + return icnss_get_irq(dev, ce_id); +} + +static inline int pld_snoc_fw_sim_is_fw_down(struct device *dev) +{ + return icnss_is_fw_down(); +} + +static inline int pld_snoc_fw_sim_idle_shutdown(struct device *dev) +{ + return icnss_idle_shutdown(dev); +} + +static inline int pld_snoc_fw_sim_idle_restart(struct device *dev) +{ + return icnss_idle_restart(dev); +} + +#endif +#endif