diff --git a/Kbuild b/Kbuild index d4da7c5480..1031b3592d 100755 --- a/Kbuild +++ b/Kbuild @@ -847,6 +847,23 @@ ifeq ($(CONFIG_MPC_UT_FRAMEWORK),y) WMA_OBJS += $(WMA_SRC_DIR)/wma_utils_ut.o endif +############## PLD ########## +PLD_DIR := core/pld +PLD_INC_DIR := $(PLD_DIR)/inc +PLD_SRC_DIR := $(PLD_DIR)/src + +PLD_INC := -I$(WLAN_ROOT)/$(PLD_INC_DIR) \ + -I$(WLAN_ROOT)/$(PLD_SRC_DIR) + +PLD_OBJS := $(PLD_SRC_DIR)/pld_common.o + +ifeq ($(CONFIG_PCI), y) +PLD_OBJS += $(PLD_SRC_DIR)/pld_pcie.o +endif +ifeq ($(CONFIG_ICNSS),y) +PLD_OBJS += $(PLD_SRC_DIR)/pld_snoc.o +endif + TARGET_INC := -I$(WLAN_ROOT)/target/inc LINUX_INC := -Iinclude/linux @@ -884,6 +901,8 @@ INCS += $(NLINK_INC) \ $(PTT_INC) \ $(WLAN_LOGGING_INC) +INCS += $(PLD_INC) + ifeq ($(CONFIG_REMOVE_PKT_LOG), 0) INCS += $(PKTLOG_INC) endif @@ -917,6 +936,8 @@ OBJS += $(WLAN_LOGGING_OBJS) OBJS += $(NLINK_OBJS) OBJS += $(PTT_OBJS) +OBJS += $(PLD_OBJS) + ifeq ($(CONFIG_REMOVE_PKT_LOG), 0) OBJS += $(PKTLOG_OBJS) endif diff --git a/core/pld/inc/pld_common.h b/core/pld/inc/pld_common.h new file mode 100644 index 0000000000..9345eaffe7 --- /dev/null +++ b/core/pld/inc/pld_common.h @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __PLD_COMMON_H__ +#define __PLD_COMMON_H__ + +#include +#include +#include + +/** + * enum pld_bus_type - bus type + * @PLD_BUS_TYPE_NONE: invalid bus type, only return in error cases + * @PLD_BUS_TYPE_PCIE: PCIE bus + * @PLD_BUS_TYPE_SNOC: SNOC bus + */ +enum pld_bus_type { + PLD_BUS_TYPE_NONE = -1, + PLD_BUS_TYPE_PCIE = 0, + PLD_BUS_TYPE_SNOC +}; + +#define PLD_MAX_FIRMWARE_SIZE (1 * 1024 * 1024) + +/** + * enum pld_bus_width_type - bus bandwith + * @PLD_BUS_WIDTH_NONE: don't vote for bus bandwidth + * @PLD_BUS_WIDTH_LOW: vote for low bus bandwidth + * @PLD_BUS_WIDTH_MEDIUM: vote for medium bus bandwidth + * @PLD_BUS_WIDTH_HIGH: vote for high bus bandwidth + */ +enum pld_bus_width_type { + PLD_BUS_WIDTH_NONE, + PLD_BUS_WIDTH_LOW, + PLD_BUS_WIDTH_MEDIUM, + PLD_BUS_WIDTH_HIGH +}; + +#define PLD_MAX_FILE_NAME 20 + +/** + * struct pld_fw_file - WLAN FW file names + * @image_file: WLAN FW image file + * @board_data: WLAN FW board data file + * @otp_data: WLAN FW OTP file + * @utf_file: WLAN FW UTF file + * @utf_board_data: WLAN FW UTF board data file + * @epping_file: WLAN FW EPPING mode file + * @evicted_data: WLAN FW evicted file + * + * pld_fw_files is used to store WLAN FW file names + */ +struct pld_fw_files { + char image_file[PLD_MAX_FILE_NAME]; + char board_data[PLD_MAX_FILE_NAME]; + char otp_data[PLD_MAX_FILE_NAME]; + char utf_file[PLD_MAX_FILE_NAME]; + char utf_board_data[PLD_MAX_FILE_NAME]; + char epping_file[PLD_MAX_FILE_NAME]; + char evicted_data[PLD_MAX_FILE_NAME]; +}; + +/** + * struct pld_image_desc_info - FW image description + * @fw_addr: FW image address + * @fw_size: FW image size + * @bdata_addr: FW board data address + * @bdata_size: FW board data size + * + * pld_image_desc_info is used to store FW image description + * information. + */ +struct pld_image_desc_info { + dma_addr_t fw_addr; + u32 fw_size; + dma_addr_t bdata_addr; + u32 bdata_size; +}; + +#define PLD_CODESWAP_MAX_CODESEGS 16 + +/** + * struct pld_codeswap_codeseg_info - code swap segment information + * @codeseg_total_bytes: total bytes of segments + * @num_codesegs: number of code segments + * @codeseg_size: code segment size + * @codeseg_size_log2: log2 of code segment size + * @codeseg_busaddr: array of addresses of each code segment + * + * pld_codeswap_codeseg_info is used to store code swap segment + * information. + */ +struct pld_codeswap_codeseg_info { + u32 codeseg_total_bytes; + u32 num_codesegs; + u32 codeseg_size; + u32 codeseg_size_log2; + void *codeseg_busaddr[PLD_CODESWAP_MAX_CODESEGS]; +}; + +/** + * enum pld_platform_cap_flag - platform capability flag + * @PLD_HAS_EXTERNAL_SWREG: has external regulator + * @PLD_HAS_UART_ACCESS: has UART access + */ +enum pld_platform_cap_flag { + PLD_HAS_EXTERNAL_SWREG = 0x01, + PLD_HAS_UART_ACCESS = 0x02, +}; + +/** + * struct pld_platform_cap - platform capabilities + * @cap_flag: capabilities flag + * + * pld_platform_cap provides platform capabilities which are + * extracted from DTS. + */ +struct pld_platform_cap { + u32 cap_flag; +}; + +/** + * enum pld_driver_status - WLAN driver status + * @PLD_UNINITIALIZED: driver is uninitialized + * @PLD_INITIALIZED: driver is initialized + * @PLD_LOAD_UNLOADL: driver is in load-unload status + */ +enum pld_driver_status { + PLD_UNINITIALIZED, + PLD_INITIALIZED, + PLD_LOAD_UNLOAD +}; + +/** + * struct pld_ce_tgt_pipe_cfg - copy engine target pipe configuration + * @pipe_num: pipe number + * @pipe_dir: pipe direction + * @nentries: number of entries + * @nbytes_max: max number of bytes + * @flags: flags + * @reserved: reserved + * + * pld_ce_tgt_pipe_cfg is used to store copy engine target pipe + * configuration. + */ +struct pld_ce_tgt_pipe_cfg { + u32 pipe_num; + u32 pipe_dir; + u32 nentries; + u32 nbytes_max; + u32 flags; + u32 reserved; +}; + +/** + * struct pld_ce_svc_pipe_cfg - copy engine service pipe configuration + * @service_id: service ID + * @pipe_dir: pipe direction + * @pipe_num: pipe number + * + * pld_ce_svc_pipe_cfg is used to store copy engine service pipe + * configuration. + */ +struct pld_ce_svc_pipe_cfg { + u32 service_id; + u32 pipe_dir; + u32 pipe_num; +}; + +/** + * struct pld_shadow_reg_cfg - shadow register configuration + * @ce_id: copy engine ID + * @reg_offset: register offset + * + * pld_shadow_reg_cfg is used to store shadow register configuration. + */ +struct pld_shadow_reg_cfg { + u16 ce_id; + u16 reg_offset; +}; + +/** + * struct pld_wlan_enable_cfg - WLAN FW configuration + * @num_ce_tgt_cfg: number of CE target configuration + * @ce_tgt_cfg: CE target configuration + * @num_ce_svc_pipe_cfg: number of CE service configuration + * @ce_svc_cfg: CE service configuration + * @num_shadow_reg_cfg: number of shadow register configuration + * @shadow_reg_cfg: shadow register configuration + * + * pld_wlan_enable_cfg stores WLAN FW configurations. It will be + * passed to WLAN FW when WLAN host driver calls wlan_enable. + */ +struct pld_wlan_enable_cfg { + u32 num_ce_tgt_cfg; + struct pld_ce_tgt_pipe_cfg *ce_tgt_cfg; + u32 num_ce_svc_pipe_cfg; + struct pld_ce_svc_pipe_cfg *ce_svc_cfg; + u32 num_shadow_reg_cfg; + struct pld_shadow_reg_cfg *shadow_reg_cfg; +}; + +/** + * enum pld_driver_mode - WLAN host driver mode + * @PLD_MISSION: mission mode + * @PLD_FTM: FTM mode + * @PLD_EPPING: EPPING mode + * @PLD_WALTEST: WAL test mode, FW standalone test mode + * @PLD_OFF: OFF mode + */ +enum pld_driver_mode { + PLD_MISSION, + PLD_FTM, + PLD_EPPING, + PLD_WALTEST, + PLD_OFF +}; + +/** + * struct pld_soc_info - SOC information + * @v_addr: virtual address of preallocated memory + * @p_addr: physical address of preallcoated memory + * @version: version number + * + * pld_soc_info is used to store WLAN SOC information. + */ +struct pld_soc_info { + void __iomem *v_addr; + phys_addr_t p_addr; + u32 version; +}; + +/** + * struct pld_driver_ops - driver callback functions + * @probe: required operation, will be called when device is detected + * @remove: required operation, will be called when device is removed + * @shutdown: optional operation, will be called during SSR + * @reinit: optional operation, will be called during SSR + * @crash_shutdown: optional operation, will be called when a crash is + * detected + * @suspend: required operation, will be called for power management + * is enabled + * @resume: required operation, will be called for power management + * is enabled + * @modem_status: optional operation, will be called when platform driver + * sending modem power status to WLAN FW + */ +struct pld_driver_ops { + int (*probe)(struct device *dev, + enum pld_bus_type bus_type, + void *bdev, void *id); + void (*remove)(struct device *dev, + enum pld_bus_type bus_type); + void (*shutdown)(struct device *dev, + enum pld_bus_type bus_type); + int (*reinit)(struct device *dev, + enum pld_bus_type bus_type, + void *bdev, void *id); + void (*crash_shutdown)(struct device *dev, + enum pld_bus_type bus_type); + int (*suspend)(struct device *dev, + enum pld_bus_type bus_type, + pm_message_t state); + int (*resume)(struct device *dev, + enum pld_bus_type bus_type); + void (*modem_status)(struct device *dev, + enum pld_bus_type bus_type, + int state); +}; + +int pld_init(void); +void pld_deinit(void); + +int pld_register_driver(struct pld_driver_ops *ops); +void pld_unregister_driver(void); + +int pld_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, const char *host_version); +int pld_wlan_disable(struct device *dev, enum pld_driver_mode mode); +int pld_set_fw_debug_mode(struct device *dev, bool enablefwlog); +int pld_get_fw_files_for_target(struct device *dev, + struct pld_fw_files *pfw_files, + u32 target_type, u32 target_version); +int pld_get_fw_image(struct device *dev, + struct pld_image_desc_info *image_desc_info); +void pld_is_pci_link_down(struct device *dev); +int pld_pcie_shadow_control(struct device *dev, bool enable); +int pld_get_codeswap_struct(struct device *dev, + struct pld_codeswap_codeseg_info *swap_seg); +int pld_set_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list, + u16 ch_count); +int pld_get_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list, + u16 *ch_count, u16 buf_len); +int pld_wlan_set_dfs_nol(struct device *dev, void *info, u16 info_len); +int pld_wlan_get_dfs_nol(struct device *dev, void *info, u16 info_len); +int pld_wlan_pm_control(struct device *dev, bool vote); +void *pld_get_virt_ramdump_mem(struct device *dev, unsigned long *size); +void pld_device_crashed(struct device *dev); +void pld_device_self_recovery(struct device *dev); +void pld_intr_notify_q6(struct device *dev); +void pld_request_pm_qos(struct device *dev, u32 qos_val); +void pld_remove_pm_qos(struct device *dev); +int pld_request_bus_bandwidth(struct device *dev, int bandwidth); +int pld_get_platform_cap(struct device *dev, struct pld_platform_cap *cap); +void pld_set_driver_status(struct device *dev, enum pld_driver_status status); +int pld_get_bmi_setup(struct device *dev); +int pld_get_sha_hash(struct device *dev, const u8 *data, + u32 data_len, u8 *hash_idx, u8 *out); +void *pld_get_fw_ptr(struct device *dev); +int pld_auto_suspend(struct device *dev); +int pld_auto_resume(struct device *dev); + +int pld_ce_request_irq(struct device *dev, unsigned int ce_id, + irqreturn_t (*handler)(int, void *), + unsigned long flags, const char *name, void *ctx); +int pld_ce_free_irq(struct device *dev, unsigned int ce_id, void *ctx); +void pld_enable_irq(struct device *dev, unsigned int ce_id); +void pld_disable_irq(struct device *dev, unsigned int ce_id); +int pld_get_soc_info(struct device *dev, struct pld_soc_info *info); +int pld_get_ce_id(struct device *dev, int irq); + +#endif diff --git a/core/pld/src/pld_common.c b/core/pld/src/pld_common.c new file mode 100644 index 0000000000..902c2108cb --- /dev/null +++ b/core/pld/src/pld_common.c @@ -0,0 +1,1117 @@ +/* + * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#define pr_fmt(fmt) "wlan_pld:%s:%d:: " fmt, __func__, __LINE__ + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_CNSS +#include +#endif +#ifdef CONFIG_ICNSS +#include +#endif + +#include "pld_pcie.h" +#include "pld_snoc.h" +#include "pld_common.h" +#include "pld_internal.h" + +#define PLD_PCIE_REGISTERED BIT(0) +#define PLD_SNOC_REGISTERED BIT(1) + +static struct pld_context *pld_ctx; + +/** + * pld_init() - Initialize PLD module + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_init(void) +{ + struct pld_context *pld_context; + + pld_context = kzalloc(sizeof(*pld_context), GFP_KERNEL); + if (!pld_context) + return -ENOMEM; + + spin_lock_init(&pld_context->pld_lock); + + INIT_LIST_HEAD(&pld_context->dev_list); + + pld_ctx = pld_context; + + return 0; +} + +/** + * pld_deinit() - Uninitialize PLD module + * + * Return: void + */ +void pld_deinit(void) +{ + struct dev_node *dev_node; + struct pld_context *pld_context; + unsigned long flags; + + pld_context = pld_ctx; + if (!pld_context) { + pld_ctx = NULL; + return; + } + + spin_lock_irqsave(&pld_context->pld_lock, flags); + while (!list_empty(&pld_context->dev_list)) { + dev_node = list_first_entry(&pld_context->dev_list, + struct dev_node, list); + list_del(&dev_node->list); + kfree(dev_node); + } + spin_unlock_irqrestore(&pld_context->pld_lock, flags); + + kfree(pld_context); + + pld_ctx = NULL; +} + +/** + * pld_get_global_context() - Get global context of PLD + * + * Return: PLD global context + */ +struct pld_context *pld_get_global_context(void) +{ + return pld_ctx; +} + +/** + * pld_get_bus_type() - Bus type of the device + * @dev: device + * + * Return: PLD bus type + */ +enum pld_bus_type pld_get_bus_type(struct device *dev) +{ + struct pld_context *pld_context; + struct dev_node *dev_node; + unsigned long flags; + + pld_context = pld_get_global_context(); + + if (dev == NULL || pld_context == NULL) { + pr_err("Invalid info: dev %p, context %p\n", + dev, pld_context); + return PLD_BUS_TYPE_NONE; + } + + spin_lock_irqsave(&pld_context->pld_lock, flags); + list_for_each_entry(dev_node, &pld_context->dev_list, list) { + if (dev_node->dev == dev) { + spin_unlock_irqrestore(&pld_context->pld_lock, flags); + return dev_node->bus_type; + } + } + spin_unlock_irqrestore(&pld_context->pld_lock, flags); + + return PLD_BUS_TYPE_NONE; +} + +/** + * pld_register_driver() - Register driver to kernel + * @ops: Callback functions that will be registered to kernel + * + * This function should be called when other modules want to + * register platform driver callback functions to kernel. The + * probe() is expected to be called after registration if the + * device is online. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_register_driver(struct pld_driver_ops *ops) +{ + int ret = 0; + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + + if (pld_context == NULL) { + pr_err("global context is NULL\n"); + ret = -ENODEV; + goto out; + } + + if (pld_context->ops) { + pr_err("driver already registered\n"); + ret = -EEXIST; + goto out; + } + + if (!ops || !ops->probe || !ops->remove || + !ops->suspend || !ops->resume) { + pr_err("Required callback functions are missing\n"); + ret = -EINVAL; + goto out; + } + + pld_context->ops = ops; + + if (0 == pld_pcie_register_driver()) + pld_context->pld_driver_state |= PLD_PCIE_REGISTERED; + if (0 == pld_snoc_register_driver()) + pld_context->pld_driver_state |= PLD_SNOC_REGISTERED; + + if (0 == pld_context->pld_driver_state) { + pr_err("All driver falied to register\n"); + ret = -EINVAL; + goto out; + } + +out: + return ret; +} + +/** + * pld_unregister_driver() - Unregister driver to kernel + * + * This function should be called when other modules want to + * unregister callback functions from kernel. The remove() is + * expected to be called after registration. + * + * Return: void + */ +void pld_unregister_driver(void) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + + if (pld_context == NULL) { + pr_err("global context is NULL\n"); + return; + } + + if (pld_context->ops == NULL) { + pr_err("driver not registered\n"); + return; + } + + pld_pcie_unregister_driver(); + pld_snoc_unregister_driver(); + + pld_context->pld_driver_state = 0; + + pld_context->ops = NULL; +} + +/** + * pld_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_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, const char *host_version) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = pld_pcie_wlan_enable(config, mode, host_version); + break; + case PLD_BUS_TYPE_SNOC: + ret = pld_snoc_wlan_enable(config, mode, host_version); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_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_wlan_disable(struct device *dev, enum pld_driver_mode mode) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = pld_pcie_wlan_disable(mode); + break; + case PLD_BUS_TYPE_SNOC: + ret = pld_snoc_wlan_disable(mode); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_set_fw_debug_mode() - Set FW debug mode + * @dev: device + * @enablefwlog: 0 for QXDM, 1 for WMI + * + * Switch Fw debug mode between DIAG logging and WMI logging. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_set_fw_debug_mode(struct device *dev, bool enablefwlog) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = pld_pcie_set_fw_debug_mode(enablefwlog); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_get_fw_files_for_target() - Get FW file names + * @dev: device + * @pfw_files: buffer for FW file names + * @target_type: target type + * @target_version: target version + * + * Return target specific FW file names to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_get_fw_files_for_target(struct device *dev, + struct pld_fw_files *pfw_files, + u32 target_type, u32 target_version) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = pld_pcie_get_fw_files_for_target(pfw_files, + target_type, target_version); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_get_fw_image() - Get FW image descriptor + * @dev: device + * @image_desc_info: buffer for image descriptor + * + * Return FW image descriptor to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_get_fw_image(struct device *dev, + struct pld_image_desc_info *image_desc_info) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = pld_pcie_get_fw_image(image_desc_info); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_is_pci_link_down() - Notification for pci link down event + * @dev: device + * + * Notify platform that pci link is down. + * + * Return: void + */ +void pld_is_pci_link_down(struct device *dev) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + cnss_wlan_pci_link_down(); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_pcie_shadow_control() - Control pci shadow registers + * @dev: device + * @enable: 0 for disable, 1 for enable + * + * This function is for suspend/resume. It can control if we + * use pci shadow registers (for saving config space) or not. + * During suspend we disable it to avoid config space corruption. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pcie_shadow_control(struct device *dev, bool enable) +{ + int ret = 0; + + /* cnss_shadow_control is not supported on BF64.0.3 kernel yet + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = cnss_shadow_control(enable); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + */ + return ret; +} + +/** + * pld_get_codeswap_struct() - Get codeswap structure + * @dev: device + * @swap_seg: buffer to codeswap information + * + * Return codeswap structure information to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_get_codeswap_struct(struct device *dev, + struct pld_codeswap_codeseg_info *swap_seg) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = pld_pcie_get_codeswap_struct(swap_seg); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_set_wlan_unsafe_channel() - Set unsafe channel + * @dev: device + * @unsafe_ch_list: unsafe channel list + * @ch_count: number of channel + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_set_wlan_unsafe_channel(struct device *dev, + u16 *unsafe_ch_list, u16 ch_count) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = cnss_set_wlan_unsafe_channel(unsafe_ch_list, + ch_count); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_get_wlan_unsafe_channel() - Get unsafe channel + * @dev: device + * @unsafe_ch_list: buffer to unsafe channel list + * @ch_count: number of channel + * @buf_len: buffer length + * + * Return WLAN unsafe channel to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_get_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list, + u16 *ch_count, u16 buf_len) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = cnss_get_wlan_unsafe_channel(unsafe_ch_list, + ch_count, buf_len); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_wlan_set_dfs_nol() - Set DFS info + * @dev: device + * @info: DFS info + * @info_len: info length + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_wlan_set_dfs_nol(struct device *dev, void *info, u16 info_len) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = cnss_wlan_set_dfs_nol(info, info_len); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_wlan_get_dfs_nol() - Get DFS info + * @dev: device + * @info: buffer to DFS info + * @info_len: info length + * + * Return DFS info to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_wlan_get_dfs_nol(struct device *dev, void *info, u16 info_len) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = cnss_wlan_get_dfs_nol(info, info_len); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_wlan_pm_control() - WLAN PM control on PCIE + * @dev: device + * @vote: 0 for enable PCIE PC, 1 for disable PCIE PC + * + * This is for PCIE power collaps control during suspend/resume. + * When PCIE power collaps is disabled, WLAN FW can access memory + * through PCIE when system is suspended. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_wlan_pm_control(struct device *dev, bool vote) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = cnss_wlan_pm_control(vote); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_get_virt_ramdump_mem() - Get virtual ramdump memory + * @dev: device + * @size: buffer to virtual memory size + * + * Return: virtual ramdump memory address + */ +void *pld_get_virt_ramdump_mem(struct device *dev, unsigned long *size) +{ + void *mem = NULL; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + mem = cnss_get_virt_ramdump_mem(size); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + pr_err("Invalid device type\n"); + break; + } + + return mem; +} + +/** + * pld_device_crashed() - Notification for device crash event + * @dev: device + * + * Notify subsystem a device crashed event. A subsystem restart + * is expected to happen after calling this function. + * + * Return: void + */ +void pld_device_crashed(struct device *dev) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + cnss_device_crashed(); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_device_self_recovery() - Device self recovery + * @dev: device + * + * Return: void + */ +void pld_device_self_recovery(struct device *dev) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + cnss_device_self_recovery(); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_intr_notify_q6() - Notify Q6 FW interrupts + * @dev: device + * + * Notify Q6 that a FW interrupt is triggered. + * + * Return: void + */ +void pld_intr_notify_q6(struct device *dev) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + cnss_intr_notify_q6(); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_request_pm_qos() - Request system PM + * @dev: device + * @qos_val: request value + * + * It votes for the value of aggregate QoS expectations. + * + * Return: void + */ +void pld_request_pm_qos(struct device *dev, u32 qos_val) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + cnss_request_pm_qos(qos_val); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_remove_pm_qos() - Remove system PM + * @dev: device + * + * Remove the vote request for Qos expectations. + * + * Return: void + */ +void pld_remove_pm_qos(struct device *dev) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + cnss_remove_pm_qos(); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_request_bus_bandwidth() - Request bus bandwidth + * @dev: device + * @bandwidth: bus bandwidth + * + * Votes for HIGH/MEDIUM/LOW bus bandwidth. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_request_bus_bandwidth(struct device *dev, int bandwidth) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = cnss_request_bus_bandwidth(bandwidth); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_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_get_platform_cap(struct device *dev, struct pld_platform_cap *cap) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = pld_pcie_get_platform_cap(cap); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_set_driver_status() - Set driver status + * @dev: device + * @status: driver status + * + * Return: void + */ +void pld_set_driver_status(struct device *dev, enum pld_driver_status status) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + pld_pcie_set_driver_status(status); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_get_bmi_setup() - Get BMI setup + * @dev: device + * + * BMI read/write test should be run if BMI test is enabled. + * + * Return: BMI test setup + */ +int pld_get_bmi_setup(struct device *dev) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = cnss_get_bmi_setup(); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_get_sha_hash() - Get sha hash number + * @dev: device + * @data: input data + * @data_len: data length + * @hash_idx: hash index + * @out: output buffer + * + * Return computed hash to the out buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_get_sha_hash(struct device *dev, const u8 *data, + u32 data_len, u8 *hash_idx, u8 *out) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = cnss_get_sha_hash(data, data_len, + hash_idx, out); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_get_fw_ptr() - Get secure FW memory address + * @dev: device + * + * Return: secure memory address + */ +void *pld_get_fw_ptr(struct device *dev) +{ + void *ptr = NULL; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ptr = cnss_get_fw_ptr(); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + pr_err("Invalid device type\n"); + break; + } + + return ptr; +} + +/** + * pld_auto_suspend() - Auto suspend + * @dev: device + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_auto_suspend(struct device *dev) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = cnss_auto_suspend(); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_auto_resume() - Auto resume + * @dev: device + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_auto_resume(struct device *dev) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + ret = cnss_auto_resume(); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_ce_request_irq() - Register IRQ for CE + * @dev: device + * @ce_id: CE 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_ce_request_irq(struct device *dev, unsigned int ce_id, + irqreturn_t (*handler)(int, void *), + unsigned long flags, const char *name, void *ctx) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_SNOC: + ret = icnss_ce_request_irq(ce_id, handler, flags, name, ctx); + break; + case PLD_BUS_TYPE_PCIE: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_ce_free_irq() - Free IRQ for CE + * @dev: device + * @ce_id: CE number + * @ctx: IRQ context + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_ce_free_irq(struct device *dev, unsigned int ce_id, void *ctx) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_SNOC: + ret = icnss_ce_free_irq(ce_id, ctx); + break; + case PLD_BUS_TYPE_PCIE: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_enable_irq() - Enable IRQ for CE + * @dev: device + * @ce_id: CE number + * + * Return: void + */ +void pld_enable_irq(struct device *dev, unsigned int ce_id) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_SNOC: + icnss_enable_irq(ce_id); + break; + case PLD_BUS_TYPE_PCIE: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_disable_irq() - Disable IRQ for CE + * @dev: device + * @ce_id: CE number + * + * Return: void + */ +void pld_disable_irq(struct device *dev, unsigned int ce_id) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_SNOC: + icnss_disable_irq(ce_id); + break; + case PLD_BUS_TYPE_PCIE: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_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_get_soc_info(struct device *dev, struct pld_soc_info *info) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_SNOC: + ret = pld_snoc_get_soc_info(info); + break; + case PLD_BUS_TYPE_PCIE: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * pld_get_ce_id() - Get CE number for the provided IRQ + * @dev: device + * @irq: IRQ number + * + * Return: CE number + */ +int pld_get_ce_id(struct device *dev, int irq) +{ + int ret = 0; + + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_SNOC: + ret = icnss_get_ce_id(irq); + break; + case PLD_BUS_TYPE_PCIE: + ret = pld_pcie_get_ce_id(irq); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} diff --git a/core/pld/src/pld_internal.h b/core/pld/src/pld_internal.h new file mode 100644 index 0000000000..3619848b6b --- /dev/null +++ b/core/pld/src/pld_internal.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __PLD_COMMON_I_H__ +#define __PLD_COMMON_I_H__ + +struct dev_node { + struct device *dev; + struct list_head list; + enum pld_bus_type bus_type; +}; + +struct pld_context { + struct pld_driver_ops *ops; + spinlock_t pld_lock; + struct list_head dev_list; + uint32_t pld_driver_state; +}; + +struct pld_context *pld_get_global_context(void); + +#endif diff --git a/core/pld/src/pld_pcie.c b/core/pld/src/pld_pcie.c new file mode 100644 index 0000000000..ca7778059b --- /dev/null +++ b/core/pld/src/pld_pcie.c @@ -0,0 +1,524 @@ +/* + * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_CNSS +#include +#endif + +#include "pld_common.h" +#include "pld_internal.h" + +#ifdef CONFIG_PCI + +#ifdef QCA_WIFI_3_0_ADRASTEA +#define CE_COUNT_MAX 12 +#else +#define CE_COUNT_MAX 8 +#endif + +/** + * pld_pcie_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_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct pld_context *pld_context; + unsigned long flags; + struct dev_node *dev_node; + int ret = 0; + + pld_context = pld_get_global_context(); + if (!pld_context) { + ret = -ENODEV; + goto out; + } + + dev_node = kzalloc(sizeof(*dev_node), GFP_KERNEL); + if (dev_node == NULL) { + ret = -ENOMEM; + goto out; + } + dev_node->dev = &pdev->dev; + dev_node->bus_type = PLD_BUS_TYPE_PCIE; + + spin_lock_irqsave(&pld_context->pld_lock, flags); + list_add_tail(&dev_node->list, &pld_context->dev_list); + spin_unlock_irqrestore(&pld_context->pld_lock, flags); + + return pld_context->ops->probe(&pdev->dev, + PLD_BUS_TYPE_PCIE, pdev, (void *)id); + +out: + return ret; +} + + +/** + * pld_pcie_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_remove(struct pci_dev *pdev) +{ + struct pld_context *pld_context; + unsigned long flags; + struct dev_node *dev_node, *tmp; + + pld_context = pld_get_global_context(); + + if (!pld_context) + return; + + spin_lock_irqsave(&pld_context->pld_lock, flags); + list_for_each_entry_safe(dev_node, tmp, &pld_context->dev_list, list) { + if (dev_node->dev == &pdev->dev) { + list_del(&dev_node->list); + kfree(dev_node); + } + } + spin_unlock_irqrestore(&pld_context->pld_lock, flags); + + pld_context->ops->remove(&pdev->dev, PLD_BUS_TYPE_PCIE); +} + +#ifdef CONFIG_CNSS +/** + * pld_pcie_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_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, pdev, (void *)id); + + return -ENODEV; +} + +/** + * pld_pcie_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_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); +} + +/** + * pld_pcie_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_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); +} + +/** + * pld_pcie_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_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, state); +} +#endif + +/** + * pld_pcie_suspend() - Suspend callback function for power management + * @pdev: PCIE device + * @state: power state + * + * This function is to suspend the PCIE device when power management is + * enabled. + * + * Return: void + */ +static int pld_pcie_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + return pld_context->ops->suspend(&pdev->dev, + PLD_BUS_TYPE_PCIE, state); +} + +/** + * pld_pcie_resume() - Resume callback function for power management + * @pdev: PCIE device + * + * This function is to resume the PCIE device when power management is + * enabled. + * + * Return: void + */ +static int pld_pcie_resume(struct pci_dev *pdev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + return pld_context->ops->resume(&pdev->dev, PLD_BUS_TYPE_PCIE); +} + +static struct pci_device_id pld_pcie_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 CONFIG_CNSS +struct cnss_wlan_driver pld_pcie_ops = { + .name = "pld_pcie", + .id_table = pld_pcie_id_table, + .probe = pld_pcie_probe, + .remove = pld_pcie_remove, + .reinit = pld_pcie_reinit, + .shutdown = pld_pcie_shutdown, + .crash_shutdown = pld_pcie_crash_shutdown, + .modem_status = pld_pcie_notify_handler, +#ifdef CONFIG_PM + .suspend = pld_pcie_suspend, + .resume = pld_pcie_resume, +#endif +}; + +/** + * pld_pcie_register_driver() - Register PCIE device callback functions + * + * Return: int + */ +int pld_pcie_register_driver(void) +{ + return cnss_wlan_register_driver(&pld_pcie_ops); +} + +/** + * pld_pcie_unregister_driver() - Unregister PCIE device callback functions + * + * Return: void + */ +void pld_pcie_unregister_driver(void) +{ + cnss_wlan_unregister_driver(&pld_pcie_ops); +} +#else +struct pci_driver pld_pcie_ops = { + .name = "pld_pcie", + .id_table = pld_pcie_id_table, + .probe = pld_pcie_probe, + .remove = pld_pcie_remove, +#ifdef CONFIG_PM + .suspend = pld_pcie_suspend, + .resume = pld_pcie_resume, +#endif +}; + +int pld_pcie_register_driver(void) +{ + return pci_register_driver(&pld_pcie_ops); +} + +void pld_pcie_unregister_driver(void) +{ + pci_unregister_driver(&pld_pcie_ops); +} +#endif + +/** + * pld_pcie_get_ce_id() - Get CE number for the provided IRQ + * @irq: IRQ number + * + * Return: CE number + */ +int pld_pcie_get_ce_id(int irq) +{ + int ce_id = irq - 100; + if (ce_id < CE_COUNT_MAX && ce_id >= 0) + return ce_id; + + return -EINVAL; +} + +#ifdef CONFIG_CNSS +#ifdef QCA_WIFI_3_0_ADRASTEA +/** + * pld_pcie_wlan_enable() - Enable WLAN + * @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_wlan_enable(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; + + 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_wlan_enable(&cfg, cnss_mode, host_version); +} + +/** + * pld_pcie_wlan_disable() - Disable WLAN + * @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_wlan_disable(enum pld_driver_mode mode) +{ + return cnss_wlan_disable(CNSS_OFF); +} + +/** + * pld_pcie_set_fw_debug_mode() - Set FW debug mode + * @mode: 0 for QXDM, 1 for WMI + * + * Switch Fw debug mode between DIAG logging and WMI logging. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pcie_set_fw_debug_mode(bool mode) +{ + return cnss_set_fw_debug_mode(mode); +} +#endif + +/** + * pld_pcie_get_fw_files_for_target() - Get FW file names + * @pfw_files: buffer for FW file names + * @target_type: target type + * @target_version: target version + * + * Return target specific FW file names to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pcie_get_fw_files_for_target(struct pld_fw_files *pfw_files, + u32 target_type, u32 target_version) +{ + int ret = 0; + struct cnss_fw_files cnss_fw_files; + + if (pfw_files == NULL) + return -ENODEV; + + ret = cnss_get_fw_files_for_target(&cnss_fw_files, + target_type, target_version); + if (0 != ret) + return ret; + + memcpy(pfw_files, &cnss_fw_files, sizeof(*pfw_files)); + return 0; +} + +/** + * pld_pcie_get_fw_image() - Get FW image descriptor + * @image_desc_info: buffer for image descriptor + * + * Return FW image descriptor to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pcie_get_fw_image(struct pld_image_desc_info *image_desc_info) +{ + int ret = 0; + struct image_desc_info cnss_image_desc_info; + + if (image_desc_info == NULL) + return -ENODEV; + + ret = cnss_get_fw_image(&cnss_image_desc_info); + if (0 != ret) + return ret; + + memcpy(image_desc_info, &cnss_image_desc_info, + sizeof(*image_desc_info)); + return 0; +} + +/** + * pld_pcie_get_codeswap_struct() - Get codeswap structure + * @swap_seg: buffer to codeswap information + * + * Return codeswap structure information to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pcie_get_codeswap_struct(struct pld_codeswap_codeseg_info *swap_seg) +{ + int ret = 0; + struct codeswap_codeseg_info cnss_swap_seg; + + if (swap_seg == NULL) + return -ENODEV; + + ret = cnss_get_codeswap_struct(&cnss_swap_seg); + if (0 != ret) + return ret; + + memcpy(swap_seg, &cnss_swap_seg, sizeof(*swap_seg)); + return 0; +} + +/** + * pld_pcie_get_platform_cap() - Get platform capabilities + * @cap: buffer to the capabilities + * + * Return capabilities to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_pcie_get_platform_cap(struct pld_platform_cap *cap) +{ + int ret = 0; + struct cnss_platform_cap cnss_cap; + + if (cap == NULL) + return -ENODEV; + + ret = cnss_get_platform_cap(&cnss_cap); + if (0 != ret) + return ret; + + memcpy(cap, &cnss_cap, sizeof(*cap)); + return 0; +} + +/** + * pld_pcie_set_driver_status() - Set driver status + * @status: driver status + * + * Return: void + */ +void pld_pcie_set_driver_status(enum pld_driver_status status) +{ + enum cnss_driver_status cnss_status; + + switch (status) { + case PLD_UNINITIALIZED: + cnss_status = CNSS_UNINITIALIZED; + break; + case PLD_INITIALIZED: + cnss_status = CNSS_INITIALIZED; + break; + default: + cnss_status = CNSS_LOAD_UNLOAD; + break; + } + cnss_set_driver_status(cnss_status); +} +#endif + +#endif diff --git a/core/pld/src/pld_pcie.h b/core/pld/src/pld_pcie.h new file mode 100644 index 0000000000..16d022b2a9 --- /dev/null +++ b/core/pld/src/pld_pcie.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __PLD_PCIE_H__ +#define __PLD_PCIE_H__ + +#include "pld_common.h" + +#ifndef CONFIG_PCI +static inline int pld_pcie_register_driver(void) +{ + return 0; +} + +static inline void pld_pcie_unregister_driver(void) +{ + return; +} + +static inline int pld_pcie_get_ce_id(int irq) +{ + return 0; +} +#else +int pld_pcie_register_driver(void); +void pld_pcie_unregister_driver(void); +int pld_pcie_get_ce_id(int irq); +#endif + +#if (!defined(CONFIG_CNSS)) || (!defined(QCA_WIFI_3_0_ADRASTEA)) +static inline int pld_pcie_wlan_enable(struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, const char *host_version) +{ + return 0; +} +static inline int pld_pcie_wlan_disable(enum pld_driver_mode mode) +{ + return 0; +} +static inline int pld_pcie_set_fw_debug_mode(bool enablefwlog) +{ + return 0; +} +static inline void cnss_intr_notify_q6(void) +{ + return; +} +#else +int pld_pcie_wlan_enable(struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, const char *host_version); +int pld_pcie_wlan_disable(enum pld_driver_mode mode); +int pld_pcie_set_fw_debug_mode(bool enablefwlog); +#endif + +#if (!defined(CONFIG_CNSS)) || (!defined(CONFIG_CNSS_SECURE_FW)) +static inline int cnss_get_sha_hash(const u8 *data, + u32 data_len, u8 *hash_idx, u8 *out) +{ + return 0; +} +static inline void *cnss_get_fw_ptr(void) +{ + return NULL; +} +#endif + +#ifndef CONFIG_CNSS +static inline int +pld_pcie_get_fw_files_for_target(struct pld_fw_files *pfw_files, + u32 target_type, u32 target_version) +{ + return 0; +} +static inline int +pld_pcie_get_fw_image(struct pld_image_desc_info *image_desc_info) +{ + return 0; +} +static inline void cnss_wlan_pci_link_down(void) +{ + return; +} +static inline int cnss_pcie_shadow_control(bool enable) +{ + return 0; +} +static inline int +pld_pcie_get_codeswap_struct(struct pld_codeswap_codeseg_info *swap_seg) +{ + return 0; +} +static inline int +cnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count) +{ + return 0; +} +static inline int cnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list, + u16 *ch_count, u16 buf_len) +{ + return 0; +} +static inline int cnss_wlan_set_dfs_nol(void *info, u16 info_len) +{ + return 0; +} +static inline int cnss_wlan_get_dfs_nol(void *info, u16 info_len) +{ + return 0; +} +static inline int cnss_wlan_pm_control(bool vote) +{ + return 0; +} +static inline void *cnss_get_virt_ramdump_mem(unsigned long *size) +{ + return NULL; +} +static inline void cnss_device_crashed(void) +{ + return; +} +static inline void cnss_device_self_recovery(void) +{ + return; +} +static inline void cnss_request_pm_qos(u32 qos_val) +{ + return; +} +static inline void cnss_remove_pm_qos(void) +{ + return; +} +static inline int cnss_request_bus_bandwidth(int bandwidth) +{ + return 0; +} +static inline int pld_pcie_get_platform_cap(struct pld_platform_cap *cap) +{ + return 0; +} +static inline void pld_pcie_set_driver_status(enum pld_driver_status status) +{ + return; +} +static inline int cnss_get_bmi_setup(void) +{ + return 0; +} +static inline int cnss_auto_suspend(void) +{ + return 0; +} +static inline int cnss_auto_resume(void) +{ + return 0; +} +#else +int pld_pcie_get_fw_files_for_target(struct pld_fw_files *pfw_files, + u32 target_type, u32 target_version); +int pld_pcie_get_fw_image(struct pld_image_desc_info *image_desc_info); +int pld_pcie_get_codeswap_struct(struct pld_codeswap_codeseg_info *swap_seg); +int pld_pcie_get_platform_cap(struct pld_platform_cap *cap); +void pld_pcie_set_driver_status(enum pld_driver_status status); +#endif + +#endif diff --git a/core/pld/src/pld_snoc.c b/core/pld/src/pld_snoc.c new file mode 100644 index 0000000000..40cee705ea --- /dev/null +++ b/core/pld/src/pld_snoc.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#include +#include +#include + +#ifdef CONFIG_ICNSS +#include +#endif + +#include "pld_common.h" +#include "pld_internal.h" + +#ifdef CONFIG_ICNSS +/** + * pld_snoc_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_probe(struct device *dev) +{ + struct pld_context *pld_context; + unsigned long flags; + struct dev_node *dev_node; + int ret = 0; + + pld_context = pld_get_global_context(); + if (!pld_context) { + ret = -ENODEV; + goto out; + } + + dev_node = kzalloc(sizeof(*dev_node), GFP_KERNEL); + if (dev_node == NULL) { + ret = -ENOMEM; + goto out; + } + dev_node->dev = dev; + dev_node->bus_type = PLD_BUS_TYPE_SNOC; + + spin_lock_irqsave(&pld_context->pld_lock, flags); + list_add_tail(&dev_node->list, &pld_context->dev_list); + spin_unlock_irqrestore(&pld_context->pld_lock, flags); + + return pld_context->ops->probe(dev, PLD_BUS_TYPE_SNOC, + NULL, NULL); + +out: + return ret; +} + +/** + * pld_snoc_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_remove(struct device *dev) +{ + struct pld_context *pld_context; + unsigned long flags; + struct dev_node *dev_node, *tmp; + + pld_context = pld_get_global_context(); + + if (!pld_context) + return; + + spin_lock_irqsave(&pld_context->pld_lock, flags); + list_for_each_entry_safe(dev_node, tmp, &pld_context->dev_list, list) { + if (dev_node->dev == dev) { + list_del(&dev_node->list); + kfree(dev_node); + } + } + spin_unlock_irqrestore(&pld_context->pld_lock, flags); + + pld_context->ops->remove(dev, PLD_BUS_TYPE_SNOC); +} + +/** + * pld_snoc_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_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, + NULL, NULL); + + return -ENODEV; +} + +/** + * pld_snoc_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_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); +} + +/** + * pld_snoc_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_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); +} + +/** + * pld_snoc_suspend() - Suspend callback function for power management + * @dev: device + * @state: power state + * + * This function is to suspend the platform device when power management + * is enabled. + * + * Return: void + */ +static int pld_snoc_suspend(struct device *dev, pm_message_t state) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + return pld_context->ops->suspend(dev, PLD_BUS_TYPE_SNOC, state); +} + +/** + * pld_snoc_resume() - 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_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); +} + +struct icnss_driver_ops pld_snoc_ops = { + .name = "pld_snoc", + .probe = pld_snoc_probe, + .remove = pld_snoc_remove, + .shutdown = pld_snoc_shutdown, + .reinit = pld_snoc_reinit, + .crash_shutdown = pld_snoc_crash_shutdown, + .suspend = pld_snoc_suspend, + .resume = pld_snoc_resume, +}; + +/** + * pld_snoc_register_driver() - Register platform device callback functions + * + * Return: int + */ +int pld_snoc_register_driver(void) +{ + return icnss_register_driver(&pld_snoc_ops); +} + +/** + * pld_snoc_unregister_driver() - Unregister platform device callback functions + * + * Return: void + */ +void pld_snoc_unregister_driver(void) +{ + icnss_unregister_driver(&pld_snoc_ops); +} + +/** + * pld_snoc_wlan_enable() - Enable WLAN + * @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_wlan_enable(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; + + 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(&cfg, icnss_mode, host_version); +} + +/** + * pld_snoc_wlan_disable() - Disable WLAN + * @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_wlan_disable(enum pld_driver_mode mode) +{ + return icnss_wlan_disable(ICNSS_OFF); +} + +/** + * pld_snoc_get_soc_info() - Get SOC information + * @info: buffer to SOC information + * + * Return SOC info to the buffer. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_snoc_get_soc_info(struct pld_soc_info *info) +{ + int ret = 0; + struct icnss_soc_info icnss_info; + + if (info == NULL) + return -ENODEV; + + ret = icnss_get_soc_info(&icnss_info); + if (0 != ret) + return ret; + + memcpy(info, &icnss_info, sizeof(*info)); + return 0; +} + +#endif diff --git a/core/pld/src/pld_snoc.h b/core/pld/src/pld_snoc.h new file mode 100644 index 0000000000..321710680c --- /dev/null +++ b/core/pld/src/pld_snoc.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __PLD_SNOC_H__ +#define __PLD_SNOC_H__ + +#include "pld_common.h" + +#ifndef CONFIG_ICNSS +static inline int pld_snoc_register_driver(void) +{ + return 0; +} + +static inline void pld_snoc_unregister_driver(void) +{ + return; +} +static inline int pld_snoc_wlan_enable(struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, const char *host_version) +{ + return 0; +} +static inline int pld_snoc_wlan_disable(enum pld_driver_mode mode) +{ + return 0; +} +static inline int icnss_ce_request_irq(unsigned int ce_id, + irqreturn_t (*handler)(int, void *), + unsigned long flags, const char *name, void *ctx) +{ + return 0; +} +static inline int icnss_ce_free_irq(unsigned int ce_id, void *ctx) +{ + return 0; +} +static inline void icnss_enable_irq(unsigned int ce_id) +{ + return; +} +static inline void icnss_disable_irq(unsigned int ce_id) +{ + return; +} +static inline int icnss_get_soc_info(struct pld_soc_info *info) +{ + return 0; +} +static inline int icnss_get_ce_id(int irq) +{ + return 0; +} +static inline int pld_snoc_get_soc_info(struct pld_soc_info *info) +{ + return 0; +} +#else +int pld_snoc_register_driver(void); +void pld_snoc_unregister_driver(void); +int pld_snoc_wlan_enable(struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, const char *host_version); +int pld_snoc_wlan_disable(enum pld_driver_mode mode); +int pld_snoc_get_soc_info(struct pld_soc_info *info); +#endif + +#endif