From d9f7a36529c5b7bc928f41f5211efa48fc495ce1 Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Fri, 22 Jan 2016 14:27:12 -0800 Subject: qcacld-3.0: Add PLD layer PLD stands for platform driver. It is a interface between CLD and CNSS/ICNSS. It hides the CNSS/ICNSS APIs from CLD and provides a set of common APIs. Other modules should include pld_common.h if they want to call PLD APIs. CRs-Fixed: 979275 Change-Id: I3571fc70f502dc367c65f13b412cd5d37ee41d3c --- Kbuild | 21 + core/pld/inc/pld_common.h | 346 ++++++++++++++ core/pld/src/pld_common.c | 1117 +++++++++++++++++++++++++++++++++++++++++++ core/pld/src/pld_internal.h | 46 ++ core/pld/src/pld_pcie.c | 524 ++++++++++++++++++++ core/pld/src/pld_pcie.h | 191 ++++++++ core/pld/src/pld_snoc.c | 317 ++++++++++++ core/pld/src/pld_snoc.h | 91 ++++ 8 files changed, 2653 insertions(+) create mode 100644 core/pld/inc/pld_common.h create mode 100644 core/pld/src/pld_common.c create mode 100644 core/pld/src/pld_internal.h create mode 100644 core/pld/src/pld_pcie.c create mode 100644 core/pld/src/pld_pcie.h create mode 100644 core/pld/src/pld_snoc.c create mode 100644 core/pld/src/pld_snoc.h diff --git a/Kbuild b/Kbuild index d4da7c54807a..1031b3592d1e 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 000000000000..9345eaffe7e7 --- /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 000000000000..902c2108cb86 --- /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 000000000000..3619848b6bbc --- /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 000000000000..ca7778059b55 --- /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 000000000000..16d022b2a9ff --- /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 000000000000..40cee705ea9d --- /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 000000000000..321710680cf2 --- /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 -- cgit v1.2.3 From dcc21ba7f6832710388bdf41c790683a69242c8b Mon Sep 17 00:00:00 2001 From: Manikandan Mohan Date: Tue, 15 Mar 2016 14:31:56 -0700 Subject: qcacld-3.0: get tsf from fw qcacld-2.0 to qcacld-3.0 propagation Get tsf from fw. Provide ioctl interface cap_tsf/get_tsf. Driver issue wmi cmd to fw to realize capture/get. It can be used in station and softap mode. For sta, getting tsf from connected ap. For softap, it will generate tsf by- self Change-Id: I00d30882bce2f49ee3de3fa189e094c04c0d9943 CRs-Fixed: 817527 --- Kbuild | 8 ++ Kconfig | 4 + core/hdd/inc/qc_sap_ioctl.h | 49 +++++---- core/hdd/inc/wlan_hdd_main.h | 9 ++ core/hdd/inc/wlan_hdd_tsf.h | 86 +++++++++++++++ core/hdd/src/wlan_hdd_hostapd.c | 75 +++++++++++++ core/hdd/src/wlan_hdd_main.c | 3 +- core/hdd/src/wlan_hdd_tsf.c | 227 ++++++++++++++++++++++++++++++++++++++++ core/hdd/src/wlan_hdd_wext.c | 84 ++++++++++++++- core/mac/inc/sir_api.h | 15 +++ core/mac/inc/wni_api.h | 1 + core/sme/inc/sme_api.h | 2 + core/sme/inc/sme_internal.h | 2 + core/sme/src/common/sme_api.c | 31 ++++++ core/wma/inc/wma_api.h | 2 + core/wma/inc/wma_internal.h | 4 + core/wma/src/wma_features.c | 171 ++++++++++++++++++++++++++++++ core/wma/src/wma_main.c | 16 +++ 18 files changed, 763 insertions(+), 26 deletions(-) create mode 100644 core/hdd/inc/wlan_hdd_tsf.h create mode 100644 core/hdd/src/wlan_hdd_tsf.c diff --git a/Kbuild b/Kbuild index 1031b3592d1e..11eed090633c 100755 --- a/Kbuild +++ b/Kbuild @@ -377,6 +377,10 @@ ifeq ($(CONFIG_QCOM_TDLS),y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tdls.o endif +ifeq ($(CONFIG_WLAN_SYNC_TSF),y) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tsf.o +endif + ifeq ($(CONFIG_MPC_UT_FRAMEWORK),y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_conc_ut.o endif @@ -1360,6 +1364,10 @@ ifeq ($(CONFIG_LINUX_QCMBR),y) CDEFINES += -DLINUX_QCMBR endif +# Enable featue sync tsf between multi devices +ifeq ($(CONFIG_WLAN_SYNC_TSF), y) +CDEFINES += -DWLAN_FEATURE_TSF +endif # Enable full rx re-order offload for adrastea ifeq (y, $(filter y, $(CONFIG_CNSS_ADRASTEA) $(CONFIG_ICNSS))) diff --git a/Kconfig b/Kconfig index 7155ea2a2b4d..39b64ed625c3 100644 --- a/Kconfig +++ b/Kconfig @@ -107,6 +107,10 @@ config WLAN_FEATURE_RX_WAKELOCK bool "Enable RX wake lock feature" default n +config WLAN_SYNC_TSF + bool "Enable QCOM sync multi devices tsf feature" + default n + config FEATURE_LFR_SUBNET_DETECTION bool "Enable LFR Subnet Change Detection" default n diff --git a/core/hdd/inc/qc_sap_ioctl.h b/core/hdd/inc/qc_sap_ioctl.h index 5a1bfbef9f48..cede160e85e8 100644 --- a/core/hdd/inc/qc_sap_ioctl.h +++ b/core/hdd/inc/qc_sap_ioctl.h @@ -131,42 +131,43 @@ typedef struct { * (regardless of the incorrect comment in wireless.h!) */ -#define QCSAP_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0) -#define QCSAP_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+1) +#define QCSAP_IOCTL_SETPARAM (SIOCIWFIRSTPRIV + 0) +#define QCSAP_IOCTL_GETPARAM (SIOCIWFIRSTPRIV + 1) /* (SIOCIWFIRSTPRIV+2) is unused */ -/* (SIOCIWFIRSTPRIV+3) is unused */ -#define QCSAP_IOCTL_GET_STAWPAIE (SIOCIWFIRSTPRIV+4) -#define QCSAP_IOCTL_SETWPAIE (SIOCIWFIRSTPRIV+5) -#define QCSAP_IOCTL_STOPBSS (SIOCIWFIRSTPRIV+6) -#define QCSAP_IOCTL_VERSION (SIOCIWFIRSTPRIV+7) -#define QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES (SIOCIWFIRSTPRIV+8) -#define QCSAP_IOCTL_GET_CHANNEL (SIOCIWFIRSTPRIV+9) -#define QCSAP_IOCTL_ASSOC_STA_MACADDR (SIOCIWFIRSTPRIV+10) -#define QCSAP_IOCTL_DISASSOC_STA (SIOCIWFIRSTPRIV+11) +#define QCSAP_IOCTL_SET_NONE_GET_THREE (SIOCIWFIRSTPRIV + 3) +#define WE_GET_TSF 1 +#define QCSAP_IOCTL_GET_STAWPAIE (SIOCIWFIRSTPRIV + 4) +#define QCSAP_IOCTL_SETWPAIE (SIOCIWFIRSTPRIV + 5) +#define QCSAP_IOCTL_STOPBSS (SIOCIWFIRSTPRIV + 6) +#define QCSAP_IOCTL_VERSION (SIOCIWFIRSTPRIV + 7) +#define QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES (SIOCIWFIRSTPRIV + 8) +#define QCSAP_IOCTL_GET_CHANNEL (SIOCIWFIRSTPRIV + 9) +#define QCSAP_IOCTL_ASSOC_STA_MACADDR (SIOCIWFIRSTPRIV + 10) +#define QCSAP_IOCTL_DISASSOC_STA (SIOCIWFIRSTPRIV + 11) /* (SIOCIWFIRSTPRIV+12) is unused */ /* Private ioctls and their sub-ioctls */ #define QCSAP_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 13) #define QCSAP_GET_STATS 1 #define QCSAP_LIST_FW_PROFILE 2 -#define QCSAP_IOCTL_CLR_STATS (SIOCIWFIRSTPRIV+14) +#define QCSAP_IOCTL_CLR_STATS (SIOCIWFIRSTPRIV + 14) -#define QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV+15) +#define QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 15) #define WE_SET_WLAN_DBG 1 #define WE_SET_DP_TRACE 2 #define WE_SET_SAP_CHANNELS 3 -#define QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV+16) +#define QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 16) #define WE_UNIT_TEST_CMD 7 -#define QCSAP_IOCTL_SET_CHANNEL_RANGE (SIOCIWFIRSTPRIV+17) +#define QCSAP_IOCTL_SET_CHANNEL_RANGE (SIOCIWFIRSTPRIV + 17) #define WE_P2P_NOA_CMD 2 -#define QCSAP_IOCTL_MODIFY_ACL (SIOCIWFIRSTPRIV+18) -#define QCSAP_IOCTL_GET_CHANNEL_LIST (SIOCIWFIRSTPRIV+19) -#define QCSAP_IOCTL_SET_TX_POWER (SIOCIWFIRSTPRIV+20) -#define QCSAP_IOCTL_GET_STA_INFO (SIOCIWFIRSTPRIV+21) -#define QCSAP_IOCTL_SET_MAX_TX_POWER (SIOCIWFIRSTPRIV+22) -#define QCSAP_IOCTL_GET_INI_CFG (SIOCIWFIRSTPRIV+25) -#define QCSAP_IOCTL_SET_INI_CFG (SIOCIWFIRSTPRIV+26) +#define QCSAP_IOCTL_MODIFY_ACL (SIOCIWFIRSTPRIV + 18) +#define QCSAP_IOCTL_GET_CHANNEL_LIST (SIOCIWFIRSTPRIV + 19) +#define QCSAP_IOCTL_SET_TX_POWER (SIOCIWFIRSTPRIV + 20) +#define QCSAP_IOCTL_GET_STA_INFO (SIOCIWFIRSTPRIV + 21) +#define QCSAP_IOCTL_SET_MAX_TX_POWER (SIOCIWFIRSTPRIV + 22) +#define QCSAP_IOCTL_GET_INI_CFG (SIOCIWFIRSTPRIV + 25) +#define QCSAP_IOCTL_SET_INI_CFG (SIOCIWFIRSTPRIV + 26) #define QCSAP_IOCTL_SET_TWO_INT_GET_NONE (SIOCIWFIRSTPRIV + 28) #ifdef DEBUG #define QCSAP_IOCTL_SET_FW_CRASH_INJECT 1 @@ -241,7 +242,9 @@ enum { QCASAP_CLEAR_STATS, QCASAP_SET_RADAR_DBG, QCSAP_GET_FW_PROFILE_DATA, - QCSAP_START_FW_PROFILING + QCSAP_START_FW_PROFILING, + QCSAP_CAP_TSF, + QCSAP_GET_TSF, }; int iw_softap_get_channel_list(struct net_device *dev, diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 39fe7e1a7d97..ab3873a552de 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -57,6 +57,7 @@ #ifdef FEATURE_WLAN_TDLS #include "wlan_hdd_tdls.h" #endif +#include "wlan_hdd_tsf.h" #include "wlan_hdd_cfg80211.h" #include #ifdef WLAN_FEATURE_MBSSID @@ -940,6 +941,14 @@ struct hdd_adapter_s { hdd_ap_ctx_t ap; } sessionCtx; +#ifdef WLAN_FEATURE_TSF + /* tsf value received from firmware */ + uint32_t tsf_low; + uint32_t tsf_high; + /* TSF capture state */ + enum hdd_tsf_capture_state tsf_state; +#endif + hdd_cfg80211_state_t cfg80211State; #ifdef WLAN_FEATURE_PACKET_FILTERING diff --git a/core/hdd/inc/wlan_hdd_tsf.h b/core/hdd/inc/wlan_hdd_tsf.h new file mode 100644 index 000000000000..f251327d7f06 --- /dev/null +++ b/core/hdd/inc/wlan_hdd_tsf.h @@ -0,0 +1,86 @@ +/* + * 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. + */ + +#if !defined WLAN_HDD_TSF_H +#define WLAN_HDD_TSF_H + +/** + * enum hdd_tsf_get_state - status of get tsf action + * @TSF_RETURN: get tsf + * @TSF_STA_NOT_CONNECTED_NO_TSF: sta not connected to ap + * @TSF_NOT_RETURNED_BY_FW: fw not returned tsf + * @TSF_CURRENT_IN_CAP_STATE: driver in capture state + * @TSF_CAPTURE_FAIL: capture fail + * @TSF_GET_FAIL: get fail + * @TSF_RESET_GPIO_FAIL: GPIO reset fail + * @TSF_SAP_NOT_STARTED_NO_TSF SAP not started + */ +enum hdd_tsf_get_state { + TSF_RETURN = 0, + TSF_STA_NOT_CONNECTED_NO_TSF, + TSF_NOT_RETURNED_BY_FW, + TSF_CURRENT_IN_CAP_STATE, + TSF_CAPTURE_FAIL, + TSF_GET_FAIL, + TSF_RESET_GPIO_FAIL, + TSF_SAP_NOT_STARTED_NO_TSF +}; + +/** + * enum hdd_tsf_capture_state - status of capture + * @TSF_IDLE: idle + * @TSF_CAP_STATE: current is in capture state + */ +enum hdd_tsf_capture_state { + TSF_IDLE = 0, + TSF_CAP_STATE +}; + +#ifdef WLAN_FEATURE_TSF +void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx); +int hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len); +int hdd_indicate_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len); +#else +static inline void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx) +{ + return; +} + +static inline int hdd_indicate_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, + int len) +{ + return -ENOTSUPP; +} + +static inline int +hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len) +{ + return -ENOTSUPP; +} +#endif + +#endif diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 3e5e6406c430..597d51278731 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -75,6 +75,7 @@ #include "qdf_trace.h" #include "wlan_hdd_cfg.h" #include "cds_concurrency.h" +#include "wlan_hdd_tsf.h" #include "wlan_hdd_green_ap.h" #define IS_UP(_dev) \ @@ -3011,6 +3012,66 @@ static __iw_softap_setparam(struct net_device *dev, return ret; } +/** + * __iw_softap_get_three() - return three value to upper layer. + * @dev: pointer of net_device of this wireless card + * @info: meta data about Request sent + * @wrqu: include request info + * @extra: buf used for in/out + * + * Return: execute result + */ +static int __iw_softap_get_three(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + uint32_t *value = (uint32_t *)extra; + uint32_t sub_cmd = value[0]; + int ret = 0; /* success */ + struct hdd_context_s *hdd_ctx; + struct hdd_adapter_s *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret != 0) + return ret; + + switch (sub_cmd) { + case QCSAP_GET_TSF: + ret = hdd_indicate_tsf(adapter, value, 3); + break; + default: + hdd_err(FL("Invalid getparam command %d"), sub_cmd); + ret = -EINVAL; + break; + } + return ret; +} + + +/** + * iw_softap_get_three() - return three value to upper layer. + * + * @dev: pointer of net_device of this wireless card + * @info: meta data about Request sent + * @wrqu: include request info + * @extra: buf used for in/Output + * + * Return: execute result + */ +static int iw_softap_get_three(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + cds_ssr_protect(__func__); + ret = __iw_softap_get_three(dev, info, wrqu, extra); + cds_ssr_unprotect(__func__); + + return ret; +} + int static iw_softap_setparam(struct net_device *dev, struct iw_request_info *info, @@ -3211,6 +3272,9 @@ static __iw_softap_getparam(struct net_device *dev, VDEV_CMD); break; } + case QCSAP_CAP_TSF: + ret = hdd_capture_tsf(pHostapdAdapter, (uint32_t *)value, 1); + break; case QCASAP_GET_TEMP_CMD: { hddLog(LOG1, "QCASAP_GET_TEMP_CMD"); @@ -5821,6 +5885,15 @@ static const struct iw_priv_args hostapd_private_args[] = { }, { QCASAP_NSS_CMD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_nss" + }, { + QCSAP_CAP_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "cap_tsf" + }, { + QCSAP_IOCTL_SET_NONE_GET_THREE, 0, IW_PRIV_TYPE_INT | + IW_PRIV_SIZE_FIXED | 3, "" + }, { + QCSAP_GET_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + "get_tsf" }, { QCASAP_GET_TEMP_CMD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_temp" @@ -5997,6 +6070,8 @@ static const iw_handler hostapd_private[] = { [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, /* get priv ioctl */ [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, + [QCSAP_IOCTL_SET_NONE_GET_THREE - SIOCIWFIRSTPRIV] = + iw_softap_get_three, /* get station genIE */ [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie, diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index acf6f9de0335..730ee4e82a6b 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -101,6 +101,7 @@ #include "hif.h" #include "wma.h" #include "cds_concurrency.h" +#include "wlan_hdd_tsf.h" #include "wlan_hdd_green_ap.h" #include "platform_icnss.h" #include "bmi.h" @@ -5963,7 +5964,7 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) hdd_rssi_threshold_breached); hdd_cfg80211_link_layer_stats_init(hdd_ctx); - + wlan_hdd_tsf_init(hdd_ctx); wlan_hdd_send_all_scan_intf_info(hdd_ctx); wlan_hdd_send_version_pkg(hdd_ctx->target_fw_version, hdd_ctx->target_hw_version, diff --git a/core/hdd/src/wlan_hdd_tsf.c b/core/hdd/src/wlan_hdd_tsf.c new file mode 100644 index 000000000000..2563a94bddbd --- /dev/null +++ b/core/hdd/src/wlan_hdd_tsf.c @@ -0,0 +1,227 @@ +/* + * 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. + */ + +/** + * wlan_hdd_tsf.c - WLAN Host Device Driver tsf related implementation + */ + +#include "wlan_hdd_main.h" +#include "wma_api.h" + +/** + * hdd_capture_tsf() - capture tsf + * @adapter: pointer to adapter + * @buf: pointer to uplayer buf + * @len : the length of buf + * + * This function returns tsf value to uplayer. + * + * Return: 0 for success or non-zero negative failure code + */ +int hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len) +{ + int ret = 0; + hdd_station_ctx_t *hdd_sta_ctx; + + if (adapter == NULL || buf == NULL) { + hdd_err(FL("invalid pointer")); + return -EINVAL; + } + if (len != 1) + return -EINVAL; + + /* Reset TSF value for new capture */ + adapter->tsf_high = 0; + adapter->tsf_low = 0; + + if (adapter->device_mode == QDF_STA_MODE || + adapter->device_mode == QDF_P2P_CLIENT_MODE) { + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (hdd_sta_ctx->conn_info.connState != + eConnectionState_Associated) { + + hdd_err(FL("failed to cap tsf, not connect with ap")); + buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF; + return ret; + } + } + if ((adapter->device_mode == QDF_SAP_MODE || + adapter->device_mode == QDF_P2P_GO_MODE) && + !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) { + hdd_err(FL("Soft AP / P2p GO not beaconing")); + buf[0] = TSF_SAP_NOT_STARTED_NO_TSF; + return ret; + } + if (adapter->tsf_state == TSF_CAP_STATE) { + hdd_err(FL("current in capture state, pls reset")); + buf[0] = TSF_CURRENT_IN_CAP_STATE; + } else { + hdd_info(FL("Send TSF capture to FW")); + buf[0] = TSF_RETURN; + adapter->tsf_state = TSF_CAP_STATE; + ret = wma_cli_set_command((int)adapter->sessionId, + (int)GEN_PARAM_CAPTURE_TSF, + adapter->sessionId, + GEN_CMD); + + if (ret != QDF_STATUS_SUCCESS) { + hdd_err(FL("capture fail")); + buf[0] = TSF_CAPTURE_FAIL; + adapter->tsf_state = TSF_IDLE; + } + } + return ret; +} + +/** + * hdd_indicate_tsf() - return tsf to uplayer + * @adapter: pointer to adapter + * @buf: pointer to uplayer buf + * @len : the length of buf + * + * This function returns tsf value to upper layer. + * + * Return: 0 for success or non-zero negative failure code + */ +int hdd_indicate_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len) +{ + int ret = 0; + hdd_station_ctx_t *hdd_sta_ctx; + + if (adapter == NULL || buf == NULL) { + hdd_err(FL("invalid pointer")); + return -EINVAL; + } + + if (len != 3) + return -EINVAL; + + buf[1] = 0; + buf[2] = 0; + if (adapter->device_mode == QDF_STA_MODE || + adapter->device_mode == QDF_P2P_CLIENT_MODE) { + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (hdd_sta_ctx->conn_info.connState != + eConnectionState_Associated) { + + hdd_info(FL("fail to get tsf, sta in disconnected")); + buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF; + return ret; + } + } + if ((adapter->device_mode == QDF_SAP_MODE || + adapter->device_mode == QDF_P2P_GO_MODE) && + !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) { + hdd_err(FL("Soft AP / P2p GO not beaconing")); + buf[0] = TSF_SAP_NOT_STARTED_NO_TSF; + return ret; + } + if (adapter->tsf_high == 0 && adapter->tsf_low == 0) { + hdd_info(FL("TSF value not received")); + buf[0] = TSF_NOT_RETURNED_BY_FW; + } else { + buf[0] = TSF_RETURN; + buf[1] = adapter->tsf_low; + buf[2] = adapter->tsf_high; + adapter->tsf_state = TSF_IDLE; + + ret = wma_cli_set_command((int)adapter->sessionId, + (int)GEN_PARAM_RESET_TSF_GPIO, + adapter->sessionId, + GEN_CMD); + + if (0 != ret) { + hdd_err(FL("tsf get fail ")); + buf[0] = TSF_RESET_GPIO_FAIL; + } + hdd_info(FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"), + buf[0], buf[1], buf[2]); + } + return ret; +} + +/** + * hdd_get_tsf_cb() - handle tsf callback + * @pcb_cxt: pointer to the hdd_contex + * @ptsf: pointer to struct stsf + * + * This function handle the event that reported by firmware at first. + * The event contains the vdev_id, current tsf value of this vdev, + * tsf value is 64bits, discripted in two varaible tsf_low and tsf_high. + * These two values each is uint32. + * + * Return: 0 for success or non-zero negative failure code + */ +static int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf) +{ + struct hdd_context_s *hddctx; + struct hdd_adapter_s *adapter; + int status; + + if (pcb_cxt == NULL || ptsf == NULL) { + hdd_err(FL("HDD context is not valid")); + return -EINVAL; + } + + hddctx = (struct hdd_context_s *)pcb_cxt; + status = wlan_hdd_validate_context(hddctx); + if (0 != status) { + hdd_err(FL("hdd context is not valid")); + return -EINVAL; + } + + adapter = hdd_get_adapter_by_vdev(hddctx, ptsf->vdev_id); + + if (NULL == adapter) { + hdd_err(FL("failed to find adapter")); + return -EINVAL; + } + + hdd_info(FL("tsf cb handle event, device_mode is %d"), + adapter->device_mode); + + adapter->tsf_low = ptsf->tsf_low; + adapter->tsf_high = ptsf->tsf_high; + + hdd_info(FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"), + ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high); + return 0; +} + +/** + * wlan_hdd_tsf_init() - set callback to handle tsf value. + * @hdd_ctx: pointer to the struct hdd_context_s + * + * This function set the callback to sme module, the callback will be + * called when a tsf event is reported by firmware + * + * Return: none + */ +void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx) +{ + sme_set_tsfcb(hdd_ctx->hHal, hdd_get_tsf_cb, hdd_ctx); +} diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index f8f4137c4e6c..b88b01bf11ed 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -80,6 +80,7 @@ #include "sme_power_save_api.h" #include "cds_concurrency.h" #include "wlan_hdd_conc_ut.h" +#include "wlan_hdd_tsf.h" #include "wlan_hdd_ocb.h" #include "wlan_hdd_napi.h" #include "cdp_txrx_flow_ctrl_legacy.h" @@ -273,6 +274,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { #define WE_GET_GTX_MINTPC 53 #define WE_GET_GTX_BWMASK 54 #define WE_GET_TEMPERATURE 56 +#define WE_CAP_TSF 58 /* Private ioctls and their sub-ioctls */ #define WLAN_PRIV_SET_INT_GET_INT (SIOCIWFIRSTPRIV + 2) @@ -383,7 +385,8 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { /* (SIOCIWFIRSTPRIV + 10) is currently unused */ /* (SIOCIWFIRSTPRIV + 12) is currently unused */ /* (SIOCIWFIRSTPRIV + 14) is currently unused */ -/* (SIOCIWFIRSTPRIV + 15) is currently unused */ +#define WLAN_PRIV_SET_NONE_GET_THREE_INT (SIOCIWFIRSTPRIV + 15) +#define WE_GET_TSF 1 /* (SIOCIWFIRSTPRIV + 16) is currently unused */ /* (SIOCIWFIRSTPRIV + 17) is currently unused */ /* (SIOCIWFIRSTPRIV + 19) is currently unused */ @@ -6298,6 +6301,65 @@ static int iw_setint_getnone(struct net_device *dev, return ret; } +/** + * __iw_setnone_get_threeint() - return three value to up layer. + * + * @dev: pointer of net_device of this wireless card + * @info: meta data about Request sent + * @wrqu: include request info + * @extra: buf used for in/Output + * + * Return: execute result + */ +static int __iw_setnone_get_threeint(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; /* success */ + uint32_t *value = (int *)extra; + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + ENTER_DEV(dev); + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) + return ret; + + hdd_info(FL("param = %d"), value[0]); + switch (value[0]) { + case WE_GET_TSF: + ret = hdd_indicate_tsf(adapter, value, 3); + break; + default: + hdd_err("Invalid IOCTL get_value command %d", value[0]); + break; + } + return ret; +} + +/** + * iw_setnone_get_threeint() - return three value to up layer. + * + * @dev: pointer of net_device of this wireless card + * @info: meta data about Request sent + * @wrqu: include request info + * @extra: buf used for in/Output + * + * Return: execute result + */ +static int iw_setnone_get_threeint(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + cds_ssr_protect(__func__); + ret = __iw_setnone_get_threeint(dev, info, wrqu, extra); + cds_ssr_unprotect(__func__); + + return ret; +} + /** * iw_setchar_getnone() - Generic "set string" private ioctl handler * @dev: device upon which the ioctl was received @@ -6914,7 +6976,9 @@ static int __iw_setnone_getint(struct net_device *dev, QPOWER_CMD); break; } - + case WE_CAP_TSF: + ret = hdd_capture_tsf(pAdapter, (uint32_t *)value, 1); + break; case WE_GET_TEMPERATURE: { hddLog(QDF_TRACE_LEVEL_INFO, "WE_GET_TEMPERATURE"); @@ -9809,6 +9873,8 @@ static const iw_handler we_private[] = { [WLAN_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_setnone_getnone, /* action priv ioctl */ [WLAN_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_hdd_set_var_ints_getnone, + [WLAN_PRIV_SET_NONE_GET_THREE_INT - SIOCIWFIRSTPRIV] = + iw_setnone_get_threeint, [WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec, [WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec, [WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec, @@ -10506,6 +10572,11 @@ static const struct iw_priv_args we_private_args[] = { IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_qnodatapoll"}, + {WE_CAP_TSF, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "cap_tsf"}, + {WE_GET_TEMPERATURE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, @@ -10565,6 +10636,15 @@ static const struct iw_priv_args we_private_args[] = { IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setsapchannels"}, + /* handlers for main ioctl */ + {WLAN_PRIV_SET_NONE_GET_THREE_INT, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + "" }, + {WE_GET_TSF, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + "get_tsf" }, {WE_SET_DUAL_MAC_SCAN_CONFIG, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 5c5ff30e87f9..0ffc244385c7 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -5563,6 +5563,21 @@ struct sir_sme_ext_cng_chan_ind { uint8_t new_channel; }; +/** + * struct stsf - the basic stsf structure + * + * @vdev_id: vdev id + * @tsf_low: low 32bits of tsf + * @tsf_high: high 32bits of tsf + * + * driver use this struct to store the tsf info + */ +struct stsf { + uint32_t vdev_id; + uint32_t tsf_low; + uint32_t tsf_high; +}; + /** * struct egap_params - the enhanced green ap params * @vdev_id: vdev id diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index 23ab4d2dffe1..93aae032223e 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -248,6 +248,7 @@ enum eWniMsgTypes { eWNI_SME_HT40_OBSS_SCAN_IND, /* START and UPDATE OBSS SCAN Indication*/ eWNI_SME_SET_ANTENNA_MODE_REQ, eWNI_SME_SET_ANTENNA_MODE_RESP, + eWNI_SME_TSF_EVENT, eWNI_SME_MSG_TYPES_END }; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index d836a36a0389..73ce120093e4 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1096,6 +1096,8 @@ static inline QDF_STATUS sme_send_egap_conf_params(uint32_t enable, void sme_update_fine_time_measurement_capab(tHalHandle hal, uint32_t val); QDF_STATUS sme_ht40_stop_obss_scan(tHalHandle hHal, uint32_t vdev_id); +QDF_STATUS sme_set_tsfcb(tHalHandle hHal, + int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx); QDF_STATUS sme_update_mimo_power_save(tHalHandle hHal, uint8_t is_ht_smps_enabled, diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index 9e27ba2d2307..f681208043f3 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -197,6 +197,8 @@ typedef struct tagSmeStruct { bool enableSelfRecovery; tCsrLinkStatusCallback linkStatusCallback; void *linkStatusContext; + int (*get_tsf_cb)(void *pcb_cxt, struct stsf *ptsf); + void *get_tsf_cxt; /* get temperature event context and callback */ void *pTemperatureCbContext; void (*pGetTemperatureCb)(int temperature, void *context); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index c12aef820c50..8785b0b017b6 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -2805,6 +2805,14 @@ QDF_STATUS sme_process_msg(tHalHandle hHal, cds_msg_t *pMsg) qdf_mem_free(pMsg->bodyptr); } break; + case eWNI_SME_TSF_EVENT: + if (pMac->sme.get_tsf_cb) { + pMac->sme.get_tsf_cb(pMac->sme.get_tsf_cxt, + (struct stsf *)pMsg->bodyptr); + } + if (pMsg->bodyptr) + qdf_mem_free(pMsg->bodyptr); + break; #ifdef WLAN_FEATURE_NAN case eWNI_SME_NAN_EVENT: if (pMsg->bodyptr) { @@ -7300,6 +7308,29 @@ QDF_STATUS sme_preferred_network_found_ind(tHalHandle hHal, void *pMsg) #endif /* FEATURE_WLAN_SCAN_PNO */ +/* + * sme_set_tsfcb() - Set callback for TSF capture + * @hHal: Handler return by macOpen + * @cb_fn: Callback function pointer + * @db_ctx: Callback data + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_set_tsfcb(tHalHandle hHal, + int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + QDF_STATUS status; + + status = sme_acquire_global_lock(&pMac->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + pMac->sme.get_tsf_cb = cb_fn; + pMac->sme.get_tsf_cxt = cb_ctx; + sme_release_global_lock(&pMac->sme); + } + return status; +} + QDF_STATUS sme_get_cfg_valid_channels(tHalHandle hHal, uint8_t *aValidChannels, uint32_t *len) { diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h index cec1e1e705ab..4bf40d266470 100644 --- a/core/wma/inc/wma_api.h +++ b/core/wma/inc/wma_api.h @@ -65,6 +65,8 @@ typedef enum { GEN_PARAM_DUMP_PCIE_ACCESS_LOG, #endif GEN_PARAM_MODULATED_DTIM, + GEN_PARAM_CAPTURE_TSF, + GEN_PARAM_RESET_TSF_GPIO, } GEN_PARAM; #define VDEV_CMD 1 diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 42c2c9d6fe3f..4543eaac9113 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1072,6 +1072,10 @@ QDF_STATUS wma_set_auto_shutdown_timer_req(tp_wma_handle wma_handle, auto_sh_cmd); #endif +int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len); +QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id); +QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id); + #ifdef WLAN_FEATURE_NAN QDF_STATUS wma_nan_req(void *wma_ptr, tpNanRequest nan_req); diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 447aa417635b..3e526e53b38b 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -267,6 +267,177 @@ end: wma_post_link_status(pGetLinkStatus, LINK_STATUS_LEGACY); } +#ifdef WLAN_FEATURE_TSF +/** + * wma_vdev_tsf_handler() - handle tsf event indicated by FW + * @handle: wma context + * @data: event buffer + * @data len: length of event buffer + * + * Return: 0 on success + */ +int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len) +{ + cds_msg_t tsf_msg = {0}; + WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; + wmi_vdev_tsf_report_event_fixed_param *tsf_event; + struct stsf *ptsf; + + if (data == NULL) { + WMA_LOGE("%s: invalid pointer", __func__); + return -EINVAL; + } + ptsf = qdf_mem_malloc(sizeof(*ptsf)); + if (NULL == ptsf) { + WMA_LOGE("%s: failed to allocate tsf data structure", __func__); + return -ENOMEM; + } + + param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)data; + tsf_event = param_buf->fixed_param; + + ptsf->vdev_id = tsf_event->vdev_id; + ptsf->tsf_low = tsf_event->tsf_low; + ptsf->tsf_high = tsf_event->tsf_high; + + WMA_LOGD("%s: receive WMI_VDEV_TSF_REPORT_EVENTID ", __func__); + WMA_LOGD("%s: vdev_id = %u,tsf_low =%u, tsf_high = %u", __func__, + ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high); + + tsf_msg.type = eWNI_SME_TSF_EVENT; + tsf_msg.bodyptr = ptsf; + tsf_msg.bodyval = 0; + + if (QDF_STATUS_SUCCESS != + cds_mq_post_message(CDS_MQ_ID_SME, &tsf_msg)) { + + WMA_LOGP("%s: Failed to post eWNI_SME_TSF_EVENT", __func__); + qdf_mem_free(ptsf); + return -EINVAL; + } + return 0; +} + +/** + * wma_capture_tsf() - send wmi to fw to capture tsf + * @wma_handle: wma handler + * @vdev_id: vdev id + * + * Return: wmi send state + */ +QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + wmi_buf_t buf; + wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; + int ret; + int len = sizeof(*cmd); + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: failed to allocate memory for cap tsf cmd", + __func__); + return QDF_STATUS_E_NOMEM; + } + + cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) wmi_buf_data(buf); + cmd->vdev_id = vdev_id; + cmd->tsf_action = TSF_TSTAMP_CAPTURE_REQ; + + WMA_LOGD("%s :vdev_id %u, TSF_TSTAMP_CAPTURE_REQ", __func__, + cmd->vdev_id); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); + + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_VDEV_TSF_TSTAMP_ACTION_CMDID); + if (ret != EOK) { + WMA_LOGE("wmi_unified_cmd_send returned Error %d", status); + status = QDF_STATUS_E_FAILURE; + goto error; + } + + return QDF_STATUS_SUCCESS; + +error: + if (buf) + wmi_buf_free(buf); + return status; +} + +/** + * wma_reset_tsf_gpio() - send wmi to fw to reset GPIO + * @wma_handle: wma handler + * @vdev_id: vdev id + * + * Return: wmi send state + */ +QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + wmi_buf_t buf; + wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; + int ret; + int len = sizeof(*cmd); + uint8_t *buf_ptr; + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: failed to allocate memory for reset tsf gpio", + __func__); + return QDF_STATUS_E_NOMEM; + } + + buf_ptr = (uint8_t *) wmi_buf_data(buf); + cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) buf_ptr; + cmd->vdev_id = vdev_id; + cmd->tsf_action = TSF_TSTAMP_CAPTURE_RESET; + + WMA_LOGD("%s :vdev_id %u, TSF_TSTAMP_CAPTURE_RESET", __func__, + cmd->vdev_id); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); + + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_VDEV_TSF_TSTAMP_ACTION_CMDID); + + if (ret != EOK) { + WMA_LOGE("wmi_unified_cmd_send returned Error %d", status); + status = QDF_STATUS_E_FAILURE; + goto error; + } + return QDF_STATUS_SUCCESS; + +error: + if (buf) + wmi_buf_free(buf); + return status; +} +#else +QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} + +int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len) +{ + return 0; +} +#endif + + + #ifdef FEATURE_WLAN_LPHB /** * wma_lphb_conf_hbenable() - enable command of LPHB configuration requests diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 723ff4921eb8..b48424401c2a 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -919,6 +919,12 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma, privcmd->param_value, privcmd->param_sec_value); break; + case GEN_PARAM_CAPTURE_TSF: + ret = wma_capture_tsf(wma, privcmd->param_value); + break; + case GEN_PARAM_RESET_TSF_GPIO: + ret = wma_reset_tsf_gpio(wma, privcmd->param_value); + break; #ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG case GEN_PARAM_DUMP_PCIE_ACCESS_LOG: htc_dump(wma->htc_handle, PCIE_DUMP, false); @@ -2755,6 +2761,16 @@ QDF_STATUS wma_start(void *cds_ctx) goto end; } + status = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_VDEV_TSF_REPORT_EVENTID, + wma_vdev_tsf_handler, + WMA_RX_SERIALIZER_CTX); + if (0 != status) { + WMA_LOGP("%s: Failed to register tsf callback", __func__); + qdf_status = QDF_STATUS_E_FAILURE; + goto end; + } + /* Initialize the log flush complete event handler */ status = wmi_unified_register_event_handler(wma_handle->wmi_handle, WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID, -- cgit v1.2.3 From 976e756f56c31feddb9ec661ae0e41e68f1ea13c Mon Sep 17 00:00:00 2001 From: Manikandan Mohan Date: Tue, 15 Mar 2016 16:33:31 -0700 Subject: qcacld-3.0: Configure tsf gpio pin qcacld-2.0 to qcacld-3.0 propagation Add configuration of gpio pin used for TSF. FW shall toggle this gpio when receive capture/get tsf cmd. Change-Id: I442f2de3af4f3946a20bf3f4a9d8c9b285aa7a7c CRs-Fixed: 817527 --- core/hdd/inc/wlan_hdd_cfg.h | 6 ++++++ core/hdd/src/wlan_hdd_cfg.c | 9 ++++++++ core/hdd/src/wlan_hdd_main.c | 4 ++++ core/mac/src/include/sir_params.h | 2 ++ core/sme/inc/sme_api.h | 9 ++++++++ core/sme/src/common/sme_api.c | 45 +++++++++++++++++++++++++++++++++------ core/wma/inc/wma_internal.h | 28 ++++++++++++++++++++++++ core/wma/inc/wma_types.h | 1 + core/wma/src/wma_features.c | 41 ++++++++++++++++++++++++----------- core/wma/src/wma_main.c | 4 ++++ 10 files changed, 129 insertions(+), 20 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 98c9f9a35855..e29aadf527dc 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -2911,6 +2911,11 @@ enum dot11p_mode { #define CFG_INFORM_BSS_RSSI_RAW_MAX (1) #define CFG_INFORM_BSS_RSSI_RAW_DEFAULT (1) +/* GPIO pin to toggle when capture tsf */ +#define CFG_SET_TSF_GPIO_PIN_NAME "gtsf_gpio_pin" +#define CFG_SET_TSF_GPIO_PIN_MIN (0) +#define CFG_SET_TSF_GPIO_PIN_MAX (255) +#define CFG_SET_TSF_GPIO_PIN_DEFAULT (34) /* * OBSS scan parameters @@ -3579,6 +3584,7 @@ struct hdd_config { uint16_t obss_passive_dwelltime; uint16_t obss_width_trigger_interval; uint8_t inform_bss_rssi_raw; + uint32_t tsf_gpio_pin; #ifdef QCA_WIFI_3_0_EMU bool enable_m2m_limitation; #endif diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index eba3d85c8a67..5bbae4c696c1 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -3725,6 +3725,15 @@ REG_TABLE_ENTRY g_registry_table[] = { CFG_INFORM_BSS_RSSI_RAW_MIN, CFG_INFORM_BSS_RSSI_RAW_MAX), +#ifdef WLAN_FEATURE_TSF + REG_VARIABLE(CFG_SET_TSF_GPIO_PIN_NAME, WLAN_PARAM_Integer, + struct hdd_config, tsf_gpio_pin, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SET_TSF_GPIO_PIN_DEFAULT, + CFG_SET_TSF_GPIO_PIN_MIN, + CFG_SET_TSF_GPIO_PIN_MAX), +#endif + #ifdef QCA_WIFI_3_0_EMU REG_VARIABLE(CFG_ENABLE_M2M_LIMITATION, WLAN_PARAM_Integer, struct hdd_config, enable_m2m_limitation, diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 730ee4e82a6b..9c04a870ce60 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5943,6 +5943,10 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) if (QDF_IS_STATUS_SUCCESS(status)) hdd_err("Error setting txlimit in sme: %d", status); + status = sme_set_tsf_gpio(hdd_ctx->hHal, hdd_ctx->config->tsf_gpio_pin); + if (!QDF_IS_STATUS_SUCCESS(status)) + hdd_err("set tsf GPIO fail"); + #ifdef MSM_PLATFORM spin_lock_init(&hdd_ctx->bus_bw_lock); qdf_mc_timer_init(&hdd_ctx->bus_bw_timer, diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index 6287638b2b8f..75dc58bc40a0 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -599,6 +599,8 @@ typedef struct sSirMbMsgP2p { #define SIR_HAL_SET_EGAP_CONF_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 336) #define SIR_HAL_HT40_OBSS_SCAN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 337) +#define SIR_HAL_TSF_GPIO_PIN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 338) + #define SIR_HAL_ADD_BCN_FILTER_CMDID (SIR_HAL_ITC_MSG_TYPES_BEGIN + 339) #define SIR_HAL_REMOVE_BCN_FILTER_CMDID (SIR_HAL_ITC_MSG_TYPES_BEGIN + 340) diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 73ce120093e4..0cc23cd26ffe 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1099,6 +1099,15 @@ QDF_STATUS sme_ht40_stop_obss_scan(tHalHandle hHal, uint32_t vdev_id); QDF_STATUS sme_set_tsfcb(tHalHandle hHal, int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx); +#ifdef WLAN_FEATURE_TSF +QDF_STATUS sme_set_tsf_gpio(tHalHandle h_hal, uint32_t pinvalue); +#else +static inline QDF_STATUS sme_set_tsf_gpio(tHalHandle h_hal, uint32_t pinvalue) +{ + return QDF_STATUS_E_FAILURE; +} +#endif + QDF_STATUS sme_update_mimo_power_save(tHalHandle hHal, uint8_t is_ht_smps_enabled, uint8_t ht_smps_mode, diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 8785b0b017b6..a4d636f55c7d 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -7310,26 +7310,57 @@ QDF_STATUS sme_preferred_network_found_ind(tHalHandle hHal, void *pMsg) /* * sme_set_tsfcb() - Set callback for TSF capture - * @hHal: Handler return by macOpen + * @h_hal: Handler return by mac_open * @cb_fn: Callback function pointer * @db_ctx: Callback data * * Return: QDF_STATUS */ -QDF_STATUS sme_set_tsfcb(tHalHandle hHal, +QDF_STATUS sme_set_tsfcb(tHalHandle h_hal, int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx) { - tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpAniSirGlobal mac = PMAC_STRUCT(h_hal); QDF_STATUS status; - status = sme_acquire_global_lock(&pMac->sme); + status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { - pMac->sme.get_tsf_cb = cb_fn; - pMac->sme.get_tsf_cxt = cb_ctx; - sme_release_global_lock(&pMac->sme); + mac->sme.get_tsf_cb = cb_fn; + mac->sme.get_tsf_cxt = cb_ctx; + sme_release_global_lock(&mac->sme); + } + return status; +} + +#ifdef WLAN_FEATURE_TSF +/* + * sme_set_tsf_gpio() - set gpio pin that be toggled when capture tef + * @h_hal: Handler return by mac_open + * @pinvalue: gpio pin id + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_set_tsf_gpio(tHalHandle h_hal, uint32_t pinvalue) +{ + QDF_STATUS status; + cds_msg_t tsf_msg = {0}; + tpAniSirGlobal mac = PMAC_STRUCT(h_hal); + + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + tsf_msg.type = WMA_TSF_GPIO_PIN; + tsf_msg.reserved = 0; + tsf_msg.bodyval = pinvalue; + + status = cds_mq_post_message(CDS_MQ_ID_WMA, &tsf_msg); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sms_log(mac, LOGE, "Unable to post WMA_TSF_GPIO_PIN"); + status = QDF_STATUS_E_FAILURE; + } + sme_release_global_lock(&mac->sme); } return status; } +#endif QDF_STATUS sme_get_cfg_valid_channels(tHalHandle hHal, uint8_t *aValidChannels, uint32_t *len) diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 4543eaac9113..2f47901d9143 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1072,9 +1072,37 @@ QDF_STATUS wma_set_auto_shutdown_timer_req(tp_wma_handle wma_handle, auto_sh_cmd); #endif +#ifdef WLAN_FEATURE_TSF int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len); QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id); QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id); +QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin); +#else +static inline QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, + uint32_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, + uint32_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} + +static inline int wma_vdev_tsf_handler(void *handle, uint8_t *data, + uint32_t data_len) +{ + return 0; +} + +static inline QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin) +{ + return QDF_STATUS_E_INVAL; +} +#endif + + #ifdef WLAN_FEATURE_NAN diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index c82cfa033a33..791f0f88910b 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -432,6 +432,7 @@ #endif #define WMA_SET_SCAN_MAC_OUI_REQ SIR_HAL_SET_SCAN_MAC_OUI_REQ +#define WMA_TSF_GPIO_PIN SIR_HAL_TSF_GPIO_PIN_REQ #ifdef DHCP_SERVER_OFFLOAD #define WMA_SET_DHCP_SERVER_OFFLOAD_CMD SIR_HAL_SET_DHCP_SERVER_OFFLOAD diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 3e526e53b38b..d23e1cbd2192 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -419,24 +419,39 @@ error: wmi_buf_free(buf); return status; } -#else -QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id) -{ - return QDF_STATUS_SUCCESS; -} -QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id) +/** + * wma_set_tsf_gpio_pin() - send wmi cmd to configure gpio pin + * @handle: wma handler + * @pin: GPIO pin id + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin) { - return QDF_STATUS_SUCCESS; -} + tp_wma_handle wma = (tp_wma_handle)handle; + struct pdev_params pdev_param = {0}; + int32_t ret; -int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len) -{ - return 0; -} -#endif + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not set gpio", __func__); + return QDF_STATUS_E_INVAL; + } + WMA_LOGD("%s: set tsf gpio pin: %d", __func__, pin); + pdev_param.param_id = WMI_PDEV_PARAM_WNTS_CONFIG; + pdev_param.param_value = pin; + ret = wmi_unified_pdev_param_send(wma->wmi_handle, + &pdev_param, + WMA_WILDCARD_PDEV_ID); + if (ret) { + WMA_LOGE("%s: Failed to set tsf gpio pin (%d)", __func__, ret); + return QDF_STATUS_E_FAILURE; + } + return QDF_STATUS_SUCCESS; +} +#endif #ifdef FEATURE_WLAN_LPHB /** diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index b48424401c2a..f0720411203d 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -5123,6 +5123,10 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg) wma_get_temperature(wma_handle); qdf_mem_free(msg->bodyptr); break; + case WMA_TSF_GPIO_PIN: + wma_set_tsf_gpio_pin(wma_handle, msg->bodyval); + break; + #ifdef DHCP_SERVER_OFFLOAD case WMA_SET_DHCP_SERVER_OFFLOAD_CMD: wma_process_dhcpserver_offload(wma_handle, -- cgit v1.2.3 From 296d4b5d321480adda0fbef15a73b35d6a4f04b2 Mon Sep 17 00:00:00 2001 From: Manikandan Mohan Date: Tue, 15 Mar 2016 16:39:31 -0700 Subject: qcacld-3.0: Configure only valid TSF gpio pin qcacld-2.0 to qcacld-3.0 propagation Update qcacld to configure only valid GPIO setting if enabled in INI file. Default TSF Gpio value is set as invalid, so it will not be set in firmware during driver load. Change-Id: I0414becbf83718155a9ca51d60f34d0e8ffcd4e3 CRs-fixed: 994569 --- core/hdd/inc/wlan_hdd_cfg.h | 5 +++-- core/hdd/src/wlan_hdd_main.c | 9 ++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index e29aadf527dc..3d346292ba84 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -2914,8 +2914,9 @@ enum dot11p_mode { /* GPIO pin to toggle when capture tsf */ #define CFG_SET_TSF_GPIO_PIN_NAME "gtsf_gpio_pin" #define CFG_SET_TSF_GPIO_PIN_MIN (0) -#define CFG_SET_TSF_GPIO_PIN_MAX (255) -#define CFG_SET_TSF_GPIO_PIN_DEFAULT (34) +#define CFG_SET_TSF_GPIO_PIN_MAX (254) +#define TSF_GPIO_PIN_INVALID (255) +#define CFG_SET_TSF_GPIO_PIN_DEFAULT (TSF_GPIO_PIN_INVALID) /* * OBSS scan parameters diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 9c04a870ce60..47198bcdfc19 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5943,9 +5943,12 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) if (QDF_IS_STATUS_SUCCESS(status)) hdd_err("Error setting txlimit in sme: %d", status); - status = sme_set_tsf_gpio(hdd_ctx->hHal, hdd_ctx->config->tsf_gpio_pin); - if (!QDF_IS_STATUS_SUCCESS(status)) - hdd_err("set tsf GPIO fail"); + if (hdd_ctx->config->tsf_gpio_pin != TSF_GPIO_PIN_INVALID) { + status = sme_set_tsf_gpio(hdd_ctx->hHal, + hdd_ctx->config->tsf_gpio_pin); + if (!QDF_IS_STATUS_SUCCESS(status)) + hdd_err("set tsf GPIO fail"); + } #ifdef MSM_PLATFORM spin_lock_init(&hdd_ctx->bus_bw_lock); -- cgit v1.2.3 From 89c66ff56cf94853cc11bb4e25ddf21413e96860 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Fri, 22 Apr 2016 15:21:37 -0700 Subject: qcacld-3.0: Avoid unexpected TSF GPIO failure qcacld-2.0 to qcacld-3.0 propagation A customer observed the following error log: wlan: [1662:E :HDD] hdd_wlan_startup: 12873: set tsf GPIO fail The customer was concerned that the device was not working correctly. The reality is that the TSF GPIO is only expected to be set on specific hardware platforms, and the customer platform was not one of those platforms. Fix this issue by making sure that all of the TSF GPIO logic is properly encapsulated within the WLAN_FEATURE_TSF feature flag. Change-Id: I34eab623243d4674c5fc1d0c8139d80efe5786a7 CRs-Fixed: 962955 --- core/hdd/inc/wlan_hdd_cfg.h | 2 ++ core/hdd/src/wlan_hdd_main.c | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 3d346292ba84..70d4ad63095f 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -3585,7 +3585,9 @@ struct hdd_config { uint16_t obss_passive_dwelltime; uint16_t obss_width_trigger_interval; uint8_t inform_bss_rssi_raw; +#ifdef WLAN_FEATURE_TSF uint32_t tsf_gpio_pin; +#endif #ifdef QCA_WIFI_3_0_EMU bool enable_m2m_limitation; #endif diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 47198bcdfc19..6722d4677832 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5671,6 +5671,35 @@ QDF_STATUS hdd_register_for_sap_restart_with_channel_switch(void) } #endif +/** + * hdd_tsf_init() - Initialize the TSF synchronization interface + * @hdd_ctx: HDD global context + * + * When TSF synchronization via GPIO is supported by the driver and + * has been enabled in the configuration file, this function plumbs + * the GPIO value down to firmware via SME. + * + * Return: None + */ +#ifdef WLAN_FEATURE_TSF +static void hdd_tsf_init(hdd_context_t *hdd_ctx) +{ + QDF_STATUS status; + + if (hdd_ctx->config->tsf_gpio_pin == TSF_GPIO_PIN_INVALID) + return; + + status = sme_set_tsf_gpio(hdd_ctx->hHal, + hdd_ctx->config->tsf_gpio_pin); + if (!QDF_IS_STATUS_SUCCESS(status)) + hdd_err("Set tsf GPIO failed, status: %d", status); +} +#else +static void hdd_tsf_init(hdd_context_t *hdd_ctx) +{ +} +#endif + /** * hdd_wlan_startup() - HDD init function * @dev: Pointer to the underlying device @@ -5943,13 +5972,7 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) if (QDF_IS_STATUS_SUCCESS(status)) hdd_err("Error setting txlimit in sme: %d", status); - if (hdd_ctx->config->tsf_gpio_pin != TSF_GPIO_PIN_INVALID) { - status = sme_set_tsf_gpio(hdd_ctx->hHal, - hdd_ctx->config->tsf_gpio_pin); - if (!QDF_IS_STATUS_SUCCESS(status)) - hdd_err("set tsf GPIO fail"); - } - + hdd_tsf_init(hdd_ctx); #ifdef MSM_PLATFORM spin_lock_init(&hdd_ctx->bus_bw_lock); qdf_mc_timer_init(&hdd_ctx->bus_bw_timer, -- cgit v1.2.3 From efc5ccd7ca5791056501ebfd9d63833e7f9d3d71 Mon Sep 17 00:00:00 2001 From: Govind Singh Date: Mon, 25 Apr 2016 11:11:55 +0530 Subject: qcacld-3.0: Replace mac_id with pdev_id in WMI PDEV commands Replace mac_id with pdev_id for WMI pdev commands and vdev start response handler to support multi-radio in converged firmware. In order to maintain backward compatibility with old fw, host needs to check WMI_SERVICE_DEPRECATED_REPLACE service id in service bitmap and needs to fill pdev id or mac id accordingly. Change-Id: I7e6b40b4c0bd20e967dc0a383b480068e256486f CRs-Fixed: 994415 --- core/wma/inc/wma.h | 9 +++++++++ core/wma/src/wma_data.c | 12 +++++++++++- core/wma/src/wma_dev_if.c | 16 ++++++++++++++-- core/wma/src/wma_main.c | 14 ++++++++++++++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index ff9dca2f5a70..b525dd771d9f 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -63,6 +63,15 @@ #define WMA_CRASH_INJECT_TIMEOUT 5000 +/* MAC ID to PDEV ID mapping is as given below + * MAC_ID PDEV_ID + * 0 1 + * 1 2 + * SOC Level WMI_PDEV_ID_SOC + */ +#define WMA_MAC_TO_PDEV_MAP(x) ((x) + (1)) +#define WMA_PDEV_TO_MAC_MAP(x) ((x) - (1)) + /* In prima 12 HW stations are supported including BCAST STA(staId 0) * and SELF STA(staId 1) so total ASSOC stations which can connect to Prima * SoftAP = 12 - 1(Self STa) - 1(Bcast Sta) = 10 Stations. diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 572b7d91a1d8..ec3c88102331 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -999,6 +999,7 @@ QDF_STATUS wma_set_enable_disable_mcc_adaptive_scheduler(uint32_t mcc_adaptive_scheduler) { tp_wma_handle wma = NULL; + uint32_t pdev_id; wma = cds_get_context(QDF_MODULE_ID_WMA); if (NULL == wma) { @@ -1006,8 +1007,17 @@ QDF_STATUS wma_set_enable_disable_mcc_adaptive_scheduler(uint32_t return QDF_STATUS_E_FAULT; } + /* In WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID fw cannot + * determine the PDEV on its own, Host needs to specify the PDEV + * ID in the command. + */ + if (wma->wlan_resource_config.use_pdev_id) + pdev_id = WMA_MAC_TO_PDEV_MAP(0); + else + pdev_id = WMI_PDEV_ID_SOC; + return wmi_unified_set_enable_disable_mcc_adaptive_scheduler_cmd( - wma->wmi_handle, mcc_adaptive_scheduler); + wma->wmi_handle, mcc_adaptive_scheduler, pdev_id); } /** diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 7526499d390c..efdde8dd5b5c 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -820,8 +820,20 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, resp_event->cfgd_rx_streams; wma->interfaces[resp_event->vdev_id].chain_mask = resp_event->chain_mask; - wma->interfaces[resp_event->vdev_id].mac_id = - resp_event->mac_id; + if (wma->wlan_resource_config.use_pdev_id) { + if (resp_event->pdev_id == WMI_PDEV_ID_SOC) { + WMA_LOGE("%s: soc level id received for mac id", + __func__); + QDF_BUG(0); + return -EINVAL; + } + wma->interfaces[resp_event->vdev_id].mac_id = + WMA_PDEV_TO_MAC_MAP(resp_event->pdev_id); + } else { + wma->interfaces[resp_event->vdev_id].mac_id = + resp_event->mac_id; + } + WMA_LOGI("%s: vdev:%d tx ss=%d rx ss=%d chain mask=%d mac=%d", __func__, resp_event->vdev_id, diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index f0720411203d..defe3cc90cb9 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -3917,6 +3917,20 @@ int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info, return -EINVAL; } + /* mac_id is replaced with pdev_id in converged firmware to have + * multi-radio support. In order to maintain backward compatibility + * with old fw, host needs to check WMI_SERVICE_DEPRECATED_REPLACE + * in service bitmap from FW and host needs to set use_pdev_id in + * wmi_resource_config to true. If WMI_SERVICE_DEPRECATED_REPLACE + * service is not set, then host shall not expect MAC ID from FW in + * VDEV START RESPONSE event and host shall use PDEV ID. + */ + if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, + WMI_SERVICE_DEPRECATED_REPLACE)) + wma_handle->wlan_resource_config.use_pdev_id = true; + else + wma_handle->wlan_resource_config.use_pdev_id = false; + /* register the Enhanced Green AP event handler */ wma_register_egap_event_handle(wma_handle); -- cgit v1.2.3 From 86bfeb15e64069157cf59402ceae52ea93eaffa2 Mon Sep 17 00:00:00 2001 From: Govind Singh Date: Wed, 27 Apr 2016 15:03:14 +0530 Subject: qcacld-3.0: Remove FL macro definition from UMAC layer FL macro definition is used in converged layer, move FL macro definition from umac layer to common qdf layer. Change-Id: Id3c4383c385eb3d6391c4c066b0034fb2f053cdc CRs-Fixed: 1008835 --- core/mac/src/include/sir_debug.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/mac/src/include/sir_debug.h b/core/mac/src/include/sir_debug.h index 674855d0567b..c038523cf784 100644 --- a/core/mac/src/include/sir_debug.h +++ b/core/mac/src/include/sir_debug.h @@ -100,9 +100,6 @@ #endif /* WLAN_MDM_CODE_REDUCTION_OPT */ -#define FL(x) "%s: %d: " \ - x, __func__, __LINE__ - #define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] #define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" -- cgit v1.2.3 From 91152df26bc4f0e21fcaee911a3e96579089c61b Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Mon, 25 Apr 2016 14:29:27 +0530 Subject: qcacld-3.0: Save the requested scan and fw mode config Save the requested scan and fw mode config when these new configs are sent to the firmware for update. This saved parameter updates the current scan and fw mode config respectively on getting the response from the firmware. If this parameter is not saved and updated in the current scan and fw mode configs, the next attempt to fetch the current scan and fw mode config provides the wrong config values. Change-Id: Iae10d16b29038a8e321ef74ba591b032eedbe425 CRs-Fixed: 1007653 --- core/wma/src/wma_main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index defe3cc90cb9..35ebdb72157d 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -5446,6 +5446,8 @@ fail: QDF_STATUS wma_send_soc_set_dual_mac_config(tp_wma_handle wma_handle, struct sir_dual_mac_config *msg) { + QDF_STATUS status; + if (!wma_handle) { WMA_LOGE("%s: WMA handle is NULL. Cannot issue command", __func__); @@ -5457,11 +5459,16 @@ QDF_STATUS wma_send_soc_set_dual_mac_config(tp_wma_handle wma_handle, return QDF_STATUS_E_NULL_VALUE; } + status = wmi_unified_soc_set_dual_mac_config_cmd(wma_handle->wmi_handle, + (struct wmi_dual_mac_config *)msg); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s: Failed to send WMI_SOC_SET_DUAL_MAC_CONFIG_CMDID: %d", + __func__, status); + return status; + } - if (wmi_unified_soc_set_dual_mac_config_cmd(wma_handle->wmi_handle, - (struct wmi_dual_mac_config *)msg)) - WMA_LOGE("%s: Failed to send WMI_SOC_SET_DUAL_MAC_CONFIG_CMDID", - __func__); + wma_handle->dual_mac_cfg.req_scan_config = msg->scan_config; + wma_handle->dual_mac_cfg.req_fw_mode_config = msg->fw_mode_config; return QDF_STATUS_SUCCESS; } -- cgit v1.2.3 From d96403461fa2c1cf98e8743fefcaeecb43d319dd Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Wed, 27 Apr 2016 12:28:26 +0530 Subject: qcacld-3.0: Replace soc level references of set hw request and response Replace the obsolete WMI command WMI_SOC_SET_HW_MODE_CMDID with WMI_PDEV_SET_HW_MODE_CMDID and event WMI_SOC_SET_HW_MODE_RESP_EVENTID with WMI_PDEV_SET_HW_MODE_RESP_EVENTID respectively. These new WMI commands and events additionally carry the pdev id and all mac id references are replaced with pdev id. Change-Id: If2a3f93dcd1947eedce8d4eac8ed936166f7e078 CRs-Fixed: 989502 --- core/cds/inc/cds_concurrency.h | 2 +- core/cds/src/cds_concurrency.c | 16 +++---- core/hdd/src/wlan_hdd_wext.c | 4 +- core/mac/src/include/sir_params.h | 4 +- core/mac/src/pe/lim/lim_process_message_queue.c | 2 +- core/mac/src/pe/lim/lim_process_sme_req_messages.c | 2 +- core/mac/src/sys/legacy/src/utils/src/mac_trace.c | 2 +- core/sme/inc/sme_api.h | 2 +- core/sme/src/common/sme_api.c | 6 +-- core/wma/inc/wma.h | 2 +- core/wma/src/wma_main.c | 52 +++++++++++++--------- 11 files changed, 51 insertions(+), 43 deletions(-) diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h index 45e37f8b0f94..3dd9786e706a 100644 --- a/core/cds/inc/cds_concurrency.h +++ b/core/cds/inc/cds_concurrency.h @@ -698,7 +698,7 @@ static inline struct cds_conc_connection_info *cds_get_conn_info(uint32_t *len) enum cds_con_mode cds_convert_device_mode_to_qdf_type( enum tQDF_ADAPTER_MODE device_mode); -QDF_STATUS cds_soc_set_hw_mode(uint32_t session_id, +QDF_STATUS cds_pdev_set_hw_mode(uint32_t session_id, enum hw_mode_ss_config mac0_ss, enum hw_mode_bandwidth mac0_bw, enum hw_mode_ss_config mac1_ss, diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index f211ace0dfc5..b90592766319 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -2379,7 +2379,7 @@ void cds_set_dual_mac_fw_mode_config(uint8_t dbs, uint8_t dfs) } /** - * cds_soc_set_hw_mode_cb() - Callback for set hw mode + * cds_pdev_set_hw_mode_cb() - Callback for set hw mode * @status: Status * @cfgd_hw_mode_index: Configured HW mode index * @num_vdev_mac_entries: Number of vdev-mac id mapping that follows @@ -2391,7 +2391,7 @@ void cds_set_dual_mac_fw_mode_config(uint8_t dbs, uint8_t dfs) * * Return: None */ -static void cds_soc_set_hw_mode_cb(uint32_t status, +static void cds_pdev_set_hw_mode_cb(uint32_t status, uint32_t cfgd_hw_mode_index, uint32_t num_vdev_mac_entries, struct sir_vdev_mac_map *vdev_mac_map) @@ -2498,7 +2498,7 @@ static void cds_hw_mode_transition_cb(uint32_t old_hw_mode_index, } /** - * cds_soc_set_hw_mode() - Set HW mode command to SME + * cds_pdev_set_hw_mode() - Set HW mode command to SME * @session_id: Session ID * @mac0_ss: MAC0 spatial stream configuration * @mac0_bw: MAC0 bandwidth configuration @@ -2526,7 +2526,7 @@ static void cds_hw_mode_transition_cb(uint32_t old_hw_mode_index, * * Return: Success if the message made it down to the next layer */ -QDF_STATUS cds_soc_set_hw_mode(uint32_t session_id, +QDF_STATUS cds_pdev_set_hw_mode(uint32_t session_id, enum hw_mode_ss_config mac0_ss, enum hw_mode_bandwidth mac0_bw, enum hw_mode_ss_config mac1_ss, @@ -2554,14 +2554,14 @@ QDF_STATUS cds_soc_set_hw_mode(uint32_t session_id, } msg.hw_mode_index = hw_mode_index; - msg.set_hw_mode_cb = (void *)cds_soc_set_hw_mode_cb; + msg.set_hw_mode_cb = (void *)cds_pdev_set_hw_mode_cb; msg.reason = reason; msg.session_id = session_id; cds_info("set hw mode to sme: hw_mode_index: %d session:%d reason:%d", msg.hw_mode_index, msg.session_id, msg.reason); - status = sme_soc_set_hw_mode(hdd_ctx->hHal, msg); + status = sme_pdev_set_hw_mode(hdd_ctx->hHal, msg); if (status != QDF_STATUS_SUCCESS) { cds_err("Failed to set hw mode to SME"); return status; @@ -6214,7 +6214,7 @@ QDF_STATUS cds_next_actions(uint32_t session_id, session_id); break; case CDS_DBS: - status = cds_soc_set_hw_mode(session_id, + status = cds_pdev_set_hw_mode(session_id, HW_MODE_SS_1x1, HW_MODE_80_MHZ, HW_MODE_SS_1x1, HW_MODE_40_MHZ, @@ -6232,7 +6232,7 @@ QDF_STATUS cds_next_actions(uint32_t session_id, session_id); break; case CDS_MCC: - status = cds_soc_set_hw_mode(session_id, + status = cds_pdev_set_hw_mode(session_id, HW_MODE_SS_2x2, HW_MODE_80_MHZ, HW_MODE_SS_0x0, HW_MODE_BW_NONE, diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index b88b01bf11ed..9e3571890bf9 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -8041,7 +8041,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev, if (apps_args[0] == 0) { hddLog(LOGE, FL("set hw mode for single mac\n")); - cds_soc_set_hw_mode( + cds_pdev_set_hw_mode( pAdapter->sessionId, HW_MODE_SS_2x2, HW_MODE_80_MHZ, @@ -8052,7 +8052,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev, } else if (apps_args[0] == 1) { hddLog(LOGE, FL("set hw mode for dual mac\n")); - cds_soc_set_hw_mode( + cds_pdev_set_hw_mode( pAdapter->sessionId, HW_MODE_SS_1x1, HW_MODE_80_MHZ, diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index 75dc58bc40a0..cc433c1a65b2 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -587,8 +587,8 @@ typedef struct sSirMbMsgP2p { #define SIR_HAL_FW_MEM_DUMP_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 327) #define SIR_HAL_START_STOP_LOGGING (SIR_HAL_ITC_MSG_TYPES_BEGIN + 328) -#define SIR_HAL_SOC_SET_HW_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 329) -#define SIR_HAL_SOC_SET_HW_MODE_RESP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 330) +#define SIR_HAL_PDEV_SET_HW_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 329) +#define SIR_HAL_PDEV_SET_HW_MODE_RESP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 330) #define SIR_HAL_SOC_HW_MODE_TRANS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 331) #define SIR_HAL_SET_RSSI_MONITOR_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 333) diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index 27d6a4159760..0bd956256ad6 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -2046,7 +2046,7 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) msg->bodyptr = NULL; break; #endif - case SIR_HAL_SOC_SET_HW_MODE_RESP: + case SIR_HAL_PDEV_SET_HW_MODE_RESP: lim_process_set_hw_mode_resp(mac_ctx, msg->bodyptr); qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index 8de45fe8734f..96a428d83144 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -165,7 +165,7 @@ static QDF_STATUS lim_process_set_hw_mode(tpAniSirGlobal mac, uint32_t *msg) /* Other parameters are not needed for WMA */ cds_message.bodyptr = req_msg; - cds_message.type = SIR_HAL_SOC_SET_HW_MODE; + cds_message.type = SIR_HAL_PDEV_SET_HW_MODE; lim_log(mac, LOG1, FL("Posting SIR_HAL_SOC_SET_HW_MOD to WMA")); status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c index db836f05c46f..1c1252e098ef 100644 --- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c +++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c @@ -527,7 +527,7 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg) CASE_RETURN_STRING(SIR_HAL_START_STOP_LOGGING); CASE_RETURN_STRING(SIR_HAL_FLUSH_LOG_TO_FW); CASE_RETURN_STRING(SIR_HAL_PDEV_SET_PCL_TO_FW); - CASE_RETURN_STRING(SIR_HAL_SOC_SET_HW_MODE); + CASE_RETURN_STRING(SIR_HAL_PDEV_SET_HW_MODE); CASE_RETURN_STRING(SIR_HAL_SOC_DUAL_MAC_CFG_REQ); CASE_RETURN_STRING(WMA_RADAR_DETECTED_IND); CASE_RETURN_STRING(WMA_TIMER_TRAFFIC_STATS_IND); diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 0cc23cd26ffe..0906720997c2 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -988,7 +988,7 @@ bool sme_is_any_session_in_connected_state(tHalHandle h_hal); QDF_STATUS sme_pdev_set_pcl(tHalHandle hal, struct sir_pcl_list msg); -QDF_STATUS sme_soc_set_hw_mode(tHalHandle hal, +QDF_STATUS sme_pdev_set_hw_mode(tHalHandle hal, struct sir_hw_mode msg); void sme_register_hw_mode_trans_cb(tHalHandle hal, hw_mode_transition_cb callback); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index a4d636f55c7d..49c7d685b708 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -14918,14 +14918,14 @@ QDF_STATUS sme_pdev_set_pcl(tHalHandle hal, } /* - * sme_soc_set_hw_mode() - Send WMI_SOC_SET_HW_MODE_CMDID to the WMA + * sme_pdev_set_hw_mode() - Send WMI_PDEV_SET_HW_MODE_CMDID to the WMA * @hal: Handle returned by macOpen * @msg: HW mode structure containing hw mode and callback details * - * Sends the command to CSR to send WMI_SOC_SET_HW_MODE_CMDID to FW + * Sends the command to CSR to send WMI_PDEV_SET_HW_MODE_CMDID to FW * Return: QDF_STATUS_SUCCESS on successful posting */ -QDF_STATUS sme_soc_set_hw_mode(tHalHandle hal, +QDF_STATUS sme_pdev_set_hw_mode(tHalHandle hal, struct sir_hw_mode msg) { QDF_STATUS status = QDF_STATUS_SUCCESS; diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index b525dd771d9f..b503fd1ae89f 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1981,7 +1981,7 @@ QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma, QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle, struct wmi_pcl_chan_weights *msg); -QDF_STATUS wma_send_soc_set_hw_mode_cmd(tp_wma_handle wma_handle, +QDF_STATUS wma_send_pdev_set_hw_mode_cmd(tp_wma_handle wma_handle, struct sir_hw_mode *msg); QDF_STATUS wma_get_scan_id(uint32_t *scan_id); diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 35ebdb72157d..66042548a741 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -2290,23 +2290,24 @@ static int wma_flush_complete_evt_handler(void *handle, } /** - * wma_soc_set_hw_mode_resp_evt_handler() - Set HW mode resp evt handler + * wma_pdev_set_hw_mode_resp_evt_handler() - Set HW mode resp evt handler * @handle: WMI handle * @event: Event recevied from FW * @len: Length of the event * - * Event handler for WMI_SOC_SET_HW_MODE_RESP_EVENTID that is sent to host - * driver in response to a WMI_SOC_SET_HW_MODE_CMDID being sent to WLAN firmware + * Event handler for WMI_PDEV_SET_HW_MODE_RESP_EVENTID that is sent to host + * driver in response to a WMI_PDEV_SET_HW_MODE_CMDID being sent to WLAN + * firmware * * Return: Success on receiving valid params from FW */ -static int wma_soc_set_hw_mode_resp_evt_handler(void *handle, +static int wma_pdev_set_hw_mode_resp_evt_handler(void *handle, uint8_t *event, uint32_t len) { - WMI_SOC_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; - wmi_soc_set_hw_mode_response_event_fixed_param *wmi_event; - wmi_soc_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry; + WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; + wmi_pdev_set_hw_mode_response_event_fixed_param *wmi_event; + wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry; uint32_t i; struct sir_set_hw_mode_resp *hw_mode_resp; tp_wma_handle wma = (tp_wma_handle) handle; @@ -2328,9 +2329,9 @@ static int wma_soc_set_hw_mode_resp_evt_handler(void *handle, return QDF_STATUS_E_NULL_VALUE; } - param_buf = (WMI_SOC_SET_HW_MODE_RESP_EVENTID_param_tlvs *) event; + param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *) event; if (!param_buf) { - WMA_LOGE("Invalid WMI_SOC_SET_HW_MODE_RESP_EVENTID event"); + WMA_LOGE("Invalid WMI_PDEV_SET_HW_MODE_RESP_EVENTID event"); /* Need to send response back to upper layer to free * active command list */ @@ -2347,13 +2348,20 @@ static int wma_soc_set_hw_mode_resp_evt_handler(void *handle, wmi_event->cfgd_hw_mode_index, wmi_event->num_vdev_mac_entries); vdev_mac_entry = - param_buf->wmi_soc_set_hw_mode_response_vdev_mac_mapping; + param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping; /* Store the vdev-mac map in WMA and prepare to send to PE */ for (i = 0; i < wmi_event->num_vdev_mac_entries; i++) { - uint32_t vdev_id, mac_id; + uint32_t vdev_id, mac_id, pdev_id; vdev_id = vdev_mac_entry[i].vdev_id; - mac_id = vdev_mac_entry[i].mac_id; + pdev_id = vdev_mac_entry[i].pdev_id; + if (pdev_id == WMI_PDEV_ID_SOC) { + WMA_LOGE("%s: soc level id received for mac id)", + __func__); + QDF_BUG(0); + goto fail; + } + mac_id = WMA_PDEV_TO_MAC_MAP(vdev_mac_entry[i].pdev_id); WMA_LOGI("%s: vdev_id:%d mac_id:%d", __func__, vdev_id, mac_id); @@ -2376,7 +2384,7 @@ static int wma_soc_set_hw_mode_resp_evt_handler(void *handle, WMA_LOGI("%s: Updated: old_hw_mode_index:%d new_hw_mode_index:%d", __func__, wma->old_hw_mode_index, wma->new_hw_mode_index); - wma_send_msg(wma, SIR_HAL_SOC_SET_HW_MODE_RESP, + wma_send_msg(wma, SIR_HAL_PDEV_SET_HW_MODE_RESP, (void *) hw_mode_resp, 0); return QDF_STATUS_SUCCESS; @@ -2386,7 +2394,7 @@ fail: hw_mode_resp->status = SET_HW_MODE_STATUS_ECANCELED; hw_mode_resp->cfgd_hw_mode_index = 0; hw_mode_resp->num_vdev_mac_entries = 0; - wma_send_msg(wma, SIR_HAL_SOC_SET_HW_MODE_RESP, + wma_send_msg(wma, SIR_HAL_PDEV_SET_HW_MODE_RESP, (void *) hw_mode_resp, 0); return QDF_STATUS_E_FAILURE; @@ -2782,10 +2790,10 @@ QDF_STATUS wma_start(void *cds_ctx) goto end; } - /* Initialize the WMI_SOC_SET_HW_MODE_RESP_EVENTID event handler */ + /* Initialize the wma_pdev_set_hw_mode_resp_evt_handler event handler */ status = wmi_unified_register_event_handler(wma_handle->wmi_handle, - WMI_SOC_SET_HW_MODE_RESP_EVENTID, - wma_soc_set_hw_mode_resp_evt_handler, + WMI_PDEV_SET_HW_MODE_RESP_EVENTID, + wma_pdev_set_hw_mode_resp_evt_handler, WMA_RX_SERIALIZER_CTX); if (status != QDF_STATUS_SUCCESS) { WMA_LOGE("Failed to register set hw mode resp event cb"); @@ -5205,8 +5213,8 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg) (struct wmi_pcl_chan_weights *)msg->bodyptr); qdf_mem_free(msg->bodyptr); break; - case SIR_HAL_SOC_SET_HW_MODE: - wma_send_soc_set_hw_mode_cmd(wma_handle, + case SIR_HAL_PDEV_SET_HW_MODE: + wma_send_pdev_set_hw_mode_cmd(wma_handle, (struct sir_hw_mode *)msg->bodyptr); qdf_mem_free(msg->bodyptr); break; @@ -5381,7 +5389,7 @@ QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle, } /** - * wma_send_soc_set_hw_mode_cmd() - Send WMI_SOC_SET_HW_MODE_CMDID to FW + * wma_send_pdev_set_hw_mode_cmd() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW * @wma_handle: WMA handle * @msg: Structure containing the following parameters * @@ -5394,7 +5402,7 @@ QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle, * * Return: Success if the cmd is sent successfully to the firmware */ -QDF_STATUS wma_send_soc_set_hw_mode_cmd(tp_wma_handle wma_handle, +QDF_STATUS wma_send_pdev_set_hw_mode_cmd(tp_wma_handle wma_handle, struct sir_hw_mode *msg) { struct sir_set_hw_mode_resp *param; @@ -5429,7 +5437,7 @@ fail: param->cfgd_hw_mode_index = 0; param->num_vdev_mac_entries = 0; WMA_LOGE("%s: Sending HW mode fail response to LIM", __func__); - wma_send_msg(wma_handle, SIR_HAL_SOC_SET_HW_MODE_RESP, + wma_send_msg(wma_handle, SIR_HAL_PDEV_SET_HW_MODE_RESP, (void *) param, 0); return QDF_STATUS_SUCCESS; } -- cgit v1.2.3 From 5d46f70d35930898eff980844b4a1d8296c5aa51 Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Wed, 27 Apr 2016 12:50:52 +0530 Subject: qcacld-3.0: Replace soc level references of set mac config Replace the WMI command WMI_SOC_SET_DUAL_MAC_CONFIG_CMDID and event WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID with WMI_PDEV_SET_MAC_CONFIG_CMDID and WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID respectively since the former are obsolete. The new WMI commands and events additionally carry the pdev id. Change-Id: I77eab3ead005bbb7f951ce7e077cd661813cb628 CRs-Fixed: 989502 --- core/mac/src/include/sir_params.h | 4 +-- core/mac/src/pe/lim/lim_process_message_queue.c | 2 +- core/mac/src/pe/lim/lim_process_sme_req_messages.c | 4 +-- core/mac/src/sys/legacy/src/utils/src/mac_trace.c | 2 +- core/wma/inc/wma.h | 2 +- core/wma/src/wma_main.c | 33 +++++++++++----------- 6 files changed, 24 insertions(+), 23 deletions(-) diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index cc433c1a65b2..48647af3e71d 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -411,8 +411,8 @@ typedef struct sSirMbMsgP2p { #define SIR_HAL_DEL_PERIODIC_TX_PTRN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 153) /* Messages between 156 to 157 are not used */ -#define SIR_HAL_SOC_DUAL_MAC_CFG_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 154) -#define SIR_HAL_SOC_DUAL_MAC_CFG_RESP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 155) +#define SIR_HAL_PDEV_DUAL_MAC_CFG_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 154) +#define SIR_HAL_PDEV_MAC_CFG_RESP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 155) /* For IBSS peer info related messages */ #define SIR_HAL_IBSS_PEER_INFO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 158) diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index 0bd956256ad6..f3b4251edd8b 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -2056,7 +2056,7 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; break; - case SIR_HAL_SOC_DUAL_MAC_CFG_RESP: + case SIR_HAL_PDEV_MAC_CFG_RESP: lim_process_dual_mac_cfg_resp(mac_ctx, msg->bodyptr); qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index 96a428d83144..be7feaeb14da 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -238,10 +238,10 @@ static QDF_STATUS lim_process_set_dual_mac_cfg_req(tpAniSirGlobal mac, /* Other parameters are not needed for WMA */ cds_message.bodyptr = req_msg; - cds_message.type = SIR_HAL_SOC_DUAL_MAC_CFG_REQ; + cds_message.type = SIR_HAL_PDEV_DUAL_MAC_CFG_REQ; lim_log(mac, LOG1, - FL("Post SIR_HAL_SOC_DUAL_MAC_CFG_REQ to WMA: %x %x"), + FL("Post SIR_HAL_PDEV_DUAL_MAC_CFG_REQ to WMA: %x %x"), req_msg->scan_config, req_msg->fw_mode_config); status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); if (!QDF_IS_STATUS_SUCCESS(status)) { diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c index 1c1252e098ef..99ee02af2fd1 100644 --- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c +++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c @@ -528,7 +528,7 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg) CASE_RETURN_STRING(SIR_HAL_FLUSH_LOG_TO_FW); CASE_RETURN_STRING(SIR_HAL_PDEV_SET_PCL_TO_FW); CASE_RETURN_STRING(SIR_HAL_PDEV_SET_HW_MODE); - CASE_RETURN_STRING(SIR_HAL_SOC_DUAL_MAC_CFG_REQ); + CASE_RETURN_STRING(SIR_HAL_PDEV_DUAL_MAC_CFG_REQ); CASE_RETURN_STRING(WMA_RADAR_DETECTED_IND); CASE_RETURN_STRING(WMA_TIMER_TRAFFIC_STATS_IND); #ifdef WLAN_FEATURE_11W diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index b503fd1ae89f..a7959ae1335b 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1985,7 +1985,7 @@ QDF_STATUS wma_send_pdev_set_hw_mode_cmd(tp_wma_handle wma_handle, struct sir_hw_mode *msg); QDF_STATUS wma_get_scan_id(uint32_t *scan_id); -QDF_STATUS wma_send_soc_set_dual_mac_config(tp_wma_handle wma_handle, +QDF_STATUS wma_send_pdev_set_dual_mac_config(tp_wma_handle wma_handle, struct sir_dual_mac_config *msg); QDF_STATUS wma_send_pdev_set_antenna_mode(tp_wma_handle wma_handle, struct sir_antenna_mode_param *msg); diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 66042548a741..4569cf1daf84 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -2483,25 +2483,25 @@ static int wma_soc_hw_mode_transition_evt_handler(void *handle, } /** - * wma_soc_set_dual_mode_config_resp_evt_handler() - Dual mode evt handler + * wma_pdev_set_dual_mode_config_resp_evt_handler() - Dual mode evt handler * @handle: WMI handle * @event: Event received from FW * @len: Length of the event * * Notifies the host driver of the completion or failure of a - * WMI_SOC_SET_DUAL_MAC_CONFIG_CMDID command. This event would be returned to + * WMI_PDEV_SET_MAC_CONFIG_CMDID command. This event would be returned to * the host driver once the firmware has completed a reconfiguration of the Scan * and FW mode configuration. This changes could include entering or leaving a * dual mac configuration for either scan and/or more permanent firmware mode. * * Return: Success on receiving valid params from FW */ -static int wma_soc_set_dual_mode_config_resp_evt_handler(void *handle, +static int wma_pdev_set_dual_mode_config_resp_evt_handler(void *handle, uint8_t *event, uint32_t len) { - WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID_param_tlvs *param_buf; - wmi_soc_set_dual_mac_config_response_event_fixed_param *wmi_event; + WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID_param_tlvs *param_buf; + wmi_pdev_set_mac_config_response_event_fixed_param *wmi_event; tp_wma_handle wma = (tp_wma_handle) handle; struct sir_dual_mac_config_resp *dual_mac_cfg_resp; @@ -2522,7 +2522,7 @@ static int wma_soc_set_dual_mode_config_resp_evt_handler(void *handle, return QDF_STATUS_E_NULL_VALUE; } - param_buf = (WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID_param_tlvs *) + param_buf = (WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID_param_tlvs *) event; if (!param_buf) { WMA_LOGE("%s: Invalid event", __func__); @@ -2545,7 +2545,7 @@ static int wma_soc_set_dual_mode_config_resp_evt_handler(void *handle, } /* Pass the message to PE */ - wma_send_msg(wma, SIR_HAL_SOC_DUAL_MAC_CFG_RESP, + wma_send_msg(wma, SIR_HAL_PDEV_MAC_CFG_RESP, (void *) dual_mac_cfg_resp, 0); return QDF_STATUS_SUCCESS; @@ -2553,7 +2553,7 @@ static int wma_soc_set_dual_mode_config_resp_evt_handler(void *handle, fail: WMA_LOGE("%s: Sending fail response to LIM", __func__); dual_mac_cfg_resp->status = SET_HW_MODE_STATUS_ECANCELED; - wma_send_msg(wma, SIR_HAL_SOC_DUAL_MAC_CFG_RESP, + wma_send_msg(wma, SIR_HAL_PDEV_MAC_CFG_RESP, (void *) dual_mac_cfg_resp, 0); return QDF_STATUS_E_FAILURE; @@ -2814,8 +2814,8 @@ QDF_STATUS wma_start(void *cds_ctx) /* Initialize the set dual mac configuration event handler */ status = wmi_unified_register_event_handler(wma_handle->wmi_handle, - WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID, - wma_soc_set_dual_mode_config_resp_evt_handler, + WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID, + wma_pdev_set_dual_mode_config_resp_evt_handler, WMA_RX_SERIALIZER_CTX); if (status != QDF_STATUS_SUCCESS) { WMA_LOGE("Failed to register hw mode transition event cb"); @@ -5258,8 +5258,8 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg) (struct sir_dcc_update_ndl *)msg->bodyptr); qdf_mem_free(msg->bodyptr); break; - case SIR_HAL_SOC_DUAL_MAC_CFG_REQ: - wma_send_soc_set_dual_mac_config(wma_handle, + case SIR_HAL_PDEV_DUAL_MAC_CFG_REQ: + wma_send_pdev_set_dual_mac_config(wma_handle, (struct sir_dual_mac_config *)msg->bodyptr); qdf_mem_free(msg->bodyptr); break; @@ -5443,7 +5443,7 @@ fail: } /** - * wma_send_soc_set_dual_mac_config() - Set dual mac config to FW + * wma_send_pdev_set_dual_mac_config() - Set dual mac config to FW * @wma_handle: WMA handle * @msg: Dual MAC config parameters * @@ -5451,7 +5451,7 @@ fail: * * Return: QDF_STATUS. 0 on success. */ -QDF_STATUS wma_send_soc_set_dual_mac_config(tp_wma_handle wma_handle, +QDF_STATUS wma_send_pdev_set_dual_mac_config(tp_wma_handle wma_handle, struct sir_dual_mac_config *msg) { QDF_STATUS status; @@ -5467,10 +5467,11 @@ QDF_STATUS wma_send_soc_set_dual_mac_config(tp_wma_handle wma_handle, return QDF_STATUS_E_NULL_VALUE; } - status = wmi_unified_soc_set_dual_mac_config_cmd(wma_handle->wmi_handle, + status = wmi_unified_pdev_set_dual_mac_config_cmd( + wma_handle->wmi_handle, (struct wmi_dual_mac_config *)msg); if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("%s: Failed to send WMI_SOC_SET_DUAL_MAC_CONFIG_CMDID: %d", + WMA_LOGE("%s: Failed to send WMI_PDEV_SET_DUAL_MAC_CONFIG_CMDID: %d", __func__, status); return status; } -- cgit v1.2.3 From 05fd26715d24955f52cb412d6a162929325e9b3d Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Wed, 27 Apr 2016 12:59:20 +0530 Subject: qcacld-3.0: Replace soc level references of hw mode transition event Replace the obsolete WMI event WMI_SOC_HW_MODE_TRANSITION_EVENTID with WMI_PDEV_HW_MODE_TRANSITION_EVENTID. The new event additionally carries the pdev id. Change-Id: Ic5d04ce63fbc582dbecb9052f490189c83094bb5 CRs-Fixed: 989502 --- core/mac/src/include/sir_params.h | 2 +- core/mac/src/pe/lim/lim_process_message_queue.c | 2 +- core/wma/src/wma_main.c | 37 +++++++++++++++---------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index 48647af3e71d..34d26ca32412 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -589,7 +589,7 @@ typedef struct sSirMbMsgP2p { #define SIR_HAL_START_STOP_LOGGING (SIR_HAL_ITC_MSG_TYPES_BEGIN + 328) #define SIR_HAL_PDEV_SET_HW_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 329) #define SIR_HAL_PDEV_SET_HW_MODE_RESP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 330) -#define SIR_HAL_SOC_HW_MODE_TRANS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 331) +#define SIR_HAL_PDEV_HW_MODE_TRANS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 331) #define SIR_HAL_SET_RSSI_MONITOR_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 333) #define SIR_HAL_SET_IE_INFO (SIR_HAL_ITC_MSG_TYPES_BEGIN + 334) diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index f3b4251edd8b..e2d0e786725d 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -2051,7 +2051,7 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; break; - case SIR_HAL_SOC_HW_MODE_TRANS_IND: + case SIR_HAL_PDEV_HW_MODE_TRANS_IND: lim_process_hw_mode_trans_ind(mac_ctx, msg->bodyptr); qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 4569cf1daf84..d679a6f9b0e1 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -2401,26 +2401,26 @@ fail: } /** - * wma_soc_hw_mode_transition_evt_handler() - HW mode transition evt handler + * wma_pdev_hw_mode_transition_evt_handler() - HW mode transition evt handler * @handle: WMI handle * @event: Event recevied from FW * @len: Length of the event * - * Event handler for WMI_SOC_HW_MODE_TRANSITION_EVENTID that indicates an + * Event handler for WMI_PDEV_HW_MODE_TRANSITION_EVENTID that indicates an * asynchronous hardware mode transition. This event notifies the host driver * that firmware independently changed the hardware mode for some reason, such * as Coex, LFR 3.0, etc * * Return: Success on receiving valid params from FW */ -static int wma_soc_hw_mode_transition_evt_handler(void *handle, +static int wma_pdev_hw_mode_transition_evt_handler(void *handle, uint8_t *event, uint32_t len) { uint32_t i; - WMI_SOC_HW_MODE_TRANSITION_EVENTID_param_tlvs *param_buf; - wmi_soc_hw_mode_transition_event_fixed_param *wmi_event; - wmi_soc_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry; + WMI_PDEV_HW_MODE_TRANSITION_EVENTID_param_tlvs *param_buf; + wmi_pdev_hw_mode_transition_event_fixed_param *wmi_event; + wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry; struct sir_hw_mode_trans_ind *hw_mode_trans_ind; tp_wma_handle wma = (tp_wma_handle) handle; @@ -2430,10 +2430,10 @@ static int wma_soc_hw_mode_transition_evt_handler(void *handle, return QDF_STATUS_E_NULL_VALUE; } - param_buf = (WMI_SOC_HW_MODE_TRANSITION_EVENTID_param_tlvs *) event; + param_buf = (WMI_PDEV_HW_MODE_TRANSITION_EVENTID_param_tlvs *) event; if (!param_buf) { /* This is an async event. So, not sending any event to LIM */ - WMA_LOGE("Invalid WMI_SOC_HW_MODE_TRANSITION_EVENTID event"); + WMA_LOGE("Invalid WMI_PDEV_HW_MODE_TRANSITION_EVENTID event"); return QDF_STATUS_E_FAILURE; } @@ -2453,13 +2453,22 @@ static int wma_soc_hw_mode_transition_evt_handler(void *handle, wmi_event->new_hw_mode_index, wmi_event->num_vdev_mac_entries); vdev_mac_entry = - param_buf->wmi_soc_set_hw_mode_response_vdev_mac_mapping; + param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping; /* Store the vdev-mac map in WMA and prepare to send to HDD */ for (i = 0; i < wmi_event->num_vdev_mac_entries; i++) { - uint32_t vdev_id, mac_id; + uint32_t vdev_id, mac_id, pdev_id; vdev_id = vdev_mac_entry[i].vdev_id; - mac_id = vdev_mac_entry[i].mac_id; + pdev_id = vdev_mac_entry[i].pdev_id; + + if (pdev_id == WMI_PDEV_ID_SOC) { + WMA_LOGE("%s: soc level id received for mac id)", + __func__); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + mac_id = WMA_PDEV_TO_MAC_MAP(vdev_mac_entry[i].pdev_id); WMA_LOGI("%s: vdev_id:%d mac_id:%d", __func__, vdev_id, mac_id); @@ -2476,7 +2485,7 @@ static int wma_soc_hw_mode_transition_evt_handler(void *handle, __func__, wma->old_hw_mode_index, wma->new_hw_mode_index); /* Pass the message to PE */ - wma_send_msg(wma, SIR_HAL_SOC_HW_MODE_TRANS_IND, + wma_send_msg(wma, SIR_HAL_PDEV_HW_MODE_TRANS_IND, (void *) hw_mode_trans_ind, 0); return QDF_STATUS_SUCCESS; @@ -2803,8 +2812,8 @@ QDF_STATUS wma_start(void *cds_ctx) /* Initialize the WMI_SOC_HW_MODE_TRANSITION_EVENTID event handler */ status = wmi_unified_register_event_handler(wma_handle->wmi_handle, - WMI_SOC_HW_MODE_TRANSITION_EVENTID, - wma_soc_hw_mode_transition_evt_handler, + WMI_PDEV_HW_MODE_TRANSITION_EVENTID, + wma_pdev_hw_mode_transition_evt_handler, WMA_RX_SERIALIZER_CTX); if (status != QDF_STATUS_SUCCESS) { WMA_LOGE("Failed to register hw mode transition event cb"); -- cgit v1.2.3 From 3904436d3604b82d14e82ff82c0db859b375d525 Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Wed, 27 Apr 2016 13:02:05 +0530 Subject: qcacld-3.0: Correct the p2p scan parameters when SAP is beaconing Correct the p2p scan's active dwell time, passive dwell time and burst duration when a SAP session is already active. Since the max duration of CTS-to-self is 32ms, the dwell time for p2p scans are calculated in such a way that it does not cross 32ms if SAP is running. This is in line with the existing STA scan parameters when SAP is active. Change-Id: I8089e01025ba07cc18684c277c36bb1694264214 CRs-Fixed: 998555 --- core/wma/src/wma_scan_roam.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index fc08eef58e72..73f6e6fc4884 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -295,20 +295,6 @@ QDF_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle, WMA_3PORT_CONC_SCAN_MAX_BURST_DURATION; break; } - if (wma_is_sap_active(wma_handle)) { - /* Background scan while SoftAP is sending beacons. - * Max duration of CTS2self is 32 ms, which limits - * the dwell time. - */ - cmd->dwell_time_active = - QDF_MIN(scan_req->maxChannelTime, - (WMA_CTS_DURATION_MS_MAX - - WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME)); - cmd->dwell_time_passive = - cmd->dwell_time_active; - cmd->burst_duration = 0; - break; - } if (wma_handle->miracast_value && wma_is_mcc_24G(wma_handle)) { cmd->max_rest_time = @@ -414,6 +400,20 @@ QDF_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle, } } + if (wma_is_sap_active(wma_handle)) { + /* P2P/STA scan while SoftAP is sending beacons. + * Max duration of CTS2self is 32 ms, which limits the + * dwell time. + */ + cmd->dwell_time_active = + QDF_MIN(scan_req->maxChannelTime, + (WMA_CTS_DURATION_MS_MAX - + WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME)); + cmd->dwell_time_passive = + cmd->dwell_time_active; + cmd->burst_duration = 0; + } + cmd->n_probes = (cmd->repeat_probe_time > 0) ? cmd->dwell_time_active / cmd->repeat_probe_time : 0; if (scan_req->channelList.numChannels) { -- cgit v1.2.3 From f37d7121d1e64f26141c8095dbdcb4b58162a599 Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Wed, 27 Apr 2016 13:05:15 +0530 Subject: qcacld-3.0: Fix Kconfig entry for MCC to SCC switch/LFR subnet detection Correct the Kconfig entry that is used for the MCC to SCC switch and LFR subnet detection feature. The Kconfig, instead of having the config name is having the feature name. i.e, instead of having the Kconfig entries as MCC_TO_SCC_SWITCH and LFR_SUBNET_DETECTION, the current entries are FEATURE_WLAN_MCC_TO_SCC_SWITCH and FEATURE_LFR_SUBNET_DETECTION. The make config process will add the CONFIG_ prefix to these Kconfig entries. Change-Id: I57f025f14bed73afeb411ea130ca88b5a4155a60 CRs-Fixed: 1000552 --- Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kconfig b/Kconfig index 39b64ed625c3..51194f09bec4 100644 --- a/Kconfig +++ b/Kconfig @@ -111,11 +111,11 @@ config WLAN_SYNC_TSF bool "Enable QCOM sync multi devices tsf feature" default n -config FEATURE_LFR_SUBNET_DETECTION +config LFR_SUBNET_DETECTION bool "Enable LFR Subnet Change Detection" default n -config FEATURE_WLAN_MCC_TO_SCC_SWITCH +config MCC_TO_SCC_SWITCH bool "Enable MCC to SCC Switch Logic" default n -- cgit v1.2.3 From 97e077d091d34825ebf4d3e9c169c8311edd453f Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Wed, 23 Mar 2016 17:10:31 +0530 Subject: qcacld-3.0: Add ioctl to change concurrency system preference Add support to change the concurrency system preference at run time. The concurrency system preferences of throughput, latency and power can be changed at run time using the IOCTL "setConcSysPref". The policy manager provides the preferred channel list based on this preference value. Usage: iwpriv setConcSysPref Preference - 0 for throughput, 1 for powersave, 2 for latency e.g., iwpriv wlan0 setConcSysPref 1 Change-Id: Ib2b8653688400a0bbad9c9c1b1d630025ae4edcb CRs-Fixed: 993122 --- core/hdd/inc/qc_sap_ioctl.h | 1 + core/hdd/src/wlan_hdd_hostapd.c | 15 ++++++++++++++- core/hdd/src/wlan_hdd_wext.c | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/core/hdd/inc/qc_sap_ioctl.h b/core/hdd/inc/qc_sap_ioctl.h index cede160e85e8..232a1d1c6f6e 100644 --- a/core/hdd/inc/qc_sap_ioctl.h +++ b/core/hdd/inc/qc_sap_ioctl.h @@ -245,6 +245,7 @@ enum { QCSAP_START_FW_PROFILING, QCSAP_CAP_TSF, QCSAP_GET_TSF, + QCSAP_PARAM_CONC_SYSTEM_PREF }; int iw_softap_get_channel_list(struct net_device *dev, diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 597d51278731..ab894f63ab1b 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -2454,7 +2454,16 @@ static __iw_softap_setparam(struct net_device *dev, else ret = -EINVAL; break; - + case QCSAP_PARAM_CONC_SYSTEM_PREF: + hdd_info("New preference: %d", set_value); + if (!((set_value >= CFG_CONC_SYSTEM_PREF_MIN) && + (set_value <= CFG_CONC_SYSTEM_PREF_MAX))) { + hdd_err("Invalid system preference %d", set_value); + return -EINVAL; + } + /* hdd_ctx, hdd_ctx->config are already checked for null */ + hdd_ctx->config->conc_system_pref = set_value; + break; case QCSAP_PARAM_MAX_ASSOC: if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) { hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), @@ -5672,6 +5681,10 @@ static const struct iw_priv_args hostapd_private_args[] = { QCSAP_PARAM_AUTO_CHANNEL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAutoChannel" + }, { + QCSAP_PARAM_CONC_SYSTEM_PREF, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "setConcSysPref" }, /* Sub-cmds DBGLOG specific commands */ { diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 9e3571890bf9..e741530bce03 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -216,6 +216,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { /* Private sub ioctl for starting/stopping the profiling */ #define WE_START_FW_PROFILE 87 #define WE_SET_CHANNEL 88 +#define WE_SET_CONC_SYSTEM_PREF 89 /* Private ioctls and their sub-ioctls */ #define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1) @@ -6274,7 +6275,19 @@ static int __iw_setint_getnone(struct net_device *dev, } break; } + case WE_SET_CONC_SYSTEM_PREF: + { + hdd_info("New preference: %d", set_value); + if (!((set_value >= CFG_CONC_SYSTEM_PREF_MIN) && + (set_value <= CFG_CONC_SYSTEM_PREF_MAX))) { + hdd_err("Invalid system preference %d", set_value); + return -EINVAL; + } + /* hdd_ctx, hdd_ctx->config are already checked for null */ + hdd_ctx->config->conc_system_pref = set_value; + break; + } default: { hddLog(LOGE, "%s: Invalid sub command %d", __func__, @@ -10322,6 +10335,10 @@ static const struct iw_priv_args we_private_args[] = { IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setChanChange" }, + {WE_SET_CONC_SYSTEM_PREF, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "setConcSysPref" }, + {WLAN_PRIV_SET_NONE_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -- cgit v1.2.3 From 7edffe037bf5d7e9879685f4ac55ccf2590b42ad Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Thu, 28 Apr 2016 20:52:14 +0530 Subject: qcacld-3.0: Fix channel number sent in probe response during P2P scans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the channel number sent to fw in probe response during P2P scans. Current channel number being sent to FW is 0. For the probe response frame from Host, as there is no channel frequency added, it ends going on default MAC 0. As in this configuration, FW will do DBS scan for P2P find, 2G is mapped to MAC1. Hence P2P probe response ends up going on wrong channel (STA’s 5G channel). Fix this by using the user space supplied channel in probe response for non beaconing modes and by using the corresponding session's frequency in probe response for the beaconing modes. Change-Id: I3928f8eb2c663b12e40239809e0728d07839317a CRs-Fixed: 1009549 --- core/wma/src/wma_data.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index ec3c88102331..503486497eee 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -2685,11 +2685,15 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, chanfreq = wma_handle->interfaces[vdev_id].scan_info.chan_freq; WMA_LOGI("%s: Preauth frame on channel %d", __func__, chanfreq); } else if (pFc->subType == SIR_MAC_MGMT_PROBE_RSP) { - chanfreq = wma_handle->interfaces[vdev_id].mhz; - WMA_LOGI("%s: Probe response frame on channel %d", __func__, - chanfreq); - WMA_LOGI("%s: Probe response frame on vdev id %d", __func__, - vdev_id); + if ((wma_is_vdev_in_ap_mode(wma_handle, vdev_id)) && + (0 != wma_handle->interfaces[vdev_id].mhz)) + chanfreq = wma_handle->interfaces[vdev_id].mhz; + else + chanfreq = channel_freq; + WMA_LOGI("%s: Probe response frame on channel %d vdev:%d", + __func__, chanfreq, vdev_id); + if (wma_is_vdev_in_ap_mode(wma_handle, vdev_id) && !chanfreq) + WMA_LOGE("%s: AP oper chan is zero", __func__); } else if (pFc->subType == SIR_MAC_MGMT_ACTION) { chanfreq = channel_freq; } else { -- cgit v1.2.3 From cb0521722bf03fc8ebabbb36b037ea3a6d0b76ef Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Fri, 22 Apr 2016 12:19:04 +0530 Subject: qcacld-3.0: Modify set hw mode sequence on channel switch scenarios Modify the set hardware mode command sequence during channel switch in the case of SAP/P2P-GO and STA/P2P-CLI as per the latest FW requirements. This is primarily to accommodate the time take for calibration during hardware mode change which could lead to momentary data stalls. The new sequence is as follows: 1. Send (E)CSA 2. Do vdev restart/vdev up 3. For DBS downgrade: a. PM will initiate HW mode change to DBS right away 4. For single MAC upgrade: a. Opportunistic timer is started, PM will check if MCC upgrade can be done on timer expiry The old sequence is as follows: For MCC upgrade: 1. Send (E)CSA 2. Opportunistic timer is started 3. vdev restart is initiated on the new channel 4. PM will check if MCC upgrade can be done on timer expiry For single mac upgrade: 1. Send (E)CSA 2. PM will initiate HW mode change to DBS right away 3. vdev restart is initiated on the new channel Change-Id: I4bce2ee176cae43b6a46c47216ed7ab47a82a54c CRs-Fixed: 1006992 --- core/cds/inc/cds_concurrency.h | 26 +- core/cds/inc/cds_sched.h | 1 + core/cds/src/cds_concurrency.c | 408 +++++++++++---------- core/hdd/inc/wlan_hdd_main.h | 3 + core/hdd/src/wlan_hdd_assoc.c | 13 + core/hdd/src/wlan_hdd_hostapd.c | 23 +- core/mac/inc/sir_api.h | 12 - core/mac/src/include/sir_params.h | 2 +- core/mac/src/pe/include/lim_session.h | 1 - core/mac/src/pe/lim/lim_process_message_queue.c | 159 +------- core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c | 1 + core/sap/src/sap_api_link_cntl.c | 146 +------- core/sme/inc/csr_api.h | 3 +- core/sme/inc/sme_internal.h | 1 - core/sme/src/common/sme_api.c | 30 -- core/sme/src/csr/csr_api_roam.c | 7 + core/wma/src/wma_dev_if.c | 11 + core/wma/src/wma_mgmt.c | 1 + 18 files changed, 298 insertions(+), 550 deletions(-) diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h index 3dd9786e706a..fd44258ef48f 100644 --- a/core/cds/inc/cds_concurrency.h +++ b/core/cds/inc/cds_concurrency.h @@ -171,6 +171,18 @@ enum cds_con_mode { CDS_MAX_NUM_OF_MODE }; +/** + * enum cds_mac_use - MACs that are used + * @CDS_MAC0: Only MAC0 is used + * @CDS_MAC1: Only MAC1 is used + * @CDS_MAC0_AND_MAC1: Both MAC0 and MAC1 are used + */ +enum cds_mac_use { + CDS_MAC0 = 1, + CDS_MAC1 = 2, + CDS_MAC0_AND_MAC1 = 3 +}; + /** * enum cds_pcl_type - Various types of Preferred channel list (PCL). * @@ -481,8 +493,8 @@ enum cds_two_connection_mode { * @CDS_NOP: No action * @CDS_DBS: switch to DBS mode * @CDS_DBS_DOWNGRADE: switch to DBS mode & downgrade to 1x1 - * @CDS_MCC: switch to MCC/SCC mode - * @CDS_MCC_UPGRADE: switch to MCC/SCC mode & upgrade to 2x2 + * @CDS_SINGLE_MAC: switch to MCC/SCC mode + * @CDS_SINGLE_MAC_UPGRADE: switch to MCC/SCC mode & upgrade to 2x2 * @CDS_MAX_CONC_PRIORITY_MODE: Max place holder * * These are generic IDs that identify the various roles @@ -492,8 +504,8 @@ enum cds_conc_next_action { CDS_NOP = 0, CDS_DBS, CDS_DBS_DOWNGRADE, - CDS_MCC, - CDS_MCC_UPGRADE, + CDS_SINGLE_MAC, + CDS_SINGLE_MAC_UPGRADE, CDS_MAX_CONC_NEXT_ACTION }; @@ -540,8 +552,6 @@ struct cds_conc_connection_info { bool in_use; }; -enum cds_conc_next_action cds_get_pref_hw_mode_for_chan(uint32_t vdev_id, - uint32_t target_channel); bool cds_is_connection_in_progress(void); void cds_dump_concurrency_info(void); void cds_set_concurrency_mode(enum tQDF_ADAPTER_MODE mode); @@ -746,4 +756,8 @@ QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode, uint8_t *pcl_ch, uint32_t *len, uint8_t *weight_list, uint32_t weight_len); QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight); +QDF_STATUS cds_set_hw_mode_on_channel_switch(uint8_t session_id); +void cds_set_do_hw_mode_change_flag(bool flag); +bool cds_is_hw_mode_change_after_vdev_up(void); +void cds_dump_connection_status_info(void); #endif /* __CDS_CONCURRENCY_H */ diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h index 46908e6701f6..4a26355e580b 100644 --- a/core/cds/inc/cds_sched.h +++ b/core/cds/inc/cds_sched.h @@ -291,6 +291,7 @@ typedef struct _cds_context_type { #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t); #endif + bool do_hw_mode_change; } cds_context_type, *p_cds_contextType; /*--------------------------------------------------------------------------- diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index b90592766319..478a27f19083 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -2085,6 +2085,8 @@ static void cds_update_conc_list(uint32_t conn_index, conc_connection_list[conn_index].original_nss = original_nss; conc_connection_list[conn_index].vdev_id = vdev_id; conc_connection_list[conn_index].in_use = in_use; + + cds_dump_connection_status_info(); } /** @@ -2239,6 +2241,7 @@ static void cds_update_hw_mode_conn_info(uint32_t num_vdev_mac_entries, conc_connection_list[conn_index].rx_spatial_stream); } } + cds_dump_connection_status_info(); qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); } @@ -3588,7 +3591,7 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void) return upgrade; } - /* Are both mac's still in use*/ + /* Are both mac's still in use */ for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { cds_debug("index:%d mac:%d in_use:%d chan:%d org_nss:%d", @@ -3599,13 +3602,13 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void) conc_connection_list[conn_index].original_nss); if ((conc_connection_list[conn_index].mac == 0) && conc_connection_list[conn_index].in_use) { - mac |= 1; - if (3 == mac) + mac |= CDS_MAC0; + if (CDS_MAC0_AND_MAC1 == mac) goto done; } else if ((conc_connection_list[conn_index].mac == 1) && conc_connection_list[conn_index].in_use) { - mac |= 2; - if (3 == mac) + mac |= CDS_MAC1; + if (CDS_MAC0_AND_MAC1 == mac) goto done; } } @@ -3618,13 +3621,13 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void) } #endif /* Let's request for single MAC mode */ - upgrade = CDS_MCC; + upgrade = CDS_SINGLE_MAC; /* Is there any connection had an initial connection with 2x2 */ for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { if ((conc_connection_list[conn_index].original_nss == 1) && conc_connection_list[conn_index].in_use) { - upgrade = CDS_MCC_UPGRADE; + upgrade = CDS_SINGLE_MAC_UPGRADE; goto done; } } @@ -3955,6 +3958,8 @@ QDF_STATUS cds_init_policy_mgr(void) return status; } + cds_ctx->do_hw_mode_change = false; + return QDF_STATUS_SUCCESS; } @@ -5976,7 +5981,7 @@ bool cds_wait_for_nss_update(uint8_t action) break; } } - } else if (CDS_MCC == action) { + } else if (CDS_SINGLE_MAC == action) { for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { @@ -6046,7 +6051,7 @@ void cds_nss_update_cb(void *context, uint8_t tx_status, uint8_t vdev_id, conc_connection_list[conn_index].rx_spatial_stream = 1; wait = cds_wait_for_nss_update(next_action); break; - case CDS_MCC: + case CDS_SINGLE_MAC: conc_connection_list[conn_index].tx_spatial_stream = 2; conc_connection_list[conn_index].rx_spatial_stream = 2; wait = cds_wait_for_nss_update(next_action); @@ -6196,8 +6201,8 @@ QDF_STATUS cds_next_actions(uint32_t session_id, */ if ((((CDS_DBS_DOWNGRADE == action) || (CDS_DBS == action)) && hw_mode.dbs_cap) || - (((CDS_MCC_UPGRADE == action) || (CDS_MCC == action)) - && !hw_mode.dbs_cap)) { + (((CDS_SINGLE_MAC_UPGRADE == action) || + (CDS_SINGLE_MAC == action)) && !hw_mode.dbs_cap)) { cds_err("driver is already in %s mode, no further action needed", (hw_mode.dbs_cap) ? "dbs" : "non dbs"); return QDF_STATUS_E_ALREADY; @@ -6222,16 +6227,16 @@ QDF_STATUS cds_next_actions(uint32_t session_id, HW_MODE_AGILE_DFS_NONE, reason); break; - case CDS_MCC_UPGRADE: + case CDS_SINGLE_MAC_UPGRADE: /* * check if we have a beaconing entity that advertised 2x2 * intially. If yes, update the beacon template & notify FW. * Once FW confirms beacon updated, send the HW mode change req */ - status = cds_complete_action(CDS_RX_NSS_2, CDS_MCC, reason, - session_id); + status = cds_complete_action(CDS_RX_NSS_2, CDS_SINGLE_MAC, + reason, session_id); break; - case CDS_MCC: + case CDS_SINGLE_MAC: status = cds_pdev_set_hw_mode(session_id, HW_MODE_SS_2x2, HW_MODE_80_MHZ, @@ -8073,22 +8078,19 @@ QDF_STATUS qdf_init_connection_update(void) } /** - * cds_get_pref_hw_mode_for_chan() - Get preferred hw mode for new channel - * @vdev_id: vdev id whose target channel needs to change - * @target_channel: Target channel + * cds_get_current_pref_hw_mode() - Get the current preferred hw mode * - * Get the preferred hw mode based on the vdev whose channel is going to change + * Get the preferred hw mode based on the current connection combinations * - * Return: No change (CDS_NOP), MCC (CDS_MCC_UPGRADE), DBS (CDS_DBS_DOWNGRADE) + * Return: No change (CDS_NOP), MCC (CDS_SINGLE_MAC_UPGRADE), + * DBS (CDS_DBS_DOWNGRADE) */ -enum cds_conc_next_action cds_get_pref_hw_mode_for_chan(uint32_t vdev_id, - uint32_t target_channel) +enum cds_conc_next_action cds_get_current_pref_hw_mode(void) { uint32_t num_connections; - uint32_t conn_index = 0; - bool found = false; - uint8_t old_band, new_band; -#ifdef QCA_WIFI_3_0_EMU + uint8_t band1, band2, band3; + struct sir_hw_mode_params hw_mode; + QDF_STATUS status; hdd_context_t *hdd_ctx; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); @@ -8096,40 +8098,22 @@ enum cds_conc_next_action cds_get_pref_hw_mode_for_chan(uint32_t vdev_id, cds_err("HDD context is NULL"); return CDS_NOP; } -#endif - while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if ((vdev_id == conc_connection_list[conn_index].vdev_id) && - (conc_connection_list[conn_index].in_use == true)) { - found = true; - break; - } - conn_index++; - } - - if (!found) { - cds_err("vdev_id:%d not available in the conn info", vdev_id); + status = wma_get_current_hw_mode(&hw_mode); + if (!QDF_IS_STATUS_SUCCESS(status)) { + cds_err("wma_get_current_hw_mode failed"); return CDS_NOP; } - old_band = cds_chan_to_band(conc_connection_list[conn_index].chan); - new_band = cds_chan_to_band(target_channel); - num_connections = cds_get_connection_count(); - cds_debug("vdev_id:%d conn_index:%d target_channel:%d chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d", - vdev_id, conn_index, target_channel, + cds_debug("chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d dbs:%d", conc_connection_list[0].chan, conc_connection_list[1].chan, - conc_connection_list[2].chan, - num_connections); + conc_connection_list[2].chan, num_connections, hw_mode.dbs_cap); - /* If the band of the new channel to which the switching is done is same - * as the band of the old channel, then there is no need for a hw mode - * change. The driver would already be in the required hw mode. + /* If the band of operation of both the MACs is the same, + * single MAC is preferred, otherwise DBS is preferred. */ - if (old_band == new_band) - return CDS_NOP; - switch (num_connections) { case 1: #ifdef QCA_WIFI_3_0_EMU @@ -8137,69 +8121,33 @@ enum cds_conc_next_action cds_get_pref_hw_mode_for_chan(uint32_t vdev_id, * request DBS */ if (hdd_ctx->config->enable_m2m_limitation && - CDS_IS_CHANNEL_24GHZ(target_channel)) + CDS_IS_CHANNEL_24GHZ(conc_connection_list[0].chan)) return CDS_DBS_DOWNGRADE; #endif /* The driver would already be in the required hw mode */ return CDS_NOP; case 2: - /* If the band of the new channel, is same as that of the band - * of the channel on the other interface, the driver needs to - * move to single MAC. - * - * If the band of the new channel, is different than that of the - * band of the channel on the other interface, the driver needs - * to move to DBS. - */ - if (conn_index == 0) { - if (new_band == cds_chan_to_band( - conc_connection_list[1].chan)) - return CDS_MCC_UPGRADE; - else if (new_band != cds_chan_to_band( - conc_connection_list[1].chan)) - return CDS_DBS_DOWNGRADE; - } else { - if (new_band == cds_chan_to_band( - conc_connection_list[0].chan)) - return CDS_MCC_UPGRADE; - else if (new_band != cds_chan_to_band( - conc_connection_list[0].chan)) - return CDS_DBS_DOWNGRADE; - } + band1 = cds_chan_to_band(conc_connection_list[0].chan); + band2 = cds_chan_to_band(conc_connection_list[1].chan); + if ((band1 == band2) && (hw_mode.dbs_cap)) + return CDS_SINGLE_MAC_UPGRADE; + else if ((band1 != band2) && (!hw_mode.dbs_cap)) + return CDS_DBS_DOWNGRADE; + else + return CDS_NOP; + case 3: - /* If the band of the new channel, is same as that of the band - * of the channel on the other two interfaces, the driver needs - * to move to single MAC. - * - * If the band of the new channel, is different than that of the - * band of the channel on the other two interfaces, the driver - * needs to move to DBS. - */ - if (conn_index == 0) { - if ((new_band == cds_chan_to_band( - conc_connection_list[1].chan)) && - (new_band == cds_chan_to_band( - conc_connection_list[2].chan))) - return CDS_MCC_UPGRADE; - else - return CDS_DBS_DOWNGRADE; - } else if (conn_index == 1) { - if ((new_band == cds_chan_to_band( - conc_connection_list[0].chan)) && - (new_band == cds_chan_to_band( - conc_connection_list[2].chan))) - return CDS_MCC_UPGRADE; - else - return CDS_DBS_DOWNGRADE; - } else { - if ((new_band == cds_chan_to_band( - conc_connection_list[0].chan)) && - (new_band == cds_chan_to_band( - conc_connection_list[1].chan))) - return CDS_MCC_UPGRADE; - else - return CDS_DBS_DOWNGRADE; - } + band1 = cds_chan_to_band(conc_connection_list[0].chan); + band2 = cds_chan_to_band(conc_connection_list[1].chan); + band3 = cds_chan_to_band(conc_connection_list[2].chan); + if (((band1 == band2) && (band2 == band3)) && + (hw_mode.dbs_cap)) + return CDS_SINGLE_MAC_UPGRADE; + else if (((band1 != band2) || (band2 != band3) || + (band1 != band3)) && (!hw_mode.dbs_cap)) + return CDS_DBS_DOWNGRADE; + else + return CDS_NOP; default: cds_err("unexpected num_connections value %d", num_connections); @@ -8239,87 +8187,6 @@ QDF_STATUS cds_stop_start_opportunistic_timer(void) return status; } -/** - * cds_handle_hw_mode_change_on_csa() - handle hw mode change for csa - * @session_id: SME session id - * @channel: given channel - * @bssid: pointer to bssid - * @dst: pointer to dest buffer - * @src: pointer to src buffer - * @numbytes: number of bytes to copy from src to dst - * - * Use this function to decide whether the hw mode upgrage or downgrade - * is required based on session_id and given channel - * - * Return: QDF_STATUS - */ -QDF_STATUS cds_handle_hw_mode_change_on_csa(uint16_t session_id, - uint8_t channel, uint8_t *bssid, void *dst, void *src, - uint32_t numbytes) -{ - enum cds_conc_next_action action; - QDF_STATUS status; - - /* - * Since all the write to the policy manager table happens in the - * MC thread context and this channel change event is also processed - * in the MC thread context, explicit lock/unlock of qdf_conc_list_lock - * is not done here - */ - action = cds_get_pref_hw_mode_for_chan(session_id, channel); - - if (action == CDS_NOP) { - cds_info("no need for hw mode change"); - /* Proceed with processing csa params. So, not freeing it */ - return QDF_STATUS_SUCCESS; - } - cds_info("session:%d action:%d", session_id, action); - - /* - * 1. Start opportunistic timer - * 2. Do vdev restart on the new channel (by the caller) - * 3. PM will check if MCC upgrade can be done after timer expiry - */ - if (action == CDS_MCC_UPGRADE) { - status = cds_stop_start_opportunistic_timer(); - if (QDF_IS_STATUS_SUCCESS(status)) - cds_info("opportunistic timer for MCC upgrade"); - - /* - * After opportunistic timer is triggered, we can go ahead - * with processing the csa params. So, not freeing the memory - * through 'err' label. - */ - return QDF_STATUS_SUCCESS; - } - - /* - * CDS_DBS_DOWNGRADE: - * 1. PM will initiate HW mode change to DBS rightaway - * 2. Do vdev restart on the new channel (on getting hw mode resp) - */ - status = cds_next_actions(session_id, action, - SIR_UPDATE_REASON_CHANNEL_SWITCH_STA); - if (!QDF_IS_STATUS_SUCCESS(status)) { - cds_err("no set hw mode command was issued"); - /* Proceed with processing csa params. So, not freeing it */ - return QDF_STATUS_SUCCESS; - } else { - if ((NULL == dst) || (NULL == src)) { - cds_err("given buffers are null, can't copy csa param"); - return QDF_STATUS_E_FAILURE; - } - /* Save the csa params to be used after DBS downgrade */ - qdf_mem_copy(dst, src, numbytes); - cds_info("saved csa params for dbs downgrade for bssid %pM", - bssid); - - /* Returning error so that csa params are not processed here */ - status = QDF_STATUS_E_FAILURE; - } - return status; -} - #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH /** * cds_register_sap_restart_channel_switch_cb() - Register callback for SAP @@ -8500,3 +8367,166 @@ QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight) return QDF_STATUS_SUCCESS; } + +/** + * cds_set_hw_mode_on_channel_switch() - Set hw mode after channel switch + * @session_id: Session ID + * + * Sets hw mode after doing a channel switch + * + * Return: QDF_STATUS + */ +QDF_STATUS cds_set_hw_mode_on_channel_switch(uint8_t session_id) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status; + cds_context_type *cds_ctx; + enum cds_conc_next_action action; + hdd_context_t *hdd_ctx; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) { + cds_err("HDD context is NULL"); + return status; + } + + if (!(hdd_ctx->config->policy_manager_enabled && + wma_is_hw_dbs_capable())) { + cds_err("PM/DBS is disabled"); + return status; + } + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + FL("Invalid CDS Context")); + return status; + } + + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); + + action = cds_get_current_pref_hw_mode(); + + if ((action != CDS_DBS_DOWNGRADE) && + (action != CDS_SINGLE_MAC_UPGRADE)) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + FL("Invalid action: %d"), action); + status = QDF_STATUS_SUCCESS; + goto done; + } + + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, + FL("action:%d session id:%d"), + action, session_id); + + /* Opportunistic timer is started, PM will check if MCC upgrade can be + * done on timer expiry. This avoids any possible ping pong effect + * as well. + */ + if (action == CDS_SINGLE_MAC_UPGRADE) { + qdf_status = cds_stop_start_opportunistic_timer(); + if (QDF_IS_STATUS_SUCCESS(qdf_status)) + cds_info("opportunistic timer for MCC upgrade"); + goto done; + } + + /* For DBS, we want to move right away to DBS mode */ + status = cds_next_actions(session_id, action, + SIR_UPDATE_REASON_CHANNEL_SWITCH); + if (!QDF_IS_STATUS_SUCCESS(status)) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + FL("no set hw mode command was issued")); + goto done; + } +done: + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); + /* success must be returned only when a set hw mode was done */ + return status; +} + +/** + * cds_dump_connection_status_info() - Dump the concurrency information + * + * Prints the concurrency information such as tx/rx spatial stream, chainmask, + * etc. + * + * Return: None + */ +void cds_dump_connection_status_info(void) +{ + cds_context_type *cds_ctx; + uint32_t i; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return; + } + + for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { + cds_debug("%d: use:%d vdev:%d tx:%d rx:%d mode:%d mac:%d chan:%d chainmask:%d orig nss:%d bw:%d", + i, conc_connection_list[i].in_use, + conc_connection_list[i].vdev_id, + conc_connection_list[i].tx_spatial_stream, + conc_connection_list[i].rx_spatial_stream, + conc_connection_list[i].mode, + conc_connection_list[i].mac, + conc_connection_list[i].chan, + conc_connection_list[i].chain_mask, + conc_connection_list[i].original_nss, + conc_connection_list[i].bw); + } +} + +/** + * cds_set_do_hw_mode_change_flag() - Set flag to indicate hw mode change + * @flag: Indicate if hw mode change is required or not + * + * Set the flag to indicate whether a hw mode change is required after a + * vdev up or not. Flag value of true indicates that a hw mode change is + * required after vdev up. + * + * Return: None + */ +void cds_set_do_hw_mode_change_flag(bool flag) +{ + cds_context_type *cds_ctx; + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return; + } + + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); + cds_ctx->do_hw_mode_change = flag; + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); + + cds_debug("hw_mode_change_channel:%d", flag); +} + +/** + * cds_is_hw_mode_change_after_vdev_up() - Check if hw mode change is needed + * + * Returns the flag which indicates if a hw mode change is required after + * vdev up. + * + * Return: True if hw mode change is required, false otherwise + */ +bool cds_is_hw_mode_change_after_vdev_up(void) +{ + cds_context_type *cds_ctx; + bool flag; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return INVALID_CHANNEL_ID; + } + + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); + flag = cds_ctx->do_hw_mode_change; + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); + + return flag; +} diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index ab3873a552de..31cb452da246 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1597,6 +1597,9 @@ uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel, uint8_t bw_offset); void hdd_update_config(hdd_context_t *hdd_ctx); +QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *adapter, + struct net_device *dev, uint8_t oper_chan); + #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH QDF_STATUS hdd_register_for_sap_restart_with_channel_switch(void); #else diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 67066ebc1733..ac874632c7bd 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -4296,6 +4296,19 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId, break; } #endif /* FEATURE_WLAN_ESE */ + case eCSR_ROAM_STA_CHANNEL_SWITCH: + hdd_info("channel switch for session:%d to channel:%d", + pAdapter->sessionId, pRoamInfo->chan_info.chan_id); + + status = hdd_chan_change_notify(pAdapter, pAdapter->dev, + pRoamInfo->chan_info.chan_id); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("channel change notification failed"); + + status = cds_set_hw_mode_on_channel_switch(pAdapter->sessionId); + if (QDF_IS_STATUS_ERROR(status)) + hdd_info("set hw mode change not done"); + break; default: break; } diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index ab894f63ab1b..7ed1ebad7315 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -706,7 +706,7 @@ hdd_update_chandef(hdd_adapter_t *hostapd_adapter, * Return: Success on intimating userspace * */ -QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter, +QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *adapter, struct net_device *dev, uint8_t oper_chan) { @@ -716,7 +716,7 @@ QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter, eCsrPhyMode phy_mode; ePhyChanBondState cb_mode; uint32_t freq; - tHalHandle hal = WLAN_HDD_GET_HAL_CTX(hostapd_adapter); + tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter); if (NULL == hal) { hdd_err("hal is NULL"); @@ -725,14 +725,18 @@ QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter, freq = cds_chan_to_freq(oper_chan); - chan = __ieee80211_get_channel(hostapd_adapter->wdev.wiphy, freq); + chan = __ieee80211_get_channel(adapter->wdev.wiphy, freq); if (!chan) { hdd_err("Invalid input frequency for channel conversion"); return QDF_STATUS_E_FAILURE; } - phy_mode = hdd_sap_get_phymode(hostapd_adapter); + if (adapter->device_mode == QDF_SAP_MODE || + adapter->device_mode == QDF_P2P_GO_MODE) + phy_mode = hdd_sap_get_phymode(adapter); + else + phy_mode = sme_get_phy_mode(hal); if (oper_chan <= 14) cb_mode = sme_get_cb_phy_state_from_cb_ini_value( @@ -767,7 +771,7 @@ QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter, if ((phy_mode == eCSR_DOT11_MODE_11ac) || (phy_mode == eCSR_DOT11_MODE_11ac_ONLY)) - hdd_update_chandef(hostapd_adapter, &chandef, cb_mode); + hdd_update_chandef(adapter, &chandef, cb_mode); cfg80211_ch_switch_notify(dev, &chandef); @@ -1099,6 +1103,15 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, cds_dump_concurrency_info(); /* Send SCC/MCC Switching event to IPA */ hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode); + + if (cds_is_hw_mode_change_after_vdev_up()) { + hdd_info("check for possible hw mode change"); + status = cds_set_hw_mode_on_channel_switch( + pHostapdAdapter->sessionId); + if (QDF_IS_STATUS_ERROR(status)) + hdd_info("set hw mode change not done"); + cds_set_do_hw_mode_change_flag(false); + } break; /* Event will be sent after Switch-Case stmt */ case eSAP_STOP_BSS_EVENT: diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 0ffc244385c7..bc35820e756e 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -5629,18 +5629,6 @@ struct csa_offload_params { tSirMacAddr bssId; }; -/** - * struct sir_saved_csa_params - saved csa offload params - * @message_type: Message type - * @length: Message length - * @session_id: Session id - */ -struct sir_saved_csa_params { - uint16_t message_type; - uint16_t length; - uint32_t session_id; -}; - /** * enum obss_ht40_scancmd_type - obss scan command type * @HT40_OBSS_SCAN_PARAM_START: OBSS scan start diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index 34d26ca32412..af4faed28d75 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -637,7 +637,7 @@ typedef struct sSirMbMsgP2p { #define SIR_LIM_SCH_CLEAN_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xB) /* Message from ISR upon Radar Detection */ #define SIR_LIM_RADAR_DETECT_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xC) -#define SIR_LIM_CSA_POST_HW_MODE_CHANGE (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xD) +/* Message id 0xD available */ /* Message from Hal to send out a DEL-TS indication */ #define SIR_LIM_DEL_TS_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xE) diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index 8ff3010ee5a7..c44aecc887aa 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -472,7 +472,6 @@ typedef struct sPESession /* Added to Support BT-AMP */ uint8_t country_info_present; uint8_t nss; bool add_bss_failed; - struct csa_offload_params saved_csa_params; /* To hold OBSS Scan IE Parameters */ struct obss_scanparam obss_ht40_scanparam; /* Supported NSS is intersection of self and peer NSS */ diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index e2d0e786725d..499cee125e68 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -1240,160 +1240,6 @@ static void lim_process_sme_obss_scan_ind(tpAniSirGlobal mac_ctx, return; } -/** - * lim_handle_hw_mode_change_on_csa() - Do HW mode change on CSA for STA mode - * @mac_ctx: Global MAC context - * @msg: Received message - * - * Checks if hw mode change is required for the new channel. - * If MCC upgrade is required, this function will start the opportunistic - * timer and the caller will invoke the other APIs to perform vdev restart on - * the new channel. - * - * If DBS downgrade is required, this function will initiate the hw mode - * change and vdev restart will happen on the new channel after getting hw - * mode response - * - * Return: QDF_STATUS_SUCCESS if processing of csa params (and hence vdev - * restart) needs to happen or if no hw mode change is required, - * QDF_STATUS_E_FAILURE otherwise. - */ -static QDF_STATUS lim_handle_hw_mode_change_on_csa(tpAniSirGlobal mac_ctx, - tpSirMsgQ msg) -{ - tpPESession session_entry; - struct csa_offload_params *csa_params = - (struct csa_offload_params *) (msg->bodyptr); - tpDphHashNode sta_ds = NULL; - uint8_t session_id; - uint16_t aid = 0; - QDF_STATUS status = QDF_STATUS_E_FAILURE; - - lim_log(mac_ctx, LOG1, FL("handle hw mode change for csa")); - - if (!csa_params) { - lim_log(mac_ctx, LOGE, FL("limMsgQ body ptr is NULL")); - /* qdf_mem_free() can handle NULL values */ - goto err; - } - - session_entry = pe_find_session_by_bssid(mac_ctx, - csa_params->bssId, &session_id); - if (!session_entry) { - lim_log(mac_ctx, LOGE, FL("Session does not exist")); - goto err; - } - - sta_ds = dph_lookup_hash_entry(mac_ctx, session_entry->bssId, &aid, - &session_entry->dph.dphHashTable); - - if (!sta_ds) { - lim_log(mac_ctx, LOGE, FL("sta_ds does not exist")); - goto err; - } - - status = cds_handle_hw_mode_change_on_csa(session_entry->smeSessionId, - csa_params->channel, csa_params->bssId, - &session_entry->saved_csa_params, csa_params, - sizeof(session_entry->saved_csa_params)); - - if (QDF_IS_STATUS_SUCCESS(status)) - return status; - -err: - qdf_mem_free(csa_params); - return status; -} - -/** - * lim_handle_hw_mode_change_on_csa_event() - Handle hw mode change on csa - * @mac_ctx: Pointer to the Global Mac Context - * @msg: Received message - * - * Checks if a hw mode change is required for the received csa event. Processes - * csa params and do vdev restart immediately if the there is no need for a hw - * mode change or if MCC upgrade is required - * - * Return: None - */ -static void lim_handle_hw_mode_change_on_csa_event(tpAniSirGlobal mac_ctx, - tpSirMsgQ msg) -{ - QDF_STATUS qdf_status; - - lim_log(mac_ctx, LOG1, FL("lim received csa offload event")); - if (mac_ctx->policy_manager_enabled && - wma_is_hw_dbs_capable() == true) { - /* Check if a hw mode change is required */ - qdf_status = lim_handle_hw_mode_change_on_csa(mac_ctx, - msg); - /* Process csa params and do vdev restart immediately if - * there is no need for a hw mode change or if MCC upgrade is - * required. - */ - if (QDF_IS_STATUS_SUCCESS(qdf_status)) - lim_handle_csa_offload_msg(mac_ctx, msg); - } else { - lim_handle_csa_offload_msg(mac_ctx, msg); - } -} - -/** - * lim_handle_csa_event_post_dbs_downgrade() - Process csa event post dbs - * downgrade - * @mac_ctx: Pointer to the Global Mac Context - * @msg: Received message - * - * Process the csa event to do vdev restart on the new channel after the dbs - * downgrade. If there was a DBS downgrade as part of the event - * WMA_CSA_OFFLOAD_EVENT, SIR_LIM_CSA_POST_HW_MODE_CHANGE will be received after - * receiving the set hw mode response, where this processing will happen. - * - * Return: None - */ -static void lim_handle_csa_event_post_dbs_downgrade(tpAniSirGlobal mac_ctx, - tpSirMsgQ msg) -{ - tSirMsgQ csa_msg; - tpPESession session_entry; - - struct sir_saved_csa_params *buf = - (struct sir_saved_csa_params *)msg->bodyptr; - - /* Null check for 'msg' already done before coming here in the caller */ - - session_entry = pe_find_session_by_sme_session_id(mac_ctx, - buf->session_id); - if (!session_entry) { - lim_log(mac_ctx, LOGE, FL("Invalid session id:%d"), - buf->session_id); - return; - } - - lim_log(mac_ctx, LOG1, - FL("received csa offload event post hw change for %pM"), - session_entry->saved_csa_params.bssId); - - csa_msg.bodyptr = qdf_mem_malloc( - sizeof(struct csa_offload_params)); - if (!csa_msg.bodyptr) { - lim_log(mac_ctx, LOGE, FL("malloc failed for csa msg")); - goto clean_msg_body; - } - - qdf_mem_copy((void *)csa_msg.bodyptr, - (void *)&session_entry->saved_csa_params, - sizeof(struct csa_offload_params)); - /* If there was a DBS downgrade as part of the event - * WMA_CSA_OFFLOAD_EVENT, SIR_LIM_CSA_POST_HW_MODE_CHANGE will - * be received after receiving the set hw mode response. - */ - lim_handle_csa_offload_msg(mac_ctx, &csa_msg); -clean_msg_body: - if (msg->bodyptr) - qdf_mem_free(msg->bodyptr); -} - /** * lim_process_messages() - Process messages from upper layers. * @@ -1853,10 +1699,7 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) lim_handle_delete_bss_rsp(mac_ctx, msg); break; case WMA_CSA_OFFLOAD_EVENT: - lim_handle_hw_mode_change_on_csa_event(mac_ctx, msg); - break; - case SIR_LIM_CSA_POST_HW_MODE_CHANGE: - lim_handle_csa_event_post_dbs_downgrade(mac_ctx, msg); + lim_handle_csa_offload_msg(mac_ctx, msg); break; case WMA_SET_BSSKEY_RSP: case WMA_SET_STA_BCASTKEY_RSP: diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c index 4659053ecb90..c25da0223394 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c @@ -3207,6 +3207,7 @@ void lim_process_switch_channel_rsp(tpAniSirGlobal pMac, void *body) * the policy manager connection table needs to be updated. */ cds_update_connection_info(psessionEntry->smeSessionId); + cds_set_do_hw_mode_change_flag(true); } break; default: diff --git a/core/sap/src/sap_api_link_cntl.c b/core/sap/src/sap_api_link_cntl.c index 78b71b4b0c3e..7d76f9cd3cf1 100644 --- a/core/sap/src/sap_api_link_cntl.c +++ b/core/sap/src/sap_api_link_cntl.c @@ -506,128 +506,6 @@ wlansap_roam_process_ch_change_success(tpAniSirGlobal mac_ctx, *ret_status = QDF_STATUS_E_FAILURE; } -/** - * wlansap_set_hw_mode_on_channel_switch() - Set hw mode before channel switch - * @sap_ctx: Global SAP context - * @target_channel: Target channel - * - * Sets hw mode, if needed, before doing a channel switch - * - * Return: None - */ -static QDF_STATUS wlansap_set_hw_mode_on_channel_switch(tpAniSirGlobal mac_ctx, - ptSapContext sap_ctx, - uint32_t target_channel) -{ - QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status; - cds_context_type *cds_ctx; - enum cds_conc_next_action action; - - cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); - if (!cds_ctx) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("Invalid CDS Context")); - return status; - } - - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); - - action = cds_get_pref_hw_mode_for_chan(sap_ctx->sessionId, - target_channel); - - if ((action != CDS_DBS_DOWNGRADE) && (action != CDS_MCC_UPGRADE)) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("Invalid action: %d"), action); - goto done; - } - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - FL("action:%d session id:%d"), - action, sap_ctx->sessionId); - - /* For MCC, opportunistic timer will be trigerred. We do not - * want to do hw mode change here to avoid the ping pong effect. - * e.g., If a new connection is immediately coming up, we could be - * moving in and out of MCC. The timer after DBS_OPPORTUNISTIC_TIME - * seconds will check if the driver can move to MCC or not. - * - * 1. Start opportunistic timer - * 2. Do vdev restart on the new channel - * 3. PM will check if MCC upgrade can be done after timer expiry - */ - if (action == CDS_MCC_UPGRADE) { - qdf_mc_timer_stop(&cds_ctx->dbs_opportunistic_timer); - qdf_status = qdf_mc_timer_start( - &cds_ctx->dbs_opportunistic_timer, - DBS_OPPORTUNISTIC_TIME * - 1000); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("Failed to start dbs opportunistic timer")); - else - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - FL("opportunistic timer for MCC upgrade")); - goto done; - } - - /* For DBS, we want to move right away to DBS mode. Else, we could - * be doing MCC momentarily. - * - * 1. PM will initiate HW mode change to DBS rightaway - * 2. Do vdev restart on the new channel - */ - status = cds_next_actions(sap_ctx->sessionId, action, - SIR_UPDATE_REASON_CHANNEL_SWITCH); - if (!QDF_IS_STATUS_SUCCESS(status)) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("no set hw mode command was issued")); - goto done; - } -done: - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); - /* success must be returned only when a set hw mode was done */ - return status; -} - -/** - * wlansap_update_hw_mode() - Set the hw mode for the new channel switch - * @hal: HAL pointer - * @sap_ctx: SAP context - * - * Sets the hw mode, if needed, for the driver based on the new channel - * to which the vdev is going to switch to - * - * Return: None - */ -void wlansap_update_hw_mode(tHalHandle hal, ptSapContext sap_ctx) -{ - QDF_STATUS status = QDF_STATUS_E_FAILURE; - tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); - tCsrRoamInfo roam_info = {0}; - - if (mac_ctx->policy_manager_enabled && - wma_is_hw_dbs_capable() == true) { - status = wlansap_set_hw_mode_on_channel_switch(mac_ctx, sap_ctx, - mac_ctx->sap.SapDfsInfo.target_channel); - } - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - FL("status:%d"), status); - - /* - * If no set hw mode was done, proceed as before by doing set channel. - * If set hw mode was done, perform the following in the callback so - * that the set channel operations are done after the driver moves to - * the required hw mode. - */ - if (!QDF_IS_STATUS_SUCCESS(status)) { - csr_roam_call_callback(mac_ctx, sap_ctx->sessionId, - &roam_info, 0, - eCSR_ROAM_STATUS_UPDATE_HW_MODE, - eCSR_ROAM_RESULT_UPDATE_HW_MODE); - } -} - /** * wlansap_roam_process_dfs_chansw_update() - handles the case for * eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS in wlansap_roam_callback() @@ -1097,10 +975,6 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId, QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, FL("Received Chan Sw Update Notification")); break; - case eCSR_ROAM_STATUS_UPDATE_HW_MODE: - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("Received HW mode update notification")); - break; case eCSR_ROAM_SET_CHANNEL_RSP: QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, FL("Received set channel response")); @@ -1316,26 +1190,8 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId, &qdf_ret_status); break; case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS: - /* eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS indicates the - * completion of sending (E)CSA IEs. After these IEs are sent, - * in eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS state, check - * for DBS downgrade/MCC upgrade is done. - * (1) From this state - * eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS, on MCC upgrade, - * transition immediately happens to the state - * eCSR_ROAM_RESULT_UPDATE_HW_MODE, where the vdev restart - * happens internally. - * (2) From this state, - * eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS, on DBS downgrade, - * transition happens to the state - * eCSR_ROAM_RESULT_UPDATE_HW_MODE to do vdev restart only after - * SME received the set HW mode response. - */ - wlansap_update_hw_mode(hal, sap_ctx); - break; - case eCSR_ROAM_RESULT_UPDATE_HW_MODE: wlansap_roam_process_dfs_chansw_update(hal, sap_ctx, - &qdf_ret_status); + &qdf_ret_status); break; case eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS: wlansap_roam_process_ch_change_success(mac_ctx, sap_ctx, diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index ae0c98749e4f..dd566f26ed17 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -492,9 +492,9 @@ typedef enum { /* Channel sw update notification */ eCSR_ROAM_DFS_CHAN_SW_NOTIFY, eCSR_ROAM_EXT_CHG_CHNL_IND, - eCSR_ROAM_STATUS_UPDATE_HW_MODE, eCSR_ROAM_DISABLE_QUEUES, eCSR_ROAM_ENABLE_QUEUES, + eCSR_ROAM_STA_CHANNEL_SWITCH, } eRoamCmdStatus; /* comment inside indicates what roaming callback gets */ @@ -591,7 +591,6 @@ typedef enum { eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE, eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS, eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND, - eCSR_ROAM_RESULT_UPDATE_HW_MODE, } eCsrRoamResult; /*---------------------------------------------------------------------------- diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index f681208043f3..674e8b597846 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -234,7 +234,6 @@ typedef struct tagSmeStruct { ocb_callback dcc_stats_event_callback; sme_set_thermal_level_callback set_thermal_level_cb; void *saved_scan_cmd; - struct csa_offload_params saved_csa_params; } tSmeStruct, *tpSmeStruct; #endif /* #if !defined( __SMEINTERNAL_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 49c7d685b708..06ba472c1d42 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -155,8 +155,6 @@ static QDF_STATUS sme_process_set_hw_mode_resp(tpAniSirGlobal mac, uint8_t *msg) struct sir_set_hw_mode_resp *param; enum sir_conn_update_reason reason; tSmeCmd *saved_cmd; - tCsrRoamInfo roam_info = {0}; - QDF_STATUS status; sms_log(mac, LOG1, FL("%s"), __func__); param = (struct sir_set_hw_mode_resp *)msg; @@ -251,34 +249,6 @@ static QDF_STATUS sme_process_set_hw_mode_resp(tpAniSirGlobal mac, uint8_t *msg) saved_cmd = NULL; mac->sme.saved_scan_cmd = NULL; } - } else if (reason == SIR_UPDATE_REASON_CHANNEL_SWITCH) { - csr_roam_call_callback(mac, - command->u.set_hw_mode_cmd.session_id, - &roam_info, 0, - eCSR_ROAM_STATUS_UPDATE_HW_MODE, - eCSR_ROAM_RESULT_UPDATE_HW_MODE); - } else if (reason == SIR_UPDATE_REASON_CHANNEL_SWITCH_STA) { - struct sir_saved_csa_params *msg; - - sms_log(mac, LOG1, FL("process channel switch sta")); - msg = qdf_mem_malloc(sizeof(*msg)); - if (!msg) { - sms_log(mac, LOGE, - FL("memory alloc fail for csa ")); - goto end; - } - - msg->message_type = SIR_LIM_CSA_POST_HW_MODE_CHANGE; - msg->length = sizeof(*msg); - msg->session_id = command->u.set_hw_mode_cmd.session_id; - - status = cds_send_mb_message_to_mac(msg); - if (!QDF_IS_STATUS_SUCCESS(status)) - sms_log(mac, LOGE, - FL("failed to process csa params")); - else - sms_log(mac, LOG1, - FL("csa after hw mode change")); } end: diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index ee72ae9a44c9..342ff292a210 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -10250,6 +10250,7 @@ csr_roam_chk_lnk_swt_ch_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr) uint32_t sessionId = CSR_SESSION_ID_INVALID; QDF_STATUS status; tpSirSmeSwitchChannelInd pSwitchChnInd; + tCsrRoamInfo roamInfo; /* in case of STA, the SWITCH_CHANNEL originates from its AP */ sms_log(mac_ctx, LOGW, FL("eWNI_SME_SWITCH_CHL_IND from SME")); @@ -10272,6 +10273,12 @@ csr_roam_chk_lnk_swt_ch_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr) session->pConnectBssDesc->channelId = (uint8_t) pSwitchChnInd->newChannelId; } + + qdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.chan_info.chan_id = pSwitchChnInd->newChannelId; + status = csr_roam_call_callback(mac_ctx, sessionId, + &roamInfo, 0, eCSR_ROAM_STA_CHANNEL_SWITCH, + eCSR_ROAM_RESULT_NONE); } } diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index efdde8dd5b5c..6cc6a04bf1d3 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -73,6 +73,8 @@ #include #include +#include "cds_concurrency.h" + /** * wma_find_vdev_by_addr() - find vdev_id from mac address * @wma: wma handle @@ -790,6 +792,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, tpAniSirGlobal mac_ctx = cds_get_context(QDF_MODULE_ID_PE); if (NULL == mac_ctx) { WMA_LOGE("%s: Failed to get mac_ctx", __func__); + cds_set_do_hw_mode_change_flag(false); return -EINVAL; } #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ @@ -798,12 +801,14 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) cmd_param_info; if (!param_buf) { WMA_LOGE("Invalid start response event buffer"); + cds_set_do_hw_mode_change_flag(false); return -EINVAL; } resp_event = param_buf->fixed_param; if (!resp_event) { WMA_LOGE("Invalid start response event buffer"); + cds_set_do_hw_mode_change_flag(false); return -EINVAL; } @@ -857,6 +862,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, wma->interfaces[resp_event->vdev_id].bssid, ¶m) != QDF_STATUS_SUCCESS) { WMA_LOGE("%s : failed to send vdev up", __func__); + cds_set_do_hw_mode_change_flag(false); return -EEXIST; } qdf_atomic_set(&wma->interfaces[resp_event->vdev_id]. @@ -871,6 +877,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, if (!req_msg) { WMA_LOGE("%s: Failed to lookup request message for vdev %d", __func__, resp_event->vdev_id); + cds_set_do_hw_mode_change_flag(false); return -EINVAL; } @@ -889,6 +896,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, if (!params) { WMA_LOGE("%s: channel switch params is NULL for vdev %d", __func__, resp_event->vdev_id); + cds_set_do_hw_mode_change_flag(false); return -EINVAL; } @@ -913,6 +921,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, __func__, resp_event->vdev_id); wma->interfaces[resp_event->vdev_id].vdev_up = false; + cds_set_do_hw_mode_change_flag(false); } else { wma->interfaces[resp_event->vdev_id].vdev_up = true; @@ -932,6 +941,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, iface->bssid, ¶m) != QDF_STATUS_SUCCESS) { WMA_LOGE(FL("failed to send vdev up")); + cds_set_do_hw_mode_change_flag(false); return -EEXIST; } iface->vdev_up = true; @@ -3802,6 +3812,7 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) ¶m) != QDF_STATUS_SUCCESS) { WMA_LOGP("%s: Failed to send vdev up cmd: vdev %d bssid %pM", __func__, params->smesessionId, params->bssId); + cds_set_do_hw_mode_change_flag(false); status = QDF_STATUS_E_FAILURE; } else { wma->interfaces[params->smesessionId].vdev_up = true; diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index e7a0ca05d3ab..60ac1ba4454a 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -2343,6 +2343,7 @@ void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info) ¶m); if (QDF_IS_STATUS_ERROR(status)) { WMA_LOGE("%s : failed to send vdev up", __func__); + cds_set_do_hw_mode_change_flag(false); return; } wma->interfaces[vdev_id].vdev_up = true; -- cgit v1.2.3 From 9bc0cad386ff4d702411b40a7d484c3cf725b84e Mon Sep 17 00:00:00 2001 From: Amar Singhal Date: Fri, 22 Apr 2016 10:32:41 -0700 Subject: qcacld-3.0: Correct regdomain definition for Japan Per regulatory data, the regdomain pair mapping for CTRY_JAPAN14 is MKK5_MKKA2 and not MKK5_MKKA. Therefore correct the same. Change-Id: Ica36574c2111753e4e23e2cd30d438a4613eefd8 CRs-Fixed: 1000056 --- core/cds/src/cds_regdomain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/cds/src/cds_regdomain.c b/core/cds/src/cds_regdomain.c index a7e8e3ec1e41..11e62813ec28 100644 --- a/core/cds/src/cds_regdomain.c +++ b/core/cds/src/cds_regdomain.c @@ -379,7 +379,7 @@ static const struct country_code_to_reg_dmn g_all_countries[] = { {CTRY_WALLIS_AND_FUTUNA, ETSI1_WORLD, "WF" "WALLIS"}, {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN"}, {CTRY_ZIMBABWE, ETSI1_WORLD, "ZW", "ZIMBABWE"}, - {CTRY_JAPAN14, MKK5_MKKA, "JP", "JAPAN"} + {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN"} }; static const struct reg_dmn g_reg_dmns[] = { -- cgit v1.2.3 From bf3280a42a137d195740e547381c066631cd6018 Mon Sep 17 00:00:00 2001 From: Sandeep puligilla Date: Mon, 25 Apr 2016 18:43:51 -0700 Subject: qcacld-3.0: Save scan results in scan timeout failure Scan results are not updated to NL when scan times out. Intermediate SME scan cache entries are dropped at LIM in failure scenario. Save scan results in SME global cache before sending the abort indication to upper layers in scan timeout scenario. Change-Id: I0f42f4264bfe275b38027998b23a061b9cea135f CRs-Fixed: 997587 --- core/sme/src/csr/csr_api_scan.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index 87ceec5baa58..dd76c63f3ebc 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -7244,6 +7244,8 @@ void csr_scan_active_list_timeout_handle(void *userData) FL(" Failed to post message to LIM")); qdf_mem_free(msg); } + csr_save_scan_results(mac_ctx, scan_cmd->u.scanCmd.reason, + scan_cmd->sessionId); csr_release_scan_command(mac_ctx, scan_cmd, eCSR_SCAN_FAILURE); return; } -- cgit v1.2.3 From eca12f2624e6b189a8afabb2b0723477d04c7087 Mon Sep 17 00:00:00 2001 From: Sandeep Puligilla Date: Thu, 28 Apr 2016 11:40:26 -0700 Subject: qcacld-3.1: Fix NULL pointer dereference API is trying to access the wmi descriptor even though it is failed to allocate. - Add a NULL pointer verification check before accessing the wmi descriptor. - Return failure to UMAC if the wmi failed to provide the wmi descriptor. Change-Id: I1ca8670c43e795d874d4e57bca8577b5fb90468a CRs-Fixed: 1009636 --- core/wma/src/wma_data.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 503486497eee..b49200cbc46a 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -2718,14 +2718,19 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, mgmt_param.tx_complete_cb = tx_frm_download_comp_cb; mgmt_param.tx_ota_post_proc_cb = tx_frm_ota_comp_cb; mgmt_param.chanfreq = chanfreq; - mgmt_param.wmi_desc = wmi_desc_get(wma_handle); mgmt_param.pdata = pData; mgmt_param.qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); - - status = wmi_mgmt_unified_cmd_send(wma_handle->wmi_handle, - &mgmt_param); - if (status) - wmi_desc_put(wma_handle, mgmt_param.wmi_desc); + mgmt_param.wmi_desc = wmi_desc_get(wma_handle); + if (NULL == mgmt_param.wmi_desc) { + WMA_LOGE(FL("Failed to get wmi descriptor")); + status = QDF_STATUS_E_FAILURE; + } else { + status = wmi_mgmt_unified_cmd_send( + wma_handle->wmi_handle, + &mgmt_param); + if (status) + wmi_desc_put(wma_handle, mgmt_param.wmi_desc); + } } else { /* Hand over the Tx Mgmt frame to TxRx */ status = ol_txrx_mgmt_send_ext(txrx_vdev, tx_frame, -- cgit v1.2.3 From 4ef5fe00a42d3e2526a2bab2d671aa395c6dfb6e Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Wed, 27 Apr 2016 12:21:24 +0530 Subject: qcacld-3.0: Add diag event for TDLS teardown qcacld-2.0 to qcacld-3.0 propagation Add diag event for TDLS teardown. Event contains reason for teardown and peer mac address. Change-Id: Ib04deac6cf7d61fae1a7bb0d0fb8f4dc652b3217 CRs-Fixed: 934448 --- core/hdd/inc/wlan_hdd_tdls.h | 33 ++++++++++++++++++++++ core/hdd/src/wlan_hdd_assoc.c | 8 ++++++ core/hdd/src/wlan_hdd_tdls.c | 33 ++++++++++++++++++++++ .../utils/host_diag_log/inc/host_diag_core_event.h | 12 ++++++++ .../utils/host_diag_log/inc/host_diag_event_defs.h | 3 +- 5 files changed, 88 insertions(+), 1 deletion(-) diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h index 8a4cd45e7f89..4e12836d3189 100644 --- a/core/hdd/inc/wlan_hdd_tdls.h +++ b/core/hdd/inc/wlan_hdd_tdls.h @@ -160,6 +160,30 @@ typedef enum eTDLSLinkStatus { eTDLS_LINK_TEARING, } tTDLSLinkStatus; +/** + * enum tdls_teardown_reason - Reason for TDLS teardown + * @eTDLS_TEARDOWN_EXT_CTRL: Reason ext ctrl. + * @eTDLS_TEARDOWN_CONCURRENCY: Reason concurrency. + * @eTDLS_TEARDOWN_RSSI_THRESHOLD: Reason rssi threshold. + * @eTDLS_TEARDOWN_TXRX_THRESHOLD: Reason txrx threshold. + * @eTDLS_TEARDOWN_BTCOEX: Reason BTCOEX. + * @eTDLS_TEARDOWN_SCAN: Reason scan. + * @eTDLS_TEARDOWN_BSS_DISCONNECT: Reason bss disconnected. + * @eTDLS_TEARDOWN_ANTENNA_SWITCH: Disconnected due to antenna switch + * + * Reason to indicate in diag event of tdls teardown. + */ +enum tdls_teardown_reason { + eTDLS_TEARDOWN_EXT_CTRL, + eTDLS_TEARDOWN_CONCURRENCY, + eTDLS_TEARDOWN_RSSI_THRESHOLD, + eTDLS_TEARDOWN_TXRX_THRESHOLD, + eTDLS_TEARDOWN_BTCOEX, + eTDLS_TEARDOWN_SCAN, + eTDLS_TEARDOWN_BSS_DISCONNECT, + eTDLS_TEARDOWN_ANTENNA_SWITCH, +}; + /** * enum tTDLSLinkReason - tdls link reason * @@ -625,4 +649,13 @@ static inline void wlan_hdd_tdls_exit(hdd_adapter_t *adapter) static inline void hdd_tdls_pre_init(hdd_context_t *hdd_ctx) { } #endif /* End of FEATURE_WLAN_TDLS */ +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void hdd_send_wlan_tdls_teardown_event(uint32_t reason, + uint8_t *peer_mac); +#else +static inline +void hdd_send_wlan_tdls_teardown_event(uint32_t reason, + uint8_t *peer_mac) {} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + #endif /* __HDD_TDLS_H */ diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index ac874632c7bd..ecca88729eaa 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -3209,6 +3209,8 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter, pRoamInfo->peerMac.bytes, true); wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer, pRoamInfo->reasonCode); + hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_BSS_DISCONNECT, + curr_peer->peerMac); status = QDF_STATUS_SUCCESS; break; } @@ -3388,6 +3390,9 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter, wlan_hdd_tdls_indicate_teardown (pHddTdlsCtx->pAdapter, curr_peer, reason); + hdd_send_wlan_tdls_teardown_event( + eTDLS_TEARDOWN_BSS_DISCONNECT, + curr_peer->peerMac); } else { hddLog(LOGE, FL @@ -3436,6 +3441,9 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter, wlan_hdd_tdls_indicate_teardown (pHddTdlsCtx->pAdapter, curr_peer, reason); + hdd_send_wlan_tdls_teardown_event( + eTDLS_TEARDOWN_BSS_DISCONNECT, + curr_peer->peerMac); } else { hddLog(LOGE, FL diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index e0978c31b2e1..de431b9a7f1a 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -85,6 +85,31 @@ static void wlan_hdd_tdls_determine_channel_opclass(hdd_context_t *hddctx, } } +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** + * hdd_send_wlan_tdls_teardown_event()- send TDLS teardown event + * @reason: reason for tear down. + * @peer_mac: peer mac + * + * This Function sends TDLS teardown diag event + * + * Return: void. + */ +void hdd_send_wlan_tdls_teardown_event(uint32_t reason, + uint8_t *peer_mac) +{ + WLAN_HOST_DIAG_EVENT_DEF(tdls_tear_down, + struct host_event_tdls_teardown); + qdf_mem_zero(&tdls_tear_down, + sizeof(tdls_tear_down)); + + tdls_tear_down.reason = reason; + qdf_mem_copy(tdls_tear_down.peer_mac, peer_mac, MAC_ADDR_LEN); + WLAN_HOST_DIAG_EVENT_REPORT(&tdls_tear_down, + EVENT_WLAN_TDLS_TEARDOWN); +} +#endif + /** * wlan_hdd_tdls_hash_key() - calculate tdls hash key given mac address * @mac: mac address @@ -168,6 +193,8 @@ void wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *hddctx) curr_peer->pHddTdlsCtx->pAdapter, curr_peer, eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_CONCURRENCY, + curr_peer->peerMac); } } @@ -2764,6 +2791,9 @@ int wlan_hdd_tdls_scan_callback(hdd_adapter_t *pAdapter, struct wiphy *wiphy, (connectedPeerList[i]->pHddTdlsCtx-> pAdapter, connectedPeerList[i], eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + hdd_send_wlan_tdls_teardown_event( + eTDLS_TEARDOWN_SCAN, + connectedPeerList[i]->peerMac); } } /* schedule scan */ @@ -4117,6 +4147,9 @@ int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, } else { wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer, eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + hdd_send_wlan_tdls_teardown_event( + eTDLS_TEARDOWN_EXT_CTRL, + pTdlsPeer->peerMac); } if (0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, false)) { QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, diff --git a/core/utils/host_diag_log/inc/host_diag_core_event.h b/core/utils/host_diag_log/inc/host_diag_core_event.h index 0c8d963e7389..135ded970a9b 100644 --- a/core/utils/host_diag_log/inc/host_diag_core_event.h +++ b/core/utils/host_diag_log/inc/host_diag_core_event.h @@ -299,6 +299,18 @@ struct host_event_wlan_log_complete { uint32_t reserved; }; +/** + * struct host_event_tdls_teardown - tdls teardown diag event + * @reason: reason for tear down + * @peer_mac: peer mac + * + * This structure contains tdls teardown diag event info + */ +struct host_event_tdls_teardown { + uint32_t reason; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; +}; + /*------------------------------------------------------------------------- Function declarations and documenation ------------------------------------------------------------------------*/ diff --git a/core/utils/host_diag_log/inc/host_diag_event_defs.h b/core/utils/host_diag_log/inc/host_diag_event_defs.h index ca250c592db2..6027f88dabd5 100644 --- a/core/utils/host_diag_log/inc/host_diag_event_defs.h +++ b/core/utils/host_diag_log/inc/host_diag_event_defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -54,6 +54,7 @@ typedef enum { EVENT_WLAN_WAKE_LOCK = 0xAA2, /* 96 bytes payload */ EVENT_WLAN_BEACON_RECEIVED = 0xAA6, /* FW event: 2726 */ EVENT_WLAN_LOG_COMPLETE = 0xAA7, /* 16 bytes payload */ + EVENT_WLAN_TDLS_TEARDOWN = 0xAB5, EVENT_MAX_ID = 0x0FFF } event_id_enum_type; -- cgit v1.2.3 From 74bcb0ab41e6a70a626e89c9ff5efd2fd523cb16 Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Wed, 27 Apr 2016 12:30:48 +0530 Subject: qcacld-3.0: Add diag event for TDLS enable link qcacld-2.0 to qcacld-3.0 propagation. Add diag event for EVENT_WLAN_TDLS_ENABLE_LINK. This event contains below info: - peer mac address - Does peer supports off channel - Is off channel configured - Is off channel established Change-Id: Ib491d8ac1d8a7850a050bf14a60b6eb08ab94078 CRs-Fixed: 934449 --- core/hdd/inc/wlan_hdd_tdls.h | 10 ++++++ core/hdd/src/wlan_hdd_tdls.c | 39 +++++++++++++++++++++- .../utils/host_diag_log/inc/host_diag_core_event.h | 16 +++++++++ .../utils/host_diag_log/inc/host_diag_event_defs.h | 1 + 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h index 4e12836d3189..e19af31b9e48 100644 --- a/core/hdd/inc/wlan_hdd_tdls.h +++ b/core/hdd/inc/wlan_hdd_tdls.h @@ -652,10 +652,20 @@ static inline void hdd_tdls_pre_init(hdd_context_t *hdd_ctx) { } #ifdef FEATURE_WLAN_DIAG_SUPPORT void hdd_send_wlan_tdls_teardown_event(uint32_t reason, uint8_t *peer_mac); +void hdd_wlan_tdls_enable_link_event(const uint8_t *peer_mac, + uint8_t is_off_chan_supported, + uint8_t is_off_chan_configured, + uint8_t is_off_chan_established); #else static inline void hdd_send_wlan_tdls_teardown_event(uint32_t reason, uint8_t *peer_mac) {} +static inline +void hdd_wlan_tdls_enable_link_event(const uint8_t *peer_mac, + uint8_t is_off_chan_supported, + uint8_t is_off_chan_configured, + uint8_t is_off_chan_established) {} + #endif /* FEATURE_WLAN_DIAG_SUPPORT */ #endif /* __HDD_TDLS_H */ diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index de431b9a7f1a..52bab8b980fd 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -108,6 +108,41 @@ void hdd_send_wlan_tdls_teardown_event(uint32_t reason, WLAN_HOST_DIAG_EVENT_REPORT(&tdls_tear_down, EVENT_WLAN_TDLS_TEARDOWN); } + +/** + * hdd_wlan_tdls_enable_link_event()- send TDLS enable link event + * @peer_mac: peer mac + * @is_off_chan_supported: Does peer supports off chan + * @is_off_chan_configured: If off channel is configured + * @is_off_chan_established: If off chan is established + * + * This Function send TDLS enable link diag event + * + * Return: void. + */ + +void hdd_wlan_tdls_enable_link_event(const uint8_t *peer_mac, + uint8_t is_off_chan_supported, + uint8_t is_off_chan_configured, + uint8_t is_off_chan_established) +{ + WLAN_HOST_DIAG_EVENT_DEF(tdls_event, + struct host_event_tdls_enable_link); + + qdf_mem_copy(tdls_event.peer_mac, + peer_mac, MAC_ADDR_LEN); + + tdls_event.is_off_chan_supported = + is_off_chan_supported; + tdls_event.is_off_chan_configured = + is_off_chan_configured; + tdls_event.is_off_chan_established = + is_off_chan_established; + + WLAN_HOST_DIAG_EVENT_REPORT(&tdls_event, + EVENT_WLAN_TDLS_ENABLE_LINK); +} + #endif /** @@ -4458,7 +4493,9 @@ static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, } } } - + hdd_wlan_tdls_enable_link_event(peer, + pTdlsPeer->isOffChannelSupported, + 0, 0); } break; case NL80211_TDLS_DISABLE_LINK: diff --git a/core/utils/host_diag_log/inc/host_diag_core_event.h b/core/utils/host_diag_log/inc/host_diag_core_event.h index 135ded970a9b..f2929c4f7b40 100644 --- a/core/utils/host_diag_log/inc/host_diag_core_event.h +++ b/core/utils/host_diag_log/inc/host_diag_core_event.h @@ -311,6 +311,22 @@ struct host_event_tdls_teardown { uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; }; +/** + * struct host_event_tdls_enable_link - tdls enable link event + * @peer_mac: peer mac + * @is_off_chan_supported: if off channel supported + * @is_off_chan_configured: if off channel configured + * @is_off_chan_established: if off channel established + * + * This structure contain tdls enable link diag event info + */ +struct host_event_tdls_enable_link { + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; + uint8_t is_off_chan_supported; + uint8_t is_off_chan_configured; + uint8_t is_off_chan_established; +}; + /*------------------------------------------------------------------------- Function declarations and documenation ------------------------------------------------------------------------*/ diff --git a/core/utils/host_diag_log/inc/host_diag_event_defs.h b/core/utils/host_diag_log/inc/host_diag_event_defs.h index 6027f88dabd5..ed174e12d54b 100644 --- a/core/utils/host_diag_log/inc/host_diag_event_defs.h +++ b/core/utils/host_diag_log/inc/host_diag_event_defs.h @@ -55,6 +55,7 @@ typedef enum { EVENT_WLAN_BEACON_RECEIVED = 0xAA6, /* FW event: 2726 */ EVENT_WLAN_LOG_COMPLETE = 0xAA7, /* 16 bytes payload */ EVENT_WLAN_TDLS_TEARDOWN = 0xAB5, + EVENT_WLAN_TDLS_ENABLE_LINK = 0XAB6, EVENT_MAX_ID = 0x0FFF } event_id_enum_type; -- cgit v1.2.3 From baea27d52a371e9e08637e648cc838a295446c19 Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Wed, 27 Apr 2016 13:29:30 +0530 Subject: qcacld-3.0: Add diag event for suspend and resume qcacld-2.0 to qcacld-3.0 propagation Add diag event for EVENT_WLAN_SUSPEND_RESUME. This contains info if driver has entered early suspend, suspend, early resume or resume state. Change-Id: Ic9bb815667ea9203d44a3c3cfcecbdbae573e717 CRs-Fixed: 934452 --- core/hdd/inc/wlan_hdd_power.h | 24 ++++++++++++++++++++++ core/hdd/src/wlan_hdd_power.c | 21 +++++++++++++++++++ .../utils/host_diag_log/inc/host_diag_core_event.h | 10 +++++++++ .../utils/host_diag_log/inc/host_diag_event_defs.h | 1 + 4 files changed, 56 insertions(+) diff --git a/core/hdd/inc/wlan_hdd_power.h b/core/hdd/inc/wlan_hdd_power.h index 2ce7f2dd2957..d872fae107ac 100644 --- a/core/hdd/inc/wlan_hdd_power.h +++ b/core/hdd/inc/wlan_hdd_power.h @@ -126,6 +126,22 @@ struct pkt_filter_cfg { #endif +/** + * enum suspend_resume_state - Suspend resume state + * @HDD_WLAN_EARLY_SUSPEND: Early suspend state. + * @HDD_WLAN_SUSPEND: Suspend state. + * @HDD_WLAN_EARLY_RESUME: Early resume state. + * @HDD_WLAN_RESUME: Resume state. + * + * Suspend state to indicate in diag event of suspend resume. + */ +enum suspend_resume_state { + HDD_WLAN_EARLY_SUSPEND, + HDD_WLAN_SUSPEND, + HDD_WLAN_EARLY_RESUME, + HDD_WLAN_RESUME +}; + /* SSR shutdown & re-init functions */ QDF_STATUS hdd_wlan_shutdown(void); @@ -171,4 +187,12 @@ int wlan_hdd_ipv4_changed(struct notifier_block *nb, int wlan_hdd_ipv6_changed(struct notifier_block *nb, unsigned long data, void *arg); +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void hdd_wlan_suspend_resume_event(uint8_t state); +#else +static inline +void hdd_wlan_suspend_resume_event(uint8_t state) {} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + + #endif /* __WLAN_HDD_POWER_H */ diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 7961eb5a626d..a78ef1174af2 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -87,6 +87,25 @@ enum hdd_power_mode { DRIVER_POWER_MODE_ACTIVE = 1, }; +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** + * hdd_wlan_suspend_resume_event()- send suspend/resume state + * @state: suspend/resume state + * + * This Function send send suspend resume state diag event + * + * Return: void. + */ +void hdd_wlan_suspend_resume_event(uint8_t state) +{ + WLAN_HOST_DIAG_EVENT_DEF(suspend_state, struct host_event_suspend); + qdf_mem_zero(&suspend_state, sizeof(suspend_state)); + + suspend_state.state = state; + WLAN_HOST_DIAG_EVENT_REPORT(&suspend_state, EVENT_WLAN_SUSPEND_RESUME); +} +#endif + /* Function and variables declarations */ extern struct notifier_block hdd_netdev_notifier; @@ -1137,6 +1156,7 @@ hdd_suspend_wlan(void (*callback)(void *callbackContext, bool suspended), callbackContext); pHddCtx->hdd_wlan_suspended = true; + hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND); return; } @@ -1170,6 +1190,7 @@ static void hdd_resume_wlan(void) } pHddCtx->hdd_wlan_suspended = false; + hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME); /*loop through all adapters. Concurrency */ status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); diff --git a/core/utils/host_diag_log/inc/host_diag_core_event.h b/core/utils/host_diag_log/inc/host_diag_core_event.h index f2929c4f7b40..91d87f90e527 100644 --- a/core/utils/host_diag_log/inc/host_diag_core_event.h +++ b/core/utils/host_diag_log/inc/host_diag_core_event.h @@ -327,6 +327,16 @@ struct host_event_tdls_enable_link { uint8_t is_off_chan_established; }; +/** + * struct host_event_suspend - suspend/resume state + * @state: suspend/resume state + * + * This structure contains suspend resume diag event info + */ +struct host_event_suspend { + uint8_t state; +}; + /*------------------------------------------------------------------------- Function declarations and documenation ------------------------------------------------------------------------*/ diff --git a/core/utils/host_diag_log/inc/host_diag_event_defs.h b/core/utils/host_diag_log/inc/host_diag_event_defs.h index ed174e12d54b..65dcab2d07f6 100644 --- a/core/utils/host_diag_log/inc/host_diag_event_defs.h +++ b/core/utils/host_diag_log/inc/host_diag_event_defs.h @@ -56,6 +56,7 @@ typedef enum { EVENT_WLAN_LOG_COMPLETE = 0xAA7, /* 16 bytes payload */ EVENT_WLAN_TDLS_TEARDOWN = 0xAB5, EVENT_WLAN_TDLS_ENABLE_LINK = 0XAB6, + EVENT_WLAN_SUSPEND_RESUME = 0xAB7, EVENT_MAX_ID = 0x0FFF } event_id_enum_type; -- cgit v1.2.3 From 4aad0f7daa7f62a61229ab9221c95f75e58dcda9 Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Wed, 27 Apr 2016 13:43:29 +0530 Subject: qcacld-3.0: Add diag event for offload requests qcacld-2.0 to qcacld-3.0 propagation Add diag event for EVENT_OFFLOAD_REQ. This events contains info if host has enabled or disabled the offload. Change-Id: I19fe216ac0900dedbcb7b247cf0d171979308dc5 CRs-Fixed: 934455 --- core/hdd/inc/wlan_hdd_host_offload.h | 9 ++++++ core/hdd/src/wlan_hdd_power.c | 33 +++++++++++++++++++++- .../utils/host_diag_log/inc/host_diag_core_event.h | 12 ++++++++ .../utils/host_diag_log/inc/host_diag_event_defs.h | 1 + 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/core/hdd/inc/wlan_hdd_host_offload.h b/core/hdd/inc/wlan_hdd_host_offload.h index 79d52ab3dbc9..873b6a73d1e3 100644 --- a/core/hdd/inc/wlan_hdd_host_offload.h +++ b/core/hdd/inc/wlan_hdd_host_offload.h @@ -57,4 +57,13 @@ typedef struct { struct qdf_mac_addr bssId; } tHostOffloadRequest, *tpHostOffloadRequest; +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void hdd_wlan_offload_event(uint8_t type, uint8_t state); +#else +static inline +void hdd_wlan_offload_event(uint8_t type, uint8_t state) +{ +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + #endif /* __WLAN_HDD_HOST_OFFLOAD_H__ */ diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index a78ef1174af2..117413611818 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -104,6 +104,27 @@ void hdd_wlan_suspend_resume_event(uint8_t state) suspend_state.state = state; WLAN_HOST_DIAG_EVENT_REPORT(&suspend_state, EVENT_WLAN_SUSPEND_RESUME); } + +/** + * hdd_wlan_offload_event()- send offloads event + * @type: offload type + * @state: enabled or disabled + * + * This Function send offloads enable/disable diag event + * + * Return: void. + */ + +void hdd_wlan_offload_event(uint8_t type, uint8_t state) +{ + WLAN_HOST_DIAG_EVENT_DEF(host_offload, struct host_event_offload_req); + qdf_mem_zero(&host_offload, sizeof(host_offload)); + + host_offload.offload_type = type; + host_offload.state = state; + + WLAN_HOST_DIAG_EVENT_REPORT(&host_offload, EVENT_WLAN_OFFLOAD_REQ); +} #endif /* Function and variables declarations */ @@ -406,6 +427,8 @@ static void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, bool fenable) &offLoadRequest.nsOffloadInfo.selfIPv6Addr[i], &offLoadRequest.nsOffloadInfo.targetIPv6Addr[i], i); } + hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD, + SIR_OFFLOAD_ENABLE); offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD; offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE; qdf_copy_macaddr(&offLoadRequest.nsOffloadInfo.self_macaddr, @@ -424,6 +447,8 @@ static void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, bool fenable) return; } } else { + hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD, + SIR_OFFLOAD_DISABLE); /* Disable NSOffload */ qdf_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq)); offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE; @@ -739,6 +764,8 @@ QDF_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, bool fenable) if (ifa && ifa->ifa_local) { offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD; offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE; + hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD, + SIR_OFFLOAD_ENABLE); hddLog(QDF_TRACE_LEVEL_INFO, "%s: Enabled", __func__); @@ -753,7 +780,9 @@ QDF_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, bool fenable) hddLog(QDF_TRACE_LEVEL_INFO, "offload: inside arp offload conditional check"); } - + hdd_wlan_offload_event( + SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE, + SIR_OFFLOAD_ENABLE); hddLog(QDF_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d", offLoadRequest.enableOrDisable); @@ -786,6 +815,8 @@ QDF_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, bool fenable) return QDF_STATUS_SUCCESS; } else { + hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD, + SIR_OFFLOAD_DISABLE); qdf_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq)); offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE; diff --git a/core/utils/host_diag_log/inc/host_diag_core_event.h b/core/utils/host_diag_log/inc/host_diag_core_event.h index 91d87f90e527..997b29599974 100644 --- a/core/utils/host_diag_log/inc/host_diag_core_event.h +++ b/core/utils/host_diag_log/inc/host_diag_core_event.h @@ -337,6 +337,18 @@ struct host_event_suspend { uint8_t state; }; +/** + * struct host_event_offload_req - offload state + * @offload_type: offload type + * @state: enabled or disabled state + * + * This structure contains offload diag event info + */ +struct host_event_offload_req { + uint8_t offload_type; + uint8_t state; +}; + /*------------------------------------------------------------------------- Function declarations and documenation ------------------------------------------------------------------------*/ diff --git a/core/utils/host_diag_log/inc/host_diag_event_defs.h b/core/utils/host_diag_log/inc/host_diag_event_defs.h index 65dcab2d07f6..2ca73cfe6876 100644 --- a/core/utils/host_diag_log/inc/host_diag_event_defs.h +++ b/core/utils/host_diag_log/inc/host_diag_event_defs.h @@ -57,6 +57,7 @@ typedef enum { EVENT_WLAN_TDLS_TEARDOWN = 0xAB5, EVENT_WLAN_TDLS_ENABLE_LINK = 0XAB6, EVENT_WLAN_SUSPEND_RESUME = 0xAB7, + EVENT_WLAN_OFFLOAD_REQ = 0xAB8, EVENT_MAX_ID = 0x0FFF } event_id_enum_type; -- cgit v1.2.3 From af1d0c92ecdf6690e425df8b00b6c15076b59d35 Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Wed, 27 Apr 2016 13:46:59 +0530 Subject: qcacld-3.0: Add diag event for scan blocked by TDLS. qcacld-2.0 to qcacld-3.0 propagation Add diag event for EVENT_TDLS_SCAN_BLOCK. This event indicates if scan is blocked because of TDLS. Change-Id: I00dd9d2a54cbe054b400b2d1cb74c0e14b9a13d7 CRs-Fixed: 934456 --- core/hdd/inc/wlan_hdd_tdls.h | 3 ++- core/hdd/src/wlan_hdd_scan.c | 1 + core/hdd/src/wlan_hdd_tdls.c | 19 +++++++++++++++++++ core/utils/host_diag_log/inc/host_diag_core_event.h | 12 ++++++++++++ core/utils/host_diag_log/inc/host_diag_event_defs.h | 1 + 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h index e19af31b9e48..74b0bb3bd480 100644 --- a/core/hdd/inc/wlan_hdd_tdls.h +++ b/core/hdd/inc/wlan_hdd_tdls.h @@ -656,6 +656,7 @@ void hdd_wlan_tdls_enable_link_event(const uint8_t *peer_mac, uint8_t is_off_chan_supported, uint8_t is_off_chan_configured, uint8_t is_off_chan_established); +void hdd_wlan_block_scan_by_tdls_event(void); #else static inline void hdd_send_wlan_tdls_teardown_event(uint32_t reason, @@ -665,7 +666,7 @@ void hdd_wlan_tdls_enable_link_event(const uint8_t *peer_mac, uint8_t is_off_chan_supported, uint8_t is_off_chan_configured, uint8_t is_off_chan_established) {} - +static inline void hdd_wlan_block_scan_by_tdls_event(void) {} #endif /* FEATURE_WLAN_DIAG_SUPPORT */ #endif /* __HDD_TDLS_H */ diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index d35f21bd0d0f..b10068bfe99a 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -1378,6 +1378,7 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, else hddLog(LOGE, FL("TDLS teardown is ongoing %d"), status); + hdd_wlan_block_scan_by_tdls_event(); return status; } #endif diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index 52bab8b980fd..878bf0f05947 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -143,6 +143,25 @@ void hdd_wlan_tdls_enable_link_event(const uint8_t *peer_mac, EVENT_WLAN_TDLS_ENABLE_LINK); } +/** + * hdd_wlan_block_scan_by_tdls_event()- send event + * if scan is blocked by tdls + * + * This Function send send diag event if scan is + * blocked by tdls + * + * Return: void. + */ +void hdd_wlan_block_scan_by_tdls_event(void) +{ + WLAN_HOST_DIAG_EVENT_DEF(tdls_scan_block_status, + struct host_event_tdls_scan_rejected); + + tdls_scan_block_status.status = true; + WLAN_HOST_DIAG_EVENT_REPORT(&tdls_scan_block_status, + EVENT_TDLS_SCAN_BLOCK); +} + #endif /** diff --git a/core/utils/host_diag_log/inc/host_diag_core_event.h b/core/utils/host_diag_log/inc/host_diag_core_event.h index 997b29599974..09fb066cdd76 100644 --- a/core/utils/host_diag_log/inc/host_diag_core_event.h +++ b/core/utils/host_diag_log/inc/host_diag_core_event.h @@ -349,6 +349,18 @@ struct host_event_offload_req { uint8_t state; }; +/** + * struct host_event_tdls_scan_rejected - scan + * rejected due to tdls + * @status: rejected status + * + * This structure contains scan rejected due to + * tdls event info + */ +struct host_event_tdls_scan_rejected { + uint8_t status; +}; + /*------------------------------------------------------------------------- Function declarations and documenation ------------------------------------------------------------------------*/ diff --git a/core/utils/host_diag_log/inc/host_diag_event_defs.h b/core/utils/host_diag_log/inc/host_diag_event_defs.h index 2ca73cfe6876..38b806aa42d0 100644 --- a/core/utils/host_diag_log/inc/host_diag_event_defs.h +++ b/core/utils/host_diag_log/inc/host_diag_event_defs.h @@ -58,6 +58,7 @@ typedef enum { EVENT_WLAN_TDLS_ENABLE_LINK = 0XAB6, EVENT_WLAN_SUSPEND_RESUME = 0xAB7, EVENT_WLAN_OFFLOAD_REQ = 0xAB8, + EVENT_TDLS_SCAN_BLOCK = 0xAB9, EVENT_MAX_ID = 0x0FFF } event_id_enum_type; -- cgit v1.2.3 From 437606ac2dc3376512191b0fa0c5e39c590f007b Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Wed, 27 Apr 2016 13:51:49 +0530 Subject: qcacld-3.0: Add diag event for TDLS management frame tx and rx qcacld-2.0 to qcacld-3.0 propagation Add diag event for EVENT_WLAN_TDLS_TX_RX_MGMT. This event contains TDLS action frame type, subtype and if its rx or tx. Change-Id: I6ec744518b7a391e4511c503cb858d532ef11322 CRs-Fixed: 934447 --- core/cds/inc/cds_api.h | 13 ++++++++++ core/cds/src/cds_api.c | 30 ++++++++++++++++++++++ core/hdd/inc/wlan_hdd_p2p.h | 3 +++ core/hdd/src/wlan_hdd_p2p.c | 16 +++++++++--- core/mac/inc/sir_mac_prot_def.h | 3 +++ core/mac/src/pe/lim/lim_process_tdls.c | 4 +++ .../utils/host_diag_log/inc/host_diag_core_event.h | 18 +++++++++++++ .../utils/host_diag_log/inc/host_diag_event_defs.h | 1 + 8 files changed, 84 insertions(+), 4 deletions(-) diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h index 103514657291..e60ae4fd52a0 100644 --- a/core/cds/inc/cds_api.h +++ b/core/cds/inc/cds_api.h @@ -242,4 +242,17 @@ QDF_STATUS cds_flush_logs(uint32_t is_fatal, uint32_t indicator, uint32_t reason_code); void cds_logging_set_fw_flush_complete(void); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx, + uint8_t type, uint8_t sub_type, uint8_t *peer_mac); +#else +static inline +void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx, + uint8_t type, uint8_t sub_type, uint8_t *peer_mac) + +{ +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + #endif /* if !defined __CDS_API_H */ diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index cc950b32ae7b..8fe325c92ae5 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -130,6 +130,36 @@ void cds_deinit(void) return; } +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** + * cds_tdls_tx_rx_mgmt_event()- send tdls mgmt rx tx event + * @event_id: event id + * @tx_rx: tx or rx + * @type: type of frame + * @action_sub_type: action frame type + * @peer_mac: peer mac + * + * This Function sends tdls mgmt rx tx diag event + * + * Return: void. + */ +void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx, + uint8_t type, uint8_t action_sub_type, uint8_t *peer_mac) +{ + WLAN_HOST_DIAG_EVENT_DEF(tdls_tx_rx_mgmt, + struct host_event_tdls_tx_rx_mgmt); + + tdls_tx_rx_mgmt.event_id = event_id; + tdls_tx_rx_mgmt.tx_rx = tx_rx; + tdls_tx_rx_mgmt.type = type; + tdls_tx_rx_mgmt.action_sub_type = action_sub_type; + qdf_mem_copy(tdls_tx_rx_mgmt.peer_mac, + peer_mac, CDS_MAC_ADDRESS_LEN); + WLAN_HOST_DIAG_EVENT_REPORT(&tdls_tx_rx_mgmt, + EVENT_WLAN_TDLS_TX_RX_MGMT); +} +#endif + #ifdef WLAN_FEATURE_NAN /** * cds_set_nan_enable() - set nan enable flag in mac open param diff --git a/core/hdd/inc/wlan_hdd_p2p.h b/core/hdd/inc/wlan_hdd_p2p.h index 3cc7dc7c0d18..9fcf9ecc2fed 100644 --- a/core/hdd/inc/wlan_hdd_p2p.h +++ b/core/hdd/inc/wlan_hdd_p2p.h @@ -51,6 +51,9 @@ #define WLAN_HDD_80211_FRM_DA_OFFSET 4 #define P2P_WILDCARD_SSID_LEN 7 #define P2P_WILDCARD_SSID "DIRECT-" +#define WLAN_HDD_80211_PEER_ADDR_OFFSET (WLAN_HDD_80211_FRM_DA_OFFSET + \ + MAC_ADDR_LEN) + #ifdef QCA_WIFI_3_0_EMU #define P2P_ROC_DURATION_MULTIPLIER_GO_PRESENT 2 diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index b54a41baba96..24f572a0e980 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -2247,8 +2247,8 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter, + 2], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE)) { /* P2P action frames */ - u8 *macFrom = - &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET + 6]; + u8 *macFrom = &pbFrames + [WLAN_HDD_80211_PEER_ADDR_OFFSET]; actionFrmType = pbFrames [WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; @@ -2409,8 +2409,8 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter, else if (pbFrames [WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + 1] == WLAN_HDD_PUBLIC_ACTION_TDLS_DISC_RESP) { - u8 *mac = - &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET + 6]; + u8 *mac = &pbFrames + [WLAN_HDD_80211_PEER_ADDR_OFFSET]; hddLog(LOG1, "[TDLS] TDLS Discovery Response," @@ -2420,6 +2420,10 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter, wlan_hdd_tdls_set_rssi(pAdapter, mac, rxRssi); wlan_hdd_tdls_recv_discovery_resp(pAdapter, mac); + cds_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS, + SIR_MAC_ACTION_RX, SIR_MAC_MGMT_ACTION, + WLAN_HDD_PUBLIC_ACTION_TDLS_DISC_RESP, + &pbFrames[WLAN_HDD_80211_PEER_ADDR_OFFSET]); } #endif } @@ -2437,6 +2441,10 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter, "[TDLS] %s <--- OTA", tdls_action_frame_type[actionFrmType]); } + cds_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS, + SIR_MAC_ACTION_RX, SIR_MAC_MGMT_ACTION, + actionFrmType, + &pbFrames[WLAN_HDD_80211_PEER_ADDR_OFFSET]); } if ((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h index 2585a4fa3445..596f55889671 100644 --- a/core/mac/inc/sir_mac_prot_def.h +++ b/core/mac/inc/sir_mac_prot_def.h @@ -145,6 +145,9 @@ #define SIR_MAC_ACTION_FST 18 #define SIR_MAC_ACTION_VHT 21 +#define SIR_MAC_ACTION_TX 1 +#define SIR_MAC_ACTION_RX 2 + /* QoS management action codes */ #define SIR_MAC_QOS_ADD_TS_REQ 0 diff --git a/core/mac/src/pe/lim/lim_process_tdls.c b/core/mac/src/pe/lim/lim_process_tdls.c index 5950dd373704..9016fbf2c412 100644 --- a/core/mac/src/pe/lim/lim_process_tdls.c +++ b/core/mac/src/pe/lim/lim_process_tdls.c @@ -2757,6 +2757,10 @@ tSirRetStatus lim_process_sme_tdls_mgmt_send_req(tpAniSirGlobal mac_ctx, goto lim_tdls_send_mgmt_error; } + cds_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS, + SIR_MAC_ACTION_TX, SIR_MAC_MGMT_ACTION, + send_req->reqType, send_req->peer_mac.bytes); + switch (send_req->reqType) { case SIR_MAC_TDLS_DIS_REQ: lim_log(mac_ctx, LOG1, FL("Transmit Discovery Request Frame")); diff --git a/core/utils/host_diag_log/inc/host_diag_core_event.h b/core/utils/host_diag_log/inc/host_diag_core_event.h index 09fb066cdd76..c7cce228a80a 100644 --- a/core/utils/host_diag_log/inc/host_diag_core_event.h +++ b/core/utils/host_diag_log/inc/host_diag_core_event.h @@ -361,6 +361,24 @@ struct host_event_tdls_scan_rejected { uint8_t status; }; +/** + * struct host_event_tdls_tx_rx_mgmt - for TX RX management frame + * @event_id: event ID + * @tx_rx: tx or rx + * @type: type of frame + * @action_sub_type: action frame type + * @peer_mac: peer mac + * + * This structure contains tdls TX RX management frame info + */ +struct host_event_tdls_tx_rx_mgmt { + uint8_t event_id; + uint8_t tx_rx; + uint8_t type; + uint8_t action_sub_type; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; +}; + /*------------------------------------------------------------------------- Function declarations and documenation ------------------------------------------------------------------------*/ diff --git a/core/utils/host_diag_log/inc/host_diag_event_defs.h b/core/utils/host_diag_log/inc/host_diag_event_defs.h index 38b806aa42d0..6b658ba37b81 100644 --- a/core/utils/host_diag_log/inc/host_diag_event_defs.h +++ b/core/utils/host_diag_log/inc/host_diag_event_defs.h @@ -59,6 +59,7 @@ typedef enum { EVENT_WLAN_SUSPEND_RESUME = 0xAB7, EVENT_WLAN_OFFLOAD_REQ = 0xAB8, EVENT_TDLS_SCAN_BLOCK = 0xAB9, + EVENT_WLAN_TDLS_TX_RX_MGMT = 0xABA, EVENT_MAX_ID = 0x0FFF } event_id_enum_type; -- cgit v1.2.3 From 5ea86536ef9359ec18e0ee5976650dc32f49bf2e Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Wed, 27 Apr 2016 14:10:53 +0530 Subject: qcacld-3.0: Add scenario based BUG report qcacld-2.0 to qcacld-3.0 propagation Change to initiate BUG report in case of fatal event Add INI support to Enable/Disable it. The fatal event handled are as below: - Roaming failed after successful preauth. - SME command timeout. - PE defer queue is full. - CDS run out of message wrapper. - HDD level wait for event timeout. CRs-Fixed: 912560 Change-Id: I64dff8b7d0836340ce3bec5f5985d1919b600c23 --- core/cds/inc/cds_api.h | 17 ++- core/cds/inc/cds_sched.h | 3 + core/cds/src/cds_api.c | 145 +++++++++++++++++++++++-- core/hdd/inc/wlan_hdd_cfg.h | 10 ++ core/hdd/src/wlan_hdd_cfg.c | 14 +++ core/hdd/src/wlan_hdd_cfg80211.c | 3 +- core/hdd/src/wlan_hdd_main.c | 2 + core/hdd/src/wlan_hdd_p2p.c | 8 ++ core/hdd/src/wlan_hdd_tdls.c | 6 +- core/mac/inc/ani_global.h | 26 ++--- core/mac/src/pe/lim/lim_utils.c | 4 + core/sme/inc/csr_api.h | 1 + core/sme/inc/csr_internal.h | 1 + core/sme/src/common/sme_api.c | 54 +++++++-- core/sme/src/csr/csr_api_roam.c | 8 ++ core/utils/logging/inc/wlan_logging_sock_svc.h | 5 + core/utils/logging/src/wlan_logging_sock_svc.c | 46 +++++++- core/wma/src/wma_main.c | 2 +- 18 files changed, 306 insertions(+), 49 deletions(-) diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h index e60ae4fd52a0..5b85fa1b0a48 100644 --- a/core/cds/inc/cds_api.h +++ b/core/cds/inc/cds_api.h @@ -231,16 +231,25 @@ void cds_set_multicast_logging(uint8_t value); uint8_t cds_is_multicast_logging(void); QDF_STATUS cds_set_log_completion(uint32_t is_fatal, uint32_t type, - uint32_t sub_type); -void cds_get_log_completion(uint32_t *is_fatal, + uint32_t sub_type, + bool recovery_needed); +void cds_get_and_reset_log_completion(uint32_t *is_fatal, uint32_t *type, - uint32_t *sub_type); + uint32_t *sub_type, + bool *recovery_needed); bool cds_is_log_report_in_progress(void); +bool cds_is_fatal_event_enabled(void); +uint32_t cds_get_log_indicator(void); +void cds_set_fatal_event(bool value); +void cds_wlan_flush_host_logs_for_fatal(void); + void cds_init_log_completion(void); void cds_deinit_log_completion(void); QDF_STATUS cds_flush_logs(uint32_t is_fatal, uint32_t indicator, - uint32_t reason_code); + uint32_t reason_code, + bool dump_mac_trace, + bool recovery_needed); void cds_logging_set_fw_flush_complete(void); #ifdef FEATURE_WLAN_DIAG_SUPPORT diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h index 4a26355e580b..cc082411e125 100644 --- a/core/cds/inc/cds_sched.h +++ b/core/cds/inc/cds_sched.h @@ -209,6 +209,7 @@ typedef struct _cds_sched_context { * @indicator: Source of bug report * @reason_code: Reason code for bug report * @is_report_in_progress: If bug report is in progress + * @recovery_needed: if recovery is needed after report completion * * This structure internally stores the log related params */ @@ -217,6 +218,7 @@ struct cds_log_complete { uint32_t indicator; uint32_t reason_code; bool is_report_in_progress; + bool recovery_needed; }; /* @@ -292,6 +294,7 @@ typedef struct _cds_context_type { void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t); #endif bool do_hw_mode_change; + bool enable_fatal_event; } cds_context_type, *p_cds_contextType; /*--------------------------------------------------------------------------- diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 8fe325c92ae5..684bdb5dae29 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -1344,11 +1344,15 @@ QDF_STATUS cds_mq_post_message(CDS_MQ_ID msgQueueId, cds_msg_t *pMsg) if (NULL == pMsgWrapper) { debug_count = atomic_inc_return(&cds_wrapper_empty_count); - if (1 == debug_count) + if (1 == debug_count) { QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, "%s: CDS Core run out of message wrapper %d", __func__, debug_count); - + cds_flush_logs(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_ONLY, + WLAN_LOG_REASON_VOS_MSG_UNDER_RUN, + true, false); + } if (CDS_WRAPPER_MAX_FAIL_COUNT == debug_count) QDF_BUG(0); @@ -1921,6 +1925,7 @@ void cds_deinit_log_completion(void) * @is_fatal: Indicates if the event triggering bug report is fatal or not * @indicator: Source which trigerred the bug report * @reason_code: Reason for triggering bug report + * @recovery_needed: If recovery is needed after bug report * * This function is used to set the logging parameters based on the * caller @@ -1929,7 +1934,8 @@ void cds_deinit_log_completion(void) */ QDF_STATUS cds_set_log_completion(uint32_t is_fatal, uint32_t indicator, - uint32_t reason_code) + uint32_t reason_code, + bool recovery_needed) { p_cds_contextType p_cds_context; @@ -1944,24 +1950,27 @@ QDF_STATUS cds_set_log_completion(uint32_t is_fatal, p_cds_context->log_complete.is_fatal = is_fatal; p_cds_context->log_complete.indicator = indicator; p_cds_context->log_complete.reason_code = reason_code; + p_cds_context->log_complete.recovery_needed = recovery_needed; p_cds_context->log_complete.is_report_in_progress = true; qdf_spinlock_release(&p_cds_context->bug_report_lock); return QDF_STATUS_SUCCESS; } /** - * cds_get_log_completion() - Get the logging related params + * cds_get_and_reset_log_completion() - Get and reset logging related params * @is_fatal: Indicates if the event triggering bug report is fatal or not * @indicator: Source which trigerred the bug report * @reason_code: Reason for triggering bug report + * @recovery_needed: If recovery is needed after bug report * * This function is used to get the logging related parameters * * Return: None */ -void cds_get_log_completion(uint32_t *is_fatal, +void cds_get_and_reset_log_completion(uint32_t *is_fatal, uint32_t *indicator, - uint32_t *reason_code) + uint32_t *reason_code, + bool *recovery_needed) { p_cds_contextType p_cds_context; @@ -1976,7 +1985,14 @@ void cds_get_log_completion(uint32_t *is_fatal, *is_fatal = p_cds_context->log_complete.is_fatal; *indicator = p_cds_context->log_complete.indicator; *reason_code = p_cds_context->log_complete.reason_code; + *recovery_needed = p_cds_context->log_complete.recovery_needed; + + /* reset */ + p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED; + p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL; p_cds_context->log_complete.is_report_in_progress = false; + p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED; + p_cds_context->log_complete.recovery_needed = false; qdf_spinlock_release(&p_cds_context->bug_report_lock); } @@ -2000,11 +2016,80 @@ bool cds_is_log_report_in_progress(void) return p_cds_context->log_complete.is_report_in_progress; } +/** + * cds_is_fatal_event_enabled() - Return if fatal event is enabled + * + * Return true if fatal event is enabled. + */ +bool cds_is_fatal_event_enabled(void) +{ + p_cds_contextType p_cds_context; + + p_cds_context = cds_get_global_context(); + if (!p_cds_context) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "%s: cds context is Invalid", __func__); + return false; + } + + + return p_cds_context->enable_fatal_event; +} + +/** + * cds_get_log_indicator() - Get the log flush indicator + * + * This function is used to get the log flush indicator + * + * Return: log indicator + */ +uint32_t cds_get_log_indicator(void) +{ + p_cds_contextType p_cds_context; + uint32_t indicator; + + p_cds_context = cds_get_global_context(); + if (!p_cds_context) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "%s: cds context is Invalid", __func__); + return WLAN_LOG_INDICATOR_UNUSED; + } + + if (cds_is_load_or_unload_in_progress() || + cds_is_driver_recovering()) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "%s: vos context initialization is in progress" + , __func__); + return WLAN_LOG_INDICATOR_UNUSED; + } + + qdf_spinlock_acquire(&p_cds_context->bug_report_lock); + indicator = p_cds_context->log_complete.indicator; + qdf_spinlock_release(&p_cds_context->bug_report_lock); + return indicator; +} + +/** + * cds_wlan_flush_host_logs_for_fatal() - Wrapper to flush host logs + * + * This function is used to send signal to the logger thread to + * flush the host logs. + * + * Return: None + * + */ +void cds_wlan_flush_host_logs_for_fatal(void) +{ + wlan_flush_host_logs_for_fatal(); +} + /** * cds_flush_logs() - Report fatal event to userspace * @is_fatal: Indicates if the event triggering bug report is fatal or not * @indicator: Source which trigerred the bug report * @reason_code: Reason for triggering bug report + * @dump_mac_trace: If mac trace are needed in logs. + * @recovery_needed: If recovery is needed after bug report * * This function sets the log related params and send the WMI command to the * FW to flush its logs. On receiving the flush completion event from the FW @@ -2014,7 +2099,9 @@ bool cds_is_log_report_in_progress(void) */ QDF_STATUS cds_flush_logs(uint32_t is_fatal, uint32_t indicator, - uint32_t reason_code) + uint32_t reason_code, + bool dump_mac_trace, + bool recovery_needed) { uint32_t ret; QDF_STATUS status; @@ -2027,6 +2114,17 @@ QDF_STATUS cds_flush_logs(uint32_t is_fatal, "%s: cds context is Invalid", __func__); return QDF_STATUS_E_FAILURE; } + if (!p_cds_context->enable_fatal_event) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "%s: Fatal event not enabled", __func__); + return QDF_STATUS_E_FAILURE; + } + if (cds_is_load_or_unload_in_progress() || + cds_is_driver_recovering()) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "%s: un/Load/SSR in progress", __func__); + return QDF_STATUS_E_FAILURE; + } if (cds_is_log_report_in_progress() == true) { QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, @@ -2035,17 +2133,26 @@ QDF_STATUS cds_flush_logs(uint32_t is_fatal, return QDF_STATUS_E_FAILURE; } - status = cds_set_log_completion(is_fatal, indicator, reason_code); + status = cds_set_log_completion(is_fatal, indicator, + reason_code, recovery_needed); if (QDF_STATUS_SUCCESS != status) { QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, "%s: Failed to set log trigger params", __func__); return QDF_STATUS_E_FAILURE; } - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, "%s: Triggering bug report: type:%d, indicator=%d reason_code=%d", __func__, is_fatal, indicator, reason_code); + if (dump_mac_trace) + qdf_trace_dump_all(p_cds_context->pMACContext, 0, 0, 500, 0); + + if (WLAN_LOG_INDICATOR_HOST_ONLY == indicator) { + cds_wlan_flush_host_logs_for_fatal(); + return QDF_STATUS_SUCCESS; + } + ret = sme_send_flush_logs_cmd_to_fw(p_cds_context->pMACContext); if (0 != ret) { QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, @@ -2070,3 +2177,23 @@ void cds_logging_set_fw_flush_complete(void) { wlan_logging_set_fw_flush_complete(); } + +/** + * cds_set_fatal_event() - set fatal event status + * @value: pending statue to set + * + * Return: None + */ +void cds_set_fatal_event(bool value) +{ + p_cds_contextType p_cds_context; + + p_cds_context = cds_get_global_context(); + if (!p_cds_context) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "%s: cds context is Invalid", __func__); + return; + } + p_cds_context->enable_fatal_event = value; +} + diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 70d4ad63095f..fd581b48f628 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -2995,6 +2995,15 @@ enum dot11p_mode { #define CFG_ROAM_DENSE_MIN_APS_MAX (5) #define CFG_ROAM_DENSE_MIN_APS_DEFAULT (1) +/* + * Enable/Disable to initiate BUG report in case of fatal event + * Default: Enable + */ +#define CFG_ENABLE_FATAL_EVENT_TRIGGER "gEnableFatalEvent" +#define CFG_ENABLE_FATAL_EVENT_TRIGGER_MIN (0) +#define CFG_ENABLE_FATAL_EVENT_TRIGGER_MAX (1) +#define CFG_ENABLE_FATAL_EVENT_TRIGGER_DEFAULT (1) + /*--------------------------------------------------------------------------- Type declarations -------------------------------------------------------------------------*/ @@ -3595,6 +3604,7 @@ struct hdd_config { uint32_t roam_dense_rssi_thresh_offset; bool ignore_peer_ht_opmode; uint32_t roam_dense_min_aps; + bool enable_fatal_event; }; #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var)) diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 5bbae4c696c1..23513f5677c5 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -3772,6 +3772,15 @@ REG_TABLE_ENTRY g_registry_table[] = { CFG_ROAM_DENSE_MIN_APS_MIN, CFG_ROAM_DENSE_MIN_APS_MAX), + REG_VARIABLE(CFG_ENABLE_FATAL_EVENT_TRIGGER, WLAN_PARAM_Integer, + struct hdd_config, enable_fatal_event, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FATAL_EVENT_TRIGGER_DEFAULT, + CFG_ENABLE_FATAL_EVENT_TRIGGER_MIN, + CFG_ENABLE_FATAL_EVENT_TRIGGER_MAX), + + }; @@ -5362,6 +5371,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx) hdd_info("Name = [%s] Value = [%u]", CFG_IGNORE_PEER_HT_MODE_NAME, pHddCtx->config->ignore_peer_ht_opmode); + hdd_info("Name = [%s] Value = [%u]", + CFG_ENABLE_FATAL_EVENT_TRIGGER, + pHddCtx->config->enable_fatal_event); hdd_info("Name = [%s] Value = [%u]", CFG_ROAM_DENSE_MIN_APS, pHddCtx->config->roam_dense_min_aps); @@ -6808,6 +6820,8 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx) pHddCtx->config->obss_passive_dwelltime; smeConfig->csrConfig.ignore_peer_ht_opmode = pConfig->ignore_peer_ht_opmode; + smeConfig->csrConfig.enable_fatal_event = + pConfig->enable_fatal_event; status = sme_update_config(pHddCtx->hHal, smeConfig); if (!QDF_IS_STATUS_SUCCESS(status)) { diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index c8af93844f02..cc8427103cba 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -3563,7 +3563,8 @@ static int __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy, status = cds_flush_logs(WLAN_LOG_TYPE_NON_FATAL, WLAN_LOG_INDICATOR_FRAMEWORK, - WLAN_LOG_REASON_CODE_UNUSED); + WLAN_LOG_REASON_CODE_UNUSED, + true, false); if (QDF_STATUS_SUCCESS != status) { hddLog(LOGE, FL("Failed to trigger bug report")); return -EINVAL; diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 6722d4677832..552f7c9e04f2 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5355,6 +5355,8 @@ hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc) hdd_notice("Setting configuredMcastBcastFilter: %d", hdd_ctx->config->mcastBcastFilterSetting); + cds_set_fatal_event(hdd_ctx->config->enable_fatal_event); + hdd_override_ini_config(hdd_ctx); ret = wlan_hdd_cfg80211_init(dev, hdd_ctx->wiphy, hdd_ctx->config); diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index 24f572a0e980..ebdb11f0bfc1 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -319,6 +319,10 @@ void wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter) hddLog(LOGE, "%s: timeout waiting for remain on channel ready indication", __func__); + cds_flush_logs(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_HDD_TIME_OUT, + true, false); } INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var); @@ -1171,6 +1175,10 @@ int __wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, cds_get_driver_state()); return -EAGAIN; } + cds_flush_logs(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_HDD_TIME_OUT, + true, false); } INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var); /* Issue abort remain on chan request to sme. diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index 878bf0f05947..afc1fd62e4c1 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -3983,7 +3983,11 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, cds_get_driver_state()); return -EAGAIN; } - + if (rc <= 0) + cds_flush_logs(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_HDD_TIME_OUT, + true, false); pAdapter->mgmtTxCompletionStatus = false; return -EINVAL; } diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h index 8f68465306b0..05430a9bb978 100644 --- a/core/mac/inc/ani_global.h +++ b/core/mac/inc/ani_global.h @@ -131,6 +131,7 @@ enum log_event_type { * @WLAN_LOG_INDICATOR_FRAMEWORK: Framework triggers bug report * @WLAN_LOG_INDICATOR_HOST_DRIVER: Host driver triggers bug report * @WLAN_LOG_INDICATOR_FIRMWARE: FW initiates bug report + * @WLAN_LOG_INDICATOR_HOST_ONLY: Host triggers fatal event bug report * * Enum indicating the module that triggered the bug report */ @@ -139,52 +140,39 @@ enum log_event_indicator { WLAN_LOG_INDICATOR_FRAMEWORK, WLAN_LOG_INDICATOR_HOST_DRIVER, WLAN_LOG_INDICATOR_FIRMWARE, + WLAN_LOG_INDICATOR_HOST_ONLY, }; /** * enum log_event_host_reason_code - Reason code for bug report * @WLAN_LOG_REASON_CODE_UNUSED: Unused - * @WLAN_LOG_REASON_COMMAND_UNSUCCESSFUL: Command response status from FW - * is error * @WLAN_LOG_REASON_ROAM_FAIL: Driver initiated roam has failed - * @WLAN_LOG_REASON_THREAD_STUCK: Monitor Health of host threads and report - * fatal event if some thread is stuck * @WLAN_LOG_REASON_DATA_STALL: Unable to send/receive data due to low resource * scenario for a prolonged period * @WLAN_LOG_REASON_SME_COMMAND_STUCK: SME command is stuck in SME active queue - * @WLAN_LOG_REASON_ZERO_SCAN_RESULTS: Full scan resulted in zero scan results * @WLAN_LOG_REASON_QUEUE_FULL: Defer queue becomes full for a prolonged period * @WLAN_LOG_REASON_POWER_COLLAPSE_FAIL: Unable to allow apps power collapse * for a prolonged period - * @WLAN_LOG_REASON_SSR_FAIL: Unable to gracefully complete SSR - * @WLAN_LOG_REASON_DISCONNECT_FAIL: Disconnect from Supplicant is not - * successful - * @WLAN_LOG_REASON_CLEAN_UP_FAIL: Clean up of TDLS or Pre-Auth Sessions - * not successful * @WLAN_LOG_REASON_MALLOC_FAIL: Memory allocation Fails * @WLAN_LOG_REASON_VOS_MSG_UNDER_RUN: VOS Core runs out of message wrapper - * @WLAN_LOG_REASON_MSG_POST_FAIL: Unable to post msg - * + * @WLAN_LOG_REASON_HDD_TIME_OUT: Wait for event Timeout in HDD layer + @WLAN_LOG_REASON_SME_OUT_OF_CMD_BUFL sme out of cmd buffer * This enum contains the different reason codes for bug report */ enum log_event_host_reason_code { WLAN_LOG_REASON_CODE_UNUSED, - WLAN_LOG_REASON_COMMAND_UNSUCCESSFUL, WLAN_LOG_REASON_ROAM_FAIL, - WLAN_LOG_REASON_THREAD_STUCK, WLAN_LOG_REASON_DATA_STALL, WLAN_LOG_REASON_SME_COMMAND_STUCK, - WLAN_LOG_REASON_ZERO_SCAN_RESULTS, WLAN_LOG_REASON_QUEUE_FULL, WLAN_LOG_REASON_POWER_COLLAPSE_FAIL, - WLAN_LOG_REASON_SSR_FAIL, - WLAN_LOG_REASON_DISCONNECT_FAIL, - WLAN_LOG_REASON_CLEAN_UP_FAIL, WLAN_LOG_REASON_MALLOC_FAIL, WLAN_LOG_REASON_VOS_MSG_UNDER_RUN, - WLAN_LOG_REASON_MSG_POST_FAIL, + WLAN_LOG_REASON_HDD_TIME_OUT, + WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF, }; + /** * enum userspace_log_level - Log level at userspace * @LOG_LEVEL_NO_COLLECTION: verbose_level 0 corresponds to no collection diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 45265686cd83..3dbf1ff563e0 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -868,6 +868,10 @@ uint8_t lim_write_deferred_msg_q(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg) FL("queue->MsgQ full Msg:%d Msgs Failed:%d"), lim_msg->type, ++mac_ctx->lim.deferredMsgCnt); + cds_flush_logs(WLAN_LOG_TYPE_NON_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_QUEUE_FULL, + true, false); } else { mac_ctx->lim.deferredMsgCnt++; } diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index dd566f26ed17..3071a777c1c7 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -1221,6 +1221,7 @@ typedef struct tagCsrConfigParam { uint32_t obss_active_dwelltime; uint32_t obss_passive_dwelltime; bool ignore_peer_ht_opmode; + bool enable_fatal_event; } tCsrConfigParam; /* Tush */ diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index 15ce478fd687..4ed2c5597b42 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -639,6 +639,7 @@ typedef struct tagCsrConfig { uint32_t obss_active_dwelltime; uint32_t obss_passive_dwelltime; bool ignore_peer_ht_opmode; + bool enable_fatal_event; } tCsrConfig; typedef struct tagCsrChannelPowerInfo { diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 06ba472c1d42..c691401bebee 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -621,8 +621,16 @@ tSmeCmd *sme_get_command_buffer(tpAniSirGlobal pMac) sme_command_queue_full++; csr_ll_unlock(&pMac->roam.roamCmdPendingList); - /* panic with out-of-command */ - QDF_BUG(0); + if (pMac->roam.configParam.enable_fatal_event) + cds_flush_logs(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF, + false, + pMac->sme.enableSelfRecovery ? true : false); + else if (pMac->sme.enableSelfRecovery) + cds_trigger_recovery(); + else + QDF_BUG(0); } /* memset to zero */ @@ -11682,19 +11690,41 @@ void sme_save_active_cmd_stats(tHalHandle hHal) void active_list_cmd_timeout_handle(void *userData) { - if (NULL == userData) - return; - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "%s: Active List command timeout Cmd List Count %d", __func__, - csr_ll_count(&((tpAniSirGlobal) userData)->sme. - smeCmdActiveList)); - sme_get_command_q_status((tHalHandle) userData); + tHalHandle hal = (tHalHandle)userData; + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); - if (((tpAniSirGlobal) userData)->sme.enableSelfRecovery) { - sme_save_active_cmd_stats((tHalHandle) userData); + if (NULL == mac_ctx) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + "%s: mac_ctx is null", __func__); + return; + } + /* Return if no cmd pending in active list as + * in this case we should not be here. + */ + if (0 == csr_ll_count(&mac_ctx->sme.smeCmdActiveList)) + return; + sms_log(mac_ctx, LOGE, + FL("Active List command timeout Cmd List Count %d"), + csr_ll_count(&mac_ctx->sme.smeCmdActiveList)); + sme_get_command_q_status(hal); + + if (mac_ctx->roam.configParam.enable_fatal_event) + cds_flush_logs(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_SME_COMMAND_STUCK, + false, + mac_ctx->sme.enableSelfRecovery ? true : false); + else + qdf_trace_dump_all(mac_ctx, 0, 0, 500, 0); + + if (mac_ctx->sme.enableSelfRecovery) { + sme_save_active_cmd_stats(hal); cds_trigger_recovery(); } else { - QDF_BUG(0); + if (!mac_ctx->roam.configParam.enable_fatal_event && + !(cds_is_load_or_unload_in_progress() || + cds_is_driver_recovering())) + QDF_BUG(0); } } diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 342ff292a210..d0b29e2129a8 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -2353,6 +2353,8 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac, pParam->early_stop_scan_min_threshold; pMac->roam.configParam.early_stop_scan_max_threshold = pParam->early_stop_scan_max_threshold; + pMac->roam.configParam.enable_fatal_event = + pParam->enable_fatal_event; } return status; @@ -2536,6 +2538,8 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam) pParam->enableHtSmps = pMac->roam.configParam.enableHtSmps; pParam->htSmps = pMac->roam.configParam.htSmps; pParam->send_smps_action = pMac->roam.configParam.send_smps_action; + pParam->enable_fatal_event = + pMac->roam.configParam.enable_fatal_event; return QDF_STATUS_SUCCESS; } @@ -8672,6 +8676,10 @@ static void csr_roam_roaming_state_reassoc_rsp_processor(tpAniSirGlobal pMac, "CSR SmeReassocReq failed with statusCode= 0x%08X [%d]", pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode); result = eCsrReassocFailure; + cds_flush_logs(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_ROAM_FAIL, + true, false); if ((eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE == pSmeJoinRsp->statusCode) || (eSIR_SME_FT_REASSOC_FAILURE == diff --git a/core/utils/logging/inc/wlan_logging_sock_svc.h b/core/utils/logging/inc/wlan_logging_sock_svc.h index 1850a0138466..d0b76d1aed9a 100644 --- a/core/utils/logging/inc/wlan_logging_sock_svc.h +++ b/core/utils/logging/inc/wlan_logging_sock_svc.h @@ -46,6 +46,7 @@ int wlan_log_to_user(QDF_TRACE_LEVEL log_level, char *to_be_sent, int length); void wlan_logging_set_per_pkt_stats(void); void wlan_logging_set_log_level(void); void wlan_logging_set_fw_flush_complete(void); +void wlan_flush_host_logs_for_fatal(void); #ifdef FEATURE_WLAN_DIAG_SUPPORT void wlan_report_log_completion(uint32_t is_fatal, uint32_t indicator, @@ -57,5 +58,9 @@ static inline void wlan_report_log_completion(uint32_t is_fatal, { return; } +static inline void wlan_flush_host_logs_for_fatal(void) +{ +} + #endif /* FEATURE_WLAN_DIAG_SUPPORT */ #endif /* WLAN_LOGGING_SOCK_SVC_H */ diff --git a/core/utils/logging/src/wlan_logging_sock_svc.c b/core/utils/logging/src/wlan_logging_sock_svc.c index 15687a2f7e15..c0c854f05bd4 100644 --- a/core/utils/logging/src/wlan_logging_sock_svc.c +++ b/core/utils/logging/src/wlan_logging_sock_svc.c @@ -39,6 +39,7 @@ #include #include "pktlog_ac.h" #include +#include "cds_utils.h" #define LOGGING_TRACE(level, args ...) \ QDF_TRACE(QDF_MODULE_ID_HDD, level, ## args) @@ -505,14 +506,19 @@ void wlan_report_log_completion(uint32_t is_fatal, void send_flush_completion_to_user(void) { uint32_t is_fatal, indicator, reason_code; + bool recovery_needed; - cds_get_log_completion(&is_fatal, &indicator, &reason_code); + cds_get_and_reset_log_completion(&is_fatal, + &indicator, &reason_code, &recovery_needed); /* Error on purpose, so that it will get logged in the kmsg */ LOGGING_TRACE(QDF_TRACE_LEVEL_ERROR, "%s: Sending flush done to userspace", __func__); wlan_report_log_completion(is_fatal, indicator, reason_code); + + if (recovery_needed) + cds_trigger_recovery(); } /** @@ -525,6 +531,7 @@ static int wlan_logging_thread(void *Arg) { int ret_wait_status = 0; int ret = 0; + unsigned long flags; set_user_nice(current, -2); @@ -561,6 +568,10 @@ static int wlan_logging_thread(void *Arg) ret = send_filled_buffers_to_user(); if (-ENOMEM == ret) msleep(200); + if (WLAN_LOG_INDICATOR_HOST_ONLY == + cds_get_log_indicator()) { + send_flush_completion_to_user(); + } } if (test_and_clear_bit(HOST_LOG_PER_PKT_STATS, @@ -582,6 +593,12 @@ static int wlan_logging_thread(void *Arg) send_flush_completion_to_user(); } else { gwlan_logging.is_flush_complete = true; + /* Flush all current host logs*/ + spin_lock_irqsave(&gwlan_logging.spin_lock, + flags); + wlan_queue_logmsg_for_app(); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, + flags); set_bit(HOST_LOG_DRIVER_MSG, &gwlan_logging.eventFlag); set_bit(HOST_LOG_PER_PKT_STATS, @@ -804,10 +821,35 @@ void wlan_logging_set_log_level(void) */ void wlan_logging_set_fw_flush_complete(void) { - if (gwlan_logging.is_active == false) + if (gwlan_logging.is_active == false || + !cds_is_fatal_event_enabled()) return; set_bit(HOST_LOG_FW_FLUSH_COMPLETE, &gwlan_logging.eventFlag); wake_up_interruptible(&gwlan_logging.wait_queue); } + +/** + * wlan_flush_host_logs_for_fatal() - Flush host logs + * + * This function is used to send signal to the logger thread to + * Flush the host logs + * + * Return: None + */ +void wlan_flush_host_logs_for_fatal(void) +{ + unsigned long flags; + + if (cds_is_log_report_in_progress()) { + pr_info("%s:flush all host logs Setting HOST_LOG_POST_MASK\n", + __func__); + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + wlan_queue_logmsg_for_app(); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + set_bit(HOST_LOG_DRIVER_MSG, &gwlan_logging.eventFlag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } +} + #endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index d679a6f9b0e1..d068183616bf 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -2269,7 +2269,7 @@ static int wma_flush_complete_evt_handler(void *handle, reason_code); status = cds_set_log_completion(WLAN_LOG_TYPE_FATAL, WLAN_LOG_INDICATOR_FIRMWARE, - reason_code); + reason_code, false); if (QDF_STATUS_SUCCESS != status) { WMA_LOGE("%s: Failed to set log trigger params", __func__); -- cgit v1.2.3 From 371d4a934097cad7314f6e4776803095a6234d8a Mon Sep 17 00:00:00 2001 From: Houston Hoffman Date: Thu, 14 Apr 2016 17:02:37 -0700 Subject: qcacld-3.0: Use qdf macro for epping mode Use QDF macro to check if we are in epping mode. Remove bit masks of epping configuration. Change-Id: I454ef259dfcc4b7c7860a5adfda605837f4a89cc CRs-Fixed: 1003792 --- core/bmi/src/ol_fw.c | 8 +++----- core/dp/txrx/ol_txrx.c | 4 ++-- core/hdd/src/wlan_hdd_driver_ops.c | 10 +++++----- core/hdd/src/wlan_hdd_main.c | 2 +- core/utils/epping/inc/epping_main.h | 4 ---- core/utils/epping/src/epping_main.c | 22 ++++++++++++++++++++++ 6 files changed, 33 insertions(+), 17 deletions(-) diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c index e47ff72fa311..b3b9380870b7 100644 --- a/core/bmi/src/ol_fw.c +++ b/core/bmi/src/ol_fw.c @@ -173,7 +173,7 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, #endif break; case ATH_FIRMWARE_FILE: - if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) { + if (QDF_IS_EPPING_ENABLED(cds_get_conparam())) { #if defined(CONFIG_CNSS) filename = bmi_ctx->fw_files.epping_file; #else @@ -237,7 +237,7 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, break; case ATH_SETUP_FILE: if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE && - !WLAN_IS_EPPING_ENABLED(cds_get_conparam())) { + !QDF_IS_EPPING_ENABLED(cds_get_conparam())) { #ifdef CONFIG_CNSS BMI_INFO("%s: no Setup file defined", __func__); return -1; @@ -1332,9 +1332,7 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx) (uint8_t *) &address, 4, ol_ctx); } - if (ini_cfg->enable_uart_print || - (WLAN_IS_EPPING_ENABLED(cds_get_conparam()) && - WLAN_IS_EPPING_FW_UART(cds_get_conparam()))) { + if (ini_cfg->enable_uart_print) { switch (target_version) { case AR6004_VERSION_REV1_3: param = 11; diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index ff9f0a8180ce..6d8ca0f40a75 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -470,7 +470,7 @@ void htt_pkt_log_init(struct ol_txrx_pdev_t *handle, void *scn) return; if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE && - !WLAN_IS_EPPING_ENABLED(cds_get_conparam())) { + !QDF_IS_EPPING_ENABLED(cds_get_conparam())) { ol_pl_sethandle(&handle->pl_dev, scn); if (pktlogmod_init(scn)) qdf_print("%s: pktlogmod_init failed", __func__); @@ -489,7 +489,7 @@ void htt_pkt_log_init(struct ol_txrx_pdev_t *handle, void *scn) void htt_pktlogmod_exit(struct ol_txrx_pdev_t *handle, void *scn) { if (scn && cds_get_conparam() != QDF_GLOBAL_FTM_MODE && - !WLAN_IS_EPPING_ENABLED(cds_get_conparam()) && + !QDF_IS_EPPING_ENABLED(cds_get_conparam()) && handle->pkt_log_init) { pktlogmod_exit(scn); handle->pkt_log_init = false; diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index 1649840e98ae..4b80d6933d72 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -353,7 +353,7 @@ static int wlan_hdd_probe(struct device *dev, void *bdev, const hif_bus_id *bid, cds_set_load_in_progress(true); } - if (WLAN_IS_EPPING_ENABLED(mode)) { + if (QDF_IS_EPPING_ENABLED(mode)) { status = epping_open(); if (status != QDF_STATUS_SUCCESS) goto err_hdd_deinit; @@ -403,7 +403,7 @@ err_bmi_close: err_hif_close: hdd_hif_close(hif_ctx); err_epping_close: - if (WLAN_IS_EPPING_ENABLED(mode)) + if (QDF_IS_EPPING_ENABLED(mode)) epping_close(); err_hdd_deinit: cds_set_load_in_progress(false); @@ -457,7 +457,7 @@ static void wlan_hdd_remove(void) hif_disable_power_management(hif_ctx); - if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) { + if (QDF_IS_EPPING_ENABLED(cds_get_conparam())) { epping_disable(); epping_close(); } else { @@ -493,7 +493,7 @@ static void wlan_hdd_shutdown(void) if (!cds_wait_for_external_threads_completion(__func__)) hdd_err("Host is not ready for SSR, attempting anyway"); - if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam())) { + if (!QDF_IS_EPPING_ENABLED(cds_get_conparam())) { hif_disable_isr(hif_ctx); hdd_wlan_shutdown(); } @@ -527,7 +527,7 @@ void wlan_hdd_crash_shutdown(void) */ void wlan_hdd_notify_handler(int state) { - if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam())) { + if (!QDF_IS_EPPING_ENABLED(cds_get_conparam())) { int ret = 0; ret = hdd_wlan_notify_modem_power_state(state); if (ret < 0) diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 552f7c9e04f2..bdfbdc3894b9 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5723,7 +5723,7 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) ENTER(); - if (WLAN_IS_EPPING_ENABLED(con_mode)) { + if (QDF_IS_EPPING_ENABLED(con_mode)) { ret = epping_enable(dev); EXIT(); return ret; diff --git a/core/utils/epping/inc/epping_main.h b/core/utils/epping/inc/epping_main.h index 6d29f0f175a7..813109fecade 100644 --- a/core/utils/epping/inc/epping_main.h +++ b/core/utils/epping/inc/epping_main.h @@ -41,10 +41,6 @@ #include #include -#define WLAN_IS_EPPING_ENABLED(x) (x == QDF_GLOBAL_EPPING_MODE) -#define WLAN_IS_EPPING_IRQ(x) 1 -#define WLAN_IS_EPPING_FW_UART(x) 0 - /* epping_main signatures */ int epping_open(void); void epping_close(void); diff --git a/core/utils/epping/src/epping_main.c b/core/utils/epping/src/epping_main.c index a0ebc9cc9b7d..6f9380f02750 100644 --- a/core/utils/epping/src/epping_main.c +++ b/core/utils/epping/src/epping_main.c @@ -164,6 +164,27 @@ static void epping_target_suspend_acknowledge(void *context) g_epping_ctx->wow_nack = wow_nack; } +/** + * epping_update_ol_config - API to update ol configuration parameters + * + * Return: void + */ +static void epping_update_ol_config(void) +{ + struct ol_config_info cfg; + struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI); + + if (!ol_ctx) + return; + + cfg.enable_self_recovery = 0; + cfg.enable_uart_print = 0; + cfg.enable_fw_log = 0; + cfg.enable_ramdump_collection = 0; + cfg.enable_lpass_support = 0; + + ol_init_ini_config(ol_ctx, &cfg); +} /** * epping_enable(): End point ping driver enable Function * @@ -221,6 +242,7 @@ int epping_enable(struct device *parent_dev) pEpping_ctx->target_type = tgt_info->target_type; ol_ctx = cds_get_context(QDF_MODULE_ID_BMI); + epping_update_ol_config(); #ifndef FEATURE_BMI_2 /* Initialize BMI and Download firmware */ if (bmi_download_firmware(ol_ctx)) { -- cgit v1.2.3 From a769ed3ba13b4e9d6c1daf9e72c513690617b9e2 Mon Sep 17 00:00:00 2001 From: Houston Hoffman Date: Thu, 14 Apr 2016 17:02:51 -0700 Subject: qcacld-3.0: Add wow_nack to TargetSendSuspendComplete api TargetSendSuspendComplete should take the HTCInitInfo context as an argument. The wow_nack should be its own argument. Change-Id: Ib13385cf0a04730d066ffcd53c1f669c7a5ced60 CRs-Fixed: 1003793 --- core/utils/epping/inc/epping_internal.h | 2 +- core/utils/epping/src/epping_main.c | 9 ++++++--- core/wma/inc/wma_api.h | 2 +- core/wma/src/wma_features.c | 8 ++++---- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/core/utils/epping/inc/epping_internal.h b/core/utils/epping/inc/epping_internal.h index 664076d7a523..3ae69fbfe09f 100644 --- a/core/utils/epping/inc/epping_internal.h +++ b/core/utils/epping/inc/epping_internal.h @@ -111,7 +111,7 @@ typedef struct epping_context { void *p_cds_context; /* CDS context */ struct device *parent_dev; /* Pointer to the parent device */ epping_ctx_state_t e_ctx_state; - int wow_nack; + bool wow_nack; void *epping_adapter; HTC_HANDLE HTCHandle; HTC_ENDPOINT_ID EppingEndpoint[EPPING_MAX_NUM_EPIDS]; diff --git a/core/utils/epping/src/epping_main.c b/core/utils/epping/src/epping_main.c index 6f9380f02750..44ddc824b9ca 100644 --- a/core/utils/epping/src/epping_main.c +++ b/core/utils/epping/src/epping_main.c @@ -151,10 +151,13 @@ void epping_close(void) qdf_mem_free(to_free); } -static void epping_target_suspend_acknowledge(void *context) +/** + * epping_target_suspend_acknowledge() - process wow ack/nack from fw + * @context: HTC_INIT_INFO->context + * @wow_nack: true when wow is rejected + */ +static void epping_target_suspend_acknowledge(void *context, bool wow_nack) { - int wow_nack = *((int *)context); - if (NULL == g_epping_ctx) { EPPING_LOG(QDF_TRACE_LEVEL_FATAL, "%s: epping_ctx is NULL", __func__); diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h index 4bf40d266470..039202571f2a 100644 --- a/core/wma/inc/wma_api.h +++ b/core/wma/inc/wma_api.h @@ -123,7 +123,7 @@ int wma_runtime_suspend(void); int wma_runtime_resume(void); int wma_bus_suspend(void); QDF_STATUS wma_suspend_target(WMA_HANDLE handle, int disable_target_intr); -void wma_target_suspend_acknowledge(void *context); +void wma_target_suspend_acknowledge(void *context, bool wow_nack); int wma_bus_resume(void); QDF_STATUS wma_resume_target(WMA_HANDLE handle); QDF_STATUS wma_disable_wow_in_fw(WMA_HANDLE handle); diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index d23e1cbd2192..b8727ca1d3e7 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -3246,7 +3246,7 @@ QDF_STATUS wma_enable_wow_in_fw(WMA_HANDLE handle) #endif /* CONFIG_CNSS */ qdf_event_reset(&wma->target_suspend); - wma->wow_nack = 0; + wma->wow_nack = false; host_credits = wmi_get_host_credits(wma->wmi_handle); wmi_pending_cmds = wmi_get_pending_cmds(wma->wmi_handle); @@ -5925,14 +5925,14 @@ QDF_STATUS wma_suspend_target(WMA_HANDLE handle, int disable_target_intr) /** * wma_target_suspend_acknowledge() - update target susspend status - * @context: wma context + * @context: HTC_INIT_INFO->context + * @wow_nack: true when wow is rejected * * Return: none */ -void wma_target_suspend_acknowledge(void *context) +void wma_target_suspend_acknowledge(void *context, bool wow_nack) { tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); - int wow_nack = *((int *)context); if (NULL == wma) { WMA_LOGE("%s: wma is NULL", __func__); -- cgit v1.2.3 From 9d774379a8579578cf3d5fccc2b456681e6ff234 Mon Sep 17 00:00:00 2001 From: Komal Seelam Date: Mon, 11 Apr 2016 17:11:42 +0530 Subject: qcacld-3.0: Remove ol_target_status in ol layer Move ol_target_status to hif and rename it hif_target_status Change-Id: Ia9dcb5f5b0d416f930968957ce8a3166ca7056bc CRs-Fixed: 998536 --- core/bmi/inc/ol_if_athvar.h | 8 -------- core/bmi/src/ol_fw.c | 7 +++---- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/core/bmi/inc/ol_if_athvar.h b/core/bmi/inc/ol_if_athvar.h index cf0e1c81634c..1eb13f2f76de 100644 --- a/core/bmi/inc/ol_if_athvar.h +++ b/core/bmi/inc/ol_if_athvar.h @@ -45,7 +45,6 @@ #endif #include "ol_ctrl_addba_api.h" -typedef void *hif_handle_t; struct ol_version { uint32_t host_ver; @@ -55,13 +54,6 @@ struct ol_version { uint32_t abi_ver; }; -typedef enum _ol_target_status { - OL_TRGET_STATUS_CONNECTED = 0, /* target connected */ - OL_TRGET_STATUS_RESET, /* target got reset */ - OL_TRGET_STATUS_EJECT, /* target got ejected */ - OL_TRGET_STATUS_SUSPEND /*target got suspend */ -} ol_target_status; - enum ol_ath_tx_ecodes { TX_IN_PKT_INCR = 0, TX_OUT_HDR_COMPL, diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c index b3b9380870b7..992a3caed63a 100644 --- a/core/bmi/src/ol_fw.c +++ b/core/bmi/src/ol_fw.c @@ -621,8 +621,7 @@ void ol_target_failure(void *instance, QDF_STATUS status) struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx); int ret; #endif - ol_target_status target_status = - hif_get_target_status(scn); + enum hif_target_status target_status = hif_get_target_status(scn); if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SNOC) { BMI_ERR("SNOC doesn't suppor this code path!"); @@ -631,12 +630,12 @@ void ol_target_failure(void *instance, QDF_STATUS status) qdf_event_set(&wma->recovery_event); - if (OL_TRGET_STATUS_RESET == target_status) { + if (TARGET_STATUS_RESET == target_status) { BMI_ERR("Target is already asserted, ignore!"); return; } - hif_set_target_status(scn, OL_TRGET_STATUS_RESET); + hif_set_target_status(scn, TARGET_STATUS_RESET); if (cds_is_driver_recovering()) { BMI_ERR("%s: Recovery in progress, ignore!\n", __func__); -- cgit v1.2.3 From 05d71f7eeb35374f34ef371fe23cf900a2ddd3f6 Mon Sep 17 00:00:00 2001 From: Houston Hoffman Date: Wed, 27 Apr 2016 18:27:33 -0700 Subject: qcacld-3.0: Define SLOTS_PER_DATAPATH_TX in common project Common project be self contained as much as possible. Change-Id: I9dd3cea3b9b2563960dd5d81a661c9ac1e61ac0d CRs-Fixed: 1009290 --- uapi/linux/osapi_linux.h | 1 - 1 file changed, 1 deletion(-) diff --git a/uapi/linux/osapi_linux.h b/uapi/linux/osapi_linux.h index 21f8ff629ab1..a62b96d3f613 100644 --- a/uapi/linux/osapi_linux.h +++ b/uapi/linux/osapi_linux.h @@ -231,7 +231,6 @@ void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q); #include "ath_carr_pltfrm.h" #endif /* QCA_PARTNER_PLATFORM */ -#define SLOTS_PER_DATAPATH_TX 2 #else /* __KERNEL__ */ #ifdef __GNUC__ -- cgit v1.2.3 From ea4c79c0121beff7ae4d186cd39a36698c24e92a Mon Sep 17 00:00:00 2001 From: Houston Hoffman Date: Thu, 21 Apr 2016 20:20:31 -0700 Subject: qcacld-3.0: Remove ifdefs of QCA_SIGNED_SPLIT_BINARY_SUPPORT Remove QCA_SIGNED_SPLIT_BINARY_SUPPORT ifdefs from __ol_transfer_bin_file function body. Change-Id: Ic801c5aa1e4019ec0e4ceca7b1818848aae0f365 CRs-Fixed: 1010214 --- core/bmi/src/i_bmi.h | 2 ++ core/bmi/src/ol_fw.c | 66 +++++++++++++++++++++------------------------------- 2 files changed, 28 insertions(+), 40 deletions(-) diff --git a/core/bmi/src/i_bmi.h b/core/bmi/src/i_bmi.h index ae92ca97f93b..6661b200f7a6 100644 --- a/core/bmi/src/i_bmi.h +++ b/core/bmi/src/i_bmi.h @@ -187,6 +187,8 @@ QDF_STATUS bmi_firmware_download(struct ol_context *ol_ctx); QDF_STATUS bmi_done_local(struct ol_context *ol_ctx); QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx); QDF_STATUS ol_configure_target(struct ol_context *ol_ctx); +QDF_STATUS bmi_sign_stream_start(uint32_t address, uint8_t *buffer, + uint32_t length, struct ol_context *ol_ctx); void ramdump_work_handler(void *arg); struct ol_config_info *ol_get_ini_handle(struct ol_context *ol_ctx); #endif diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c index 992a3caed63a..98770253e4e7 100644 --- a/core/bmi/src/ol_fw.c +++ b/core/bmi/src/ol_fw.c @@ -135,6 +135,12 @@ end: } #endif +#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT +#define SIGNED_SPLIT_BINARY_VALUE true +#else +#define SIGNED_SPLIT_BINARY_VALUE false +#endif + static int __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, uint32_t address, bool compressed) @@ -146,11 +152,9 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, uint32_t fw_entry_size; uint8_t *temp_eeprom; uint32_t board_data_size; -#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT bool bin_sign = false; int bin_off, bin_len; SIGN_HEADER_T *sign_header; -#endif struct hif_target_info *tgt_info = hif_get_target_info_handle(scn); uint32_t target_type = tgt_info->target_type; #if defined(CONFIG_CNSS) @@ -168,9 +172,9 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, #else filename = QCA_OTP_FILE; #endif -#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT - bin_sign = true; -#endif + if (SIGNED_SPLIT_BINARY_VALUE) + bin_sign = true; + break; case ATH_FIRMWARE_FILE: if (QDF_IS_EPPING_ENABLED(cds_get_conparam())) { @@ -190,9 +194,8 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, #else filename = QCA_UTF_FIRMWARE_FILE; #endif -#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT - bin_sign = true; -#endif + if (SIGNED_SPLIT_BINARY_VALUE) + bin_sign = true; BMI_INFO("%s: Loading firmware file %s", __func__, filename); break; @@ -203,9 +206,8 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, #else filename = QCA_FIRMWARE_FILE; #endif -#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT - bin_sign = true; -#endif + if (SIGNED_SPLIT_BINARY_VALUE) + bin_sign = true; break; case ATH_PATCH_FILE: BMI_INFO("%s: no Patch file defined", __func__); @@ -218,9 +220,9 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, #else filename = QCA_BOARD_DATA_FILE; #endif -#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT - bin_sign = true; -#endif + if (SIGNED_SPLIT_BINARY_VALUE) + bin_sign = true; + BMI_INFO("%s: Loading board data file %s", __func__, filename); break; @@ -231,9 +233,9 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, #else filename = QCA_BOARD_DATA_FILE; #endif -#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT - bin_sign = false; -#endif + if (SIGNED_SPLIT_BINARY_VALUE) + bin_sign = false; + break; case ATH_SETUP_FILE: if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE && @@ -243,9 +245,10 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, return -1; #else filename = QCA_SETUP_FILE; -#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT - bin_sign = true; -#endif + + if (SIGNED_SPLIT_BINARY_VALUE) + bin_sign = true; + BMI_INFO("%s: Loading setup file %s", __func__, filename); #endif /* CONFIG_CNSS */ @@ -362,8 +365,8 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, fw_entry_size = board_data_size; } } -#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT - if (bin_sign) { + + if (bin_sign && SIGNED_SPLIT_BINARY_VALUE) { uint32_t chip_id; if (fw_entry_size < sizeof(SIGN_HEADER_T)) { @@ -417,7 +420,7 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, } } - if (bin_sign) { + if (bin_sign && SIGNED_SPLIT_BINARY_VALUE) { bin_off += bin_len; bin_len = sign_header->total_len - sign_header->rampatch_len; @@ -429,23 +432,6 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, BMI_ERR("sign stream error"); } } -#else - if (compressed) { - status = bmi_fast_download(address, - (uint8_t *) fw_entry->data, - fw_entry_size, ol_ctx); - } else { - if (file == ATH_BOARD_DATA_FILE && fw_entry->data) { - status = bmi_write_memory(address, - (uint8_t *) temp_eeprom, - fw_entry_size, ol_ctx); - } else { - status = bmi_write_memory(address, - (uint8_t *) fw_entry->data, - fw_entry_size, ol_ctx); - } - } -#endif /* QCA_SIGNED_SPLIT_BINARY_SUPPORT */ end: if (temp_eeprom) -- cgit v1.2.3 From 0cde9662a99c7c5009d3c7719ffa79646f15c6d1 Mon Sep 17 00:00:00 2001 From: Houston Hoffman Date: Mon, 25 Apr 2016 16:06:07 -0700 Subject: qcacld-3.0: Remove ifdefs from __ol_transfer_bin_file __ol_transfer_bin_file is overly complex because of the ifdefs. Change-Id: Ie758476b94561d4d67b0fe051c5a72035f2df0ec CRs-Fixed: 1010214 --- core/bmi/src/i_bmi.h | 12 ++++++++++++ core/bmi/src/ol_fw.c | 49 ++++++++++++++++--------------------------------- 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/core/bmi/src/i_bmi.h b/core/bmi/src/i_bmi.h index 6661b200f7a6..1cdc0d2896ef 100644 --- a/core/bmi/src/i_bmi.h +++ b/core/bmi/src/i_bmi.h @@ -40,12 +40,24 @@ #include "bmi.h" #include "ol_fw.h" +#ifdef CONFIG_CNSS +#define QCA_FIRMWARE_FILE fw_files->image_file +#define QCA_UTF_FIRMWARE_FILE fw_files->utf_file +#define QCA_BOARD_DATA_FILE fw_files->board_data +#define QCA_UTF_BOARD_DATA_FILE fw_files->utf_board_data +#define QCA_OTP_FILE fw_files->otp_data +#define QCA_SETUP_FILE NULL +#define QCA_FIRMWARE_EPPING_FILE fw_files->epping_file +#else #define QCA_FIRMWARE_FILE "athwlan.bin" #define QCA_UTF_FIRMWARE_FILE "utf.bin" #define QCA_BOARD_DATA_FILE "fakeboar.bin" +#define QCA_UTF_BOARD_DATA_FILE "fakeboar.bin" #define QCA_OTP_FILE "otp.bin" #define QCA_SETUP_FILE "athsetup.bin" #define QCA_FIRMWARE_EPPING_FILE "epping.bin" +#endif + /* * Note that not all the register locations are accessible. * A list of accessible target registers are specified with diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c index 98770253e4e7..2950a69ebd50 100644 --- a/core/bmi/src/ol_fw.c +++ b/core/bmi/src/ol_fw.c @@ -141,6 +141,12 @@ end: #define SIGNED_SPLIT_BINARY_VALUE false #endif +#ifdef CONFIG_CNSS +#define CONFIG_CNSS_DEFINED true +#else +#define CONFIG_CNSS_DEFINED false +#endif + static int __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, uint32_t address, bool compressed) @@ -158,7 +164,9 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, struct hif_target_info *tgt_info = hif_get_target_info_handle(scn); uint32_t target_type = tgt_info->target_type; #if defined(CONFIG_CNSS) + /* fw_files variable used in filename assignment macros */ struct bmi_info *bmi_ctx = GET_BMI_CONTEXT(ol_ctx); + struct cnss_fw_files *fw_files = &bmi_ctx->fw_files; #endif qdf_device_t qdf_dev = ol_ctx->qdf_dev; @@ -167,33 +175,21 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, BMI_ERR("%s: Unknown file type", __func__); return -1; case ATH_OTP_FILE: -#if defined(CONFIG_CNSS) - filename = bmi_ctx->fw_files.otp_data; -#else filename = QCA_OTP_FILE; -#endif if (SIGNED_SPLIT_BINARY_VALUE) bin_sign = true; break; case ATH_FIRMWARE_FILE: if (QDF_IS_EPPING_ENABLED(cds_get_conparam())) { -#if defined(CONFIG_CNSS) - filename = bmi_ctx->fw_files.epping_file; -#else filename = QCA_FIRMWARE_EPPING_FILE; -#endif BMI_INFO("%s: Loading epping firmware file %s", __func__, filename); break; } #ifdef QCA_WIFI_FTM if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) { -#if defined(CONFIG_CNSS) - filename = bmi_ctx->fw_files.utf_file; -#else filename = QCA_UTF_FIRMWARE_FILE; -#endif if (SIGNED_SPLIT_BINARY_VALUE) bin_sign = true; BMI_INFO("%s: Loading firmware file %s", @@ -201,11 +197,7 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, break; } #endif -#if defined(CONFIG_CNSS) - filename = bmi_ctx->fw_files.image_file; -#else filename = QCA_FIRMWARE_FILE; -#endif if (SIGNED_SPLIT_BINARY_VALUE) bin_sign = true; break; @@ -213,13 +205,11 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, BMI_INFO("%s: no Patch file defined", __func__); return 0; case ATH_BOARD_DATA_FILE: + #ifdef QCA_WIFI_FTM if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) { -#if defined(CONFIG_CNSS) - filename = bmi_ctx->fw_files.utf_board_data; -#else - filename = QCA_BOARD_DATA_FILE; -#endif + filename = QCA_UTF_BOARD_DATA_FILE; + if (SIGNED_SPLIT_BINARY_VALUE) bin_sign = true; @@ -228,22 +218,19 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, break; } #endif /* QCA_WIFI_FTM */ -#if defined(CONFIG_CNSS) - filename = bmi_ctx->fw_files.board_data; -#else filename = QCA_BOARD_DATA_FILE; -#endif + if (SIGNED_SPLIT_BINARY_VALUE) bin_sign = false; break; case ATH_SETUP_FILE: - if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE && - !QDF_IS_EPPING_ENABLED(cds_get_conparam())) { -#ifdef CONFIG_CNSS + if (CONFIG_CNSS_DEFINED || + cds_get_conparam() == QDF_GLOBAL_FTM_MODE || + QDF_IS_EPPING_ENABLED(cds_get_conparam())) { BMI_INFO("%s: no Setup file defined", __func__); return -1; -#else + } else { filename = QCA_SETUP_FILE; if (SIGNED_SPLIT_BINARY_VALUE) @@ -251,10 +238,6 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, BMI_INFO("%s: Loading setup file %s", __func__, filename); -#endif /* CONFIG_CNSS */ - } else { - BMI_INFO("%s: no Setup file needed", __func__); - return -1; } break; } -- cgit v1.2.3 From 90e24d85f8675c86754cea900fe6b5808ca2bb82 Mon Sep 17 00:00:00 2001 From: Houston Hoffman Date: Wed, 27 Apr 2016 17:15:44 -0700 Subject: qcacld-3.0: Add hif_ctx to fastpath_cb_register api Hif apis can't rely on a global context. Change-Id: I2cad80573fc0102f210bb0f7c3f9e22c5f8e16f9 CRs-fixed: 1009274 --- core/dp/htt/htt.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/core/dp/htt/htt.c b/core/dp/htt/htt.c index 1672a39c2ea5..fe30c3405d3a 100644 --- a/core/dp/htt/htt.c +++ b/core/dp/htt/htt.c @@ -137,6 +137,14 @@ void htt_htc_misc_pkt_pool_free(struct htt_pdev_t *pdev) } #endif + +/* AR6004 don't need HTT layer. */ +#ifdef AR6004_HW +#define NO_HTT_NEEDED true +#else +#define NO_HTT_NEEDED false +#endif + /** * htt_pdev_alloc() - allocate HTT pdev * @txrx_pdev: txrx pdev @@ -152,6 +160,10 @@ htt_pdev_alloc(ol_txrx_pdev_handle txrx_pdev, HTC_HANDLE htc_pdev, qdf_device_t osdev) { struct htt_pdev_t *pdev; + struct hif_opaque_softc *osc = cds_get_context(QDF_MODULE_ID_HIF); + + if (!osc) + goto fail1; pdev = qdf_mem_malloc(sizeof(*pdev)); if (!pdev) @@ -186,14 +198,14 @@ htt_pdev_alloc(ol_txrx_pdev_handle txrx_pdev, HTT_SET_WIFI_IP(pdev, 2, 0); #endif /* defined(HELIUMPLUS_PADDR64) */ + if (NO_HTT_NEEDED) + goto success; /* * Connect to HTC service. * This has to be done before calling htt_rx_attach, * since htt_rx_attach involves sending a rx ring configure * message to the target. */ -/* AR6004 don't need HTT layer. */ -#ifndef AR6004_HW if (htt_htc_attach(pdev, HTT_DATA_MSG_SVC)) goto fail2; if (htt_htc_attach(pdev, HTT_DATA2_MSG_SVC)) @@ -204,11 +216,10 @@ htt_pdev_alloc(ol_txrx_pdev_handle txrx_pdev, ; /* TODO: enable the following line once FW is ready */ /* goto fail2; */ - if (hif_ce_fastpath_cb_register(htt_t2h_msg_handler_fast, pdev)) + if (hif_ce_fastpath_cb_register(osc, htt_t2h_msg_handler_fast, pdev)) qdf_print("failed to register fastpath callback\n"); -#endif - +success: return pdev; fail2: -- cgit v1.2.3 From ebf8a8640e2122225f96ad619978e4e227813ba3 Mon Sep 17 00:00:00 2001 From: Mohit Khanna Date: Thu, 28 Apr 2016 17:53:59 -0700 Subject: qcacld-3.0: Fix use-after-free crash for trace buffer There is a race condition between hdd_disconnect_handler and cds_pkt_proto_trace_close while trying to update the trace_buffer. Fix race condition by calling cds_pkt_proto_trace_deinit (formerly cds_pkt_proto_trace_close) at the end of cds_close, after all the threads have been torn down and other modules have been shut. Similarly, call cds_pkt_proto_trace_init at the begining of cds_open, so it gets initialized before any of the threads are up or any modules have been initialized. Change-Id: If9e2d6a360d814b7f1b0c92789dc0fd3fe3d974b CRs-Fixed: 1009162 --- core/cds/inc/cds_packet.h | 51 ++++++++++++++++++-------------------- core/cds/src/cds_api.c | 6 +++++ core/cds/src/cds_packet.c | 58 +++++++++++++++++++++++++++----------------- core/hdd/src/wlan_hdd_main.c | 6 +---- 4 files changed, 66 insertions(+), 55 deletions(-) diff --git a/core/cds/inc/cds_packet.h b/core/cds/inc/cds_packet.h index f63e9033345c..e85ebb3d34a6 100644 --- a/core/cds/inc/cds_packet.h +++ b/core/cds/inc/cds_packet.h @@ -76,42 +76,37 @@ uint8_t cds_pkt_get_proto_type (struct sk_buff *skb, uint8_t tracking_map, uint8_t dot11_type); #ifdef QCA_PKT_PROTO_TRACE -/*--------------------------------------------------------------------------- - -* brief cds_pkt_trace_buf_update() - - Update storage buffer with interest event string - -* event_string Event String may packet type or outstanding event - - ---------------------------------------------------------------------------*/ +/** + * cds_pkt_trace_buf_update() - Update storage buffer with interest event string + * @event_string: string may be a packet type or an outstanding event + * + * Return: none + */ void cds_pkt_trace_buf_update(char *event_string); -/*--------------------------------------------------------------------------- - -* brief cds_pkt_trace_buf_dump() - - Dump stored information into kernel log - - ---------------------------------------------------------------------------*/ +/** + * cds_pkt_trace_buf_dump() - Dump stored information into kernel log + * + * Return: none + */ void cds_pkt_trace_buf_dump(void); -/*--------------------------------------------------------------------------- - -* brief cds_pkt_proto_trace_init() - - Initialize protocol trace functionality, allocate required resource - - ---------------------------------------------------------------------------*/ +/** + * cds_pkt_proto_trace_init() - Initialize protocol trace functionality + * + * Return: none + */ void cds_pkt_proto_trace_init(void); -/*--------------------------------------------------------------------------- - -* brief cds_pkt_proto_trace_close() - - Free required resource - - ---------------------------------------------------------------------------*/ -void cds_pkt_proto_trace_close(void); +/** + * cds_pkt_proto_trace_deinit() - Free protocol trace buffer resource + * + * Return: none + */ +void cds_pkt_proto_trace_deinit(void); #else static inline void cds_pkt_proto_trace_init(void) { } -static inline void cds_pkt_proto_trace_close(void) {} +static inline void cds_pkt_proto_trace_deinit(void) {} #endif /* QCA_PKT_PROTO_TRACE */ /** diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 684bdb5dae29..12e17cfda911 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -223,6 +223,9 @@ QDF_STATUS cds_open(void) /* Initialize bug reporting structure */ cds_init_log_completion(); + /* Initialize protocol trace functionality */ + cds_pkt_proto_trace_init(); + /* Initialize the probe event */ if (qdf_event_create(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) { QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL, @@ -853,6 +856,9 @@ QDF_STATUS cds_close(v_CONTEXT_t cds_context) QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status)); } + /* De-Initialize protocol trace functionality */ + cds_pkt_proto_trace_deinit(); + cds_deinit_log_completion(); gp_cds_context->pHDDContext = NULL; diff --git a/core/cds/src/cds_packet.c b/core/cds/src/cds_packet.c index 38447aeef712..f8f610459f4e 100644 --- a/core/cds/src/cds_packet.c +++ b/core/cds/src/cds_packet.c @@ -181,12 +181,12 @@ uint8_t cds_pkt_get_proto_type(struct sk_buff *skb, uint8_t tracking_map, } #ifdef QCA_PKT_PROTO_TRACE -/*--------------------------------------------------------------------------- -* @brief cds_pkt_trace_buf_update() - - Update storage buffer with interest event string - -* event_string Event String may packet type or outstanding event - ---------------------------------------------------------------------------*/ +/** + * cds_pkt_trace_buf_update() - Update storage buffer with interest event string + * @event_string: string may be a packet type or an outstanding event + * + * Return: none + */ void cds_pkt_trace_buf_update(char *event_string) { uint32_t slot; @@ -194,6 +194,11 @@ void cds_pkt_trace_buf_update(char *event_string) QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, "%s %d, %s", __func__, __LINE__, event_string); qdf_spinlock_acquire(&trace_buffer_lock); + if (!trace_buffer) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "trace_buffer is null"); + goto release_lock; + } slot = trace_buffer_order % CDS_PKT_TRAC_MAX_TRACE_BUF; trace_buffer[slot].order = trace_buffer_order; trace_buffer[slot].event_time = qdf_mc_timer_get_system_time(); @@ -204,20 +209,27 @@ void cds_pkt_trace_buf_update(char *event_string) (CDS_PKT_TRAC_MAX_STRING_LEN < strlen(event_string)) ? CDS_PKT_TRAC_MAX_STRING_LEN : strlen(event_string)); trace_buffer_order++; - qdf_spinlock_release(&trace_buffer_lock); +release_lock: + qdf_spinlock_release(&trace_buffer_lock); return; } -/*--------------------------------------------------------------------------- -* @brief cds_pkt_trace_buf_dump() - - Dump stored information into kernel log - ---------------------------------------------------------------------------*/ +/** + * cds_pkt_trace_buf_dump() - Dump stored information into kernel log + * + * Return: none + */ void cds_pkt_trace_buf_dump(void) { uint32_t slot, idx; qdf_spinlock_acquire(&trace_buffer_lock); + if (!trace_buffer) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "trace_buffer is null"); + goto release_lock; + } QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, "PACKET TRACE DUMP START Current Timestamp %u", (unsigned int)qdf_mc_timer_get_system_time()); @@ -245,15 +257,16 @@ void cds_pkt_trace_buf_dump(void) QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, "PACKET TRACE DUMP END"); +release_lock: qdf_spinlock_release(&trace_buffer_lock); - return; } -/*--------------------------------------------------------------------------- -* @brief cds_pkt_proto_trace_init() - - Initialize protocol trace functionality, allocate required resource - ---------------------------------------------------------------------------*/ +/** + * cds_pkt_proto_trace_init() - Initialize protocol trace functionality + * + * Return: none + */ void cds_pkt_proto_trace_init(void) { /* Init spin lock to protect global memory */ @@ -269,17 +282,18 @@ void cds_pkt_proto_trace_init(void) return; } -/*--------------------------------------------------------------------------- -* @brief cds_pkt_proto_trace_close() - - Free required resource - ---------------------------------------------------------------------------*/ -void cds_pkt_proto_trace_close(void) +/** + * cds_pkt_proto_trace_deinit() - Free trace_buffer resource + * + * Return: none + */ +void cds_pkt_proto_trace_deinit(void) { QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, "%s %d", __func__, __LINE__); qdf_mem_free(trace_buffer); + trace_buffer = NULL; qdf_spinlock_destroy(&trace_buffer_lock); - return; } #endif /* QCA_PKT_PROTO_TRACE */ diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index bdfbdc3894b9..220531ca6750 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -4036,11 +4036,9 @@ void __hdd_wlan_exit(void) memdump_deinit(); -#ifdef QCA_PKT_PROTO_TRACE - cds_pkt_proto_trace_close(); -#endif /* Do all the cleanup before deregistering the driver */ hdd_wlan_exit(hdd_ctx); + EXIT(); } @@ -5863,8 +5861,6 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) goto err_cds_disable; } - cds_pkt_proto_trace_init(); - rtnl_held = hdd_hold_rtnl_lock(); adapter = hdd_open_interfaces(hdd_ctx, rtnl_held); -- cgit v1.2.3 From ebcab886505c506e2ab04c8d91ea9c2a3d0454d2 Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Wed, 4 May 2016 12:55:14 +0530 Subject: qcacld-3.0: Initialize max peers before default target configuration Make sure that the maximum number of peers is initialized before this value is configured to the target. Currently, the default target configuration is happening even before the max number of peers is initialized. Fix the same by initializing the max peers before the default target configuration. Change-Id: I189e9c92727703655b238b3edd1e3b480a09c17e CRs-Fixed: 1011487 --- core/wma/src/wma_main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index d068183616bf..89889ddca52e 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -1678,6 +1678,13 @@ QDF_STATUS wma_open(void *cds_context, wma_handle->wma_runtime_resume_lock = qdf_runtime_lock_init("wma_runtime_resume"); + /* Initialize max_no_of_peers for wma_get_number_of_peers_supported() */ + wma_init_max_no_of_peers(wma_handle, mac_params->maxStation); + /* Cap maxStation based on the target version */ + mac_params->maxStation = wma_get_number_of_peers_supported(wma_handle); + /* Reinitialize max_no_of_peers based on the capped maxStation value */ + wma_init_max_no_of_peers(wma_handle, mac_params->maxStation); + /* initialize default target config */ wma_set_default_tgt_config(wma_handle); @@ -1739,8 +1746,6 @@ QDF_STATUS wma_open(void *cds_context, if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) wma_utf_attach(wma_handle); #endif /* QCA_WIFI_FTM */ - wma_init_max_no_of_peers(wma_handle, mac_params->maxStation); - mac_params->maxStation = wma_get_number_of_peers_supported(wma_handle); mac_params->maxBssId = WMA_MAX_SUPPORTED_BSS; mac_params->frameTransRequired = 0; -- cgit v1.2.3 From 60024c87515e33833c15db2105d22d9cad391629 Mon Sep 17 00:00:00 2001 From: Vishwajith Upendra Date: Tue, 3 May 2016 00:34:32 -0700 Subject: Release 5.1.0.6 Release 5.1.0.6 Change-Id: I7797caedfa14af14c0491a7818aab3138178797d CRs-Fixed: 688141 --- core/mac/inc/qwlan_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h index 738e05d5cb54..a253ce6cb2b0 100644 --- a/core/mac/inc/qwlan_version.h +++ b/core/mac/inc/qwlan_version.h @@ -42,8 +42,8 @@ #define QWLAN_VERSION_MINOR 1 #define QWLAN_VERSION_PATCH 0 #define QWLAN_VERSION_EXTRA "" -#define QWLAN_VERSION_BUILD 5 +#define QWLAN_VERSION_BUILD 6 -#define QWLAN_VERSIONSTR "5.1.0.5" +#define QWLAN_VERSIONSTR "5.1.0.6" #endif /* QWLAN_VERSION_H */ -- cgit v1.2.3 From 9b03ab30e15a0dee1013c7d8cdf303cf9168c4f2 Mon Sep 17 00:00:00 2001 From: Prashanth Bhatta Date: Thu, 28 Apr 2016 12:35:13 -0700 Subject: qcacld-3.0: hdd: Refactor wlan_startup (phase 6) In HDD, hdd_wlan_startup which is called by probe is beast of a function to maintain. Over time it has grown to such an extent that it is almost 800 lines of code with in a single function. Divide the beast into logical smaller functions. Add register/unregister notifier routines to register and unregister NETDEV, IPv4 and IPv6 notifiers. Change-Id: Ife886f06f170a50149c110073469d8fcf183d39b CRs-fixed: 996332 --- core/hdd/src/wlan_hdd_main.c | 135 ++++++++++++++++++++++++++++--------------- 1 file changed, 89 insertions(+), 46 deletions(-) diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 220531ca6750..450c3e0281a3 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -3588,9 +3588,11 @@ QDF_STATUS hdd_abort_mac_scan_all_adapters(hdd_context_t *hdd_ctx) #ifdef WLAN_NS_OFFLOAD /** - * hdd_wlan_unregister_ip6_notifier() - unregister IP6 change notifier + * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier * @hdd_ctx: Pointer to hdd context * + * Unregister for IPv6 address change notifications. + * * Return: None */ static void hdd_wlan_unregister_ip6_notifier(hdd_context_t *hdd_ctx) @@ -3601,42 +3603,52 @@ static void hdd_wlan_unregister_ip6_notifier(hdd_context_t *hdd_ctx) } /** - * hdd_wlan_register_ip6_notifier() - register IP6 change notifier + * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier * @hdd_ctx: Pointer to hdd context * - * Return: None + * Register for IPv6 address change notifications. + * + * Return: 0 on success and errno on failure. */ -static void hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx) +static int hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx) { int ret; hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed; ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier); - if (ret) - hddLog(LOGE, FL("Failed to register IPv6 notifier")); - else - hdd_info("Registered IPv6 notifier"); + if (ret) { + hdd_err("Failed to register IPv6 notifier: %d", ret); + goto out; + } - return; + hdd_info("Registered IPv6 notifier"); +out: + return ret; } #else /** - * hdd_wlan_unregister_ip6_notifier() - unregister IP6 change notifier + * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier * @hdd_ctx: Pointer to hdd context * + * Unregister for IPv6 address change notifications. + * * Return: None */ static void hdd_wlan_unregister_ip6_notifier(hdd_context_t *hdd_ctx) { } + /** - * hdd_wlan_register_ip6_notifier() - register IP6 change notifier + * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier * @hdd_ctx: Pointer to hdd context * + * Register for IPv6 address change notifications. + * * Return: None */ -static void hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx) +static int hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx) { + return 0; } #endif @@ -3770,6 +3782,63 @@ static inline int hdd_logging_sock_deactivate_svc(hdd_context_t *hdd_ctx) } #endif +/** + * hdd_register_notifiers - Register netdev notifiers. + * @hdd_ctx: HDD context + * + * Register netdev notifiers like IPv4 and IPv6. + * + * Return: 0 on success and errno on failure + */ +static int hdd_register_notifiers(hdd_context_t *hdd_ctx) +{ + int ret; + + ret = register_netdevice_notifier(&hdd_netdev_notifier); + if (ret) { + hdd_err("register_netdevice_notifier failed: %d", ret); + goto out; + } + + ret = hdd_wlan_register_ip6_notifier(hdd_ctx); + if (ret) + goto unregister_notifier; + + hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed; + ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier); + if (ret) { + hdd_err("Failed to register IPv4 notifier: %d", ret); + goto unregister_ip6_notifier; + } + + return 0; + +unregister_ip6_notifier: + hdd_wlan_unregister_ip6_notifier(hdd_ctx); +unregister_notifier: + unregister_netdevice_notifier(&hdd_netdev_notifier); +out: + return ret; + +} + +/** + * hdd_unregister_notifiers - Unregister netdev notifiers. + * @hdd_ctx: HDD context + * + * Unregister netdev notifiers like IPv4 and IPv6. + * + * Return: None. + */ +static void hdd_unregister_notifiers(hdd_context_t *hdd_ctx) +{ + hdd_wlan_unregister_ip6_notifier(hdd_ctx); + + unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier); + + unregister_netdevice_notifier(&hdd_netdev_notifier); +} + /** * hdd_exit_netlink_services - Exit netlink services * @hdd_ctx: HDD context @@ -3881,11 +3950,6 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx) ENTER(); - hddLog(LOGE, FL("Unregister IPv6 notifier")); - hdd_wlan_unregister_ip6_notifier(hdd_ctx); - hddLog(LOGE, FL("Unregister IPv4 notifier")); - unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier); - hdd_unregister_wext_all_adapters(hdd_ctx); if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { @@ -3895,6 +3959,8 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx) goto free_hdd_ctx; } + hdd_unregister_notifiers(hdd_ctx); + /* * Cancel any outstanding scan requests. We are about to close all * of our adapters, but an adapter structure is what SME passes back @@ -5908,12 +5974,6 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) hdd_release_rtnl_lock(); rtnl_held = false; - ret = register_netdevice_notifier(&hdd_netdev_notifier); - if (ret < 0) { - hdd_err("register_netdevice_notifier failed: %d", ret); - goto err_exit_nl_srv; - } - #ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK /* Initialize the wake lcok */ qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock"); @@ -5985,8 +6045,7 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) status = hdd_register_for_sap_restart_with_channel_switch(); if (!QDF_IS_STATUS_SUCCESS(status)) - /* Error already logged */ - goto err_unreg_netdev_notifier; + goto err_exit_nl_srv; sme_set_rssi_threshold_breached_cb(hdd_ctx->hHal, hdd_rssi_threshold_breached); @@ -6009,40 +6068,24 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) INIT_DELAYED_WORK(&hdd_ctx->roc_req_work, wlan_hdd_roc_request_dequeue); #endif - /* - * Register IPv6 notifier to notify if any change in IP - * So that we can reconfigure the offload parameters - */ - hdd_wlan_register_ip6_notifier(hdd_ctx); - - /* - * Register IPv4 notifier to notify if any change in IP - * So that we can reconfigure the offload parameters - */ - hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed; - ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier); - if (ret) - hddLog(LOGE, FL("Failed to register IPv4 notifier")); - else - hdd_info("Registered IPv4 notifier"); - wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx); if (hdd_ctx->config->dual_mac_feature_disable) { status = wlan_hdd_disable_all_dual_mac_features(hdd_ctx); if (status != QDF_STATUS_SUCCESS) { hdd_err("Failed to disable dual mac features"); - goto err_unreg_netdev_notifier; + goto err_exit_nl_srv; } } + ret = hdd_register_notifiers(hdd_ctx); + if (ret) + goto err_exit_nl_srv; + memdump_init(); goto success; -err_unreg_netdev_notifier: - unregister_netdevice_notifier(&hdd_netdev_notifier); - err_exit_nl_srv: hdd_exit_netlink_services(hdd_ctx); -- cgit v1.2.3 From 527fd754ec4507a476d07aee76e9681ef4d9e2b3 Mon Sep 17 00:00:00 2001 From: Prashanth Bhatta Date: Thu, 28 Apr 2016 12:35:23 -0700 Subject: qcacld-3.0: hdd: Refactor wlan_startup (phase 7) In HDD, hdd_wlan_startup which is called by probe is beast of a function to maintain. Over time it has grown to such an extent that it is almost 800 lines of code with in a single function. Divide the beast into logical smaller functions. Create a separate function to initialize and destroy feature specific contexts. Change-Id: Ia09960a832674bfcba0ec9b6e8ddc0cc925ec419 CRs-fixed: 996332 --- core/hdd/inc/wlan_hdd_tdls.h | 6 +- core/hdd/src/wlan_hdd_hostapd.c | 50 ++++++--- core/hdd/src/wlan_hdd_hostapd.h | 4 +- core/hdd/src/wlan_hdd_main.c | 239 +++++++++++++++++++++++++++------------- core/hdd/src/wlan_hdd_scan.c | 31 ++++++ core/hdd/src/wlan_hdd_scan.h | 3 + core/hdd/src/wlan_hdd_tdls.c | 21 +++- 7 files changed, 251 insertions(+), 103 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h index 74b0bb3bd480..2d446b4fe504 100644 --- a/core/hdd/inc/wlan_hdd_tdls.h +++ b/core/hdd/inc/wlan_hdd_tdls.h @@ -631,7 +631,8 @@ int hdd_set_tdls_offchannel(hdd_context_t *hdd_ctx, int offchannel); int hdd_set_tdls_secoffchanneloffset(hdd_context_t *hdd_ctx, int offchanoffset); int hdd_set_tdls_offchannelmode(hdd_adapter_t *adapter, int offchanmode); int hdd_set_tdls_scan_type(hdd_context_t *hdd_ctx, int val); -void hdd_tdls_pre_init(hdd_context_t *hdd_ctx); +void hdd_tdls_context_init(hdd_context_t *hdd_ctx); +void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx); #else static inline void hdd_tdls_notify_mode_change(hdd_adapter_t *adapter, @@ -646,7 +647,8 @@ static inline void wlan_hdd_tdls_exit(hdd_adapter_t *adapter) { } -static inline void hdd_tdls_pre_init(hdd_context_t *hdd_ctx) { } +static inline void hdd_tdls_context_init(hdd_context_t *hdd_ctx) { } +static inline void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx) { } #endif /* End of FEATURE_WLAN_TDLS */ #ifdef FEATURE_WLAN_DIAG_SUPPORT diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 7ed1ebad7315..0cb38a44674e 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -102,16 +102,24 @@ /* Function definitions */ /** - * hdd_hostapd_channel_wakelock_init() - init the channel wakelock - * @pHddCtx: pointer to hdd context + * hdd_sap_context_init() - Initialize SAP context. + * @hdd_ctx: HDD context. * - * Return: None + * Initialize SAP context. + * + * Return: 0 on success. */ -void hdd_hostapd_channel_wakelock_init(hdd_context_t *pHddCtx) +int hdd_sap_context_init(hdd_context_t *hdd_ctx) { - /* Initialize the wakelock */ - qdf_wake_lock_create(&pHddCtx->sap_dfs_wakelock, "sap_dfs_wakelock"); - atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0); + qdf_wake_lock_create(&hdd_ctx->sap_dfs_wakelock, "sap_dfs_wakelock"); + atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0); + + mutex_init(&hdd_ctx->sap_lock); + qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock"); + + mutex_init(&hdd_ctx->dfs_lock); + + return 0; } /** @@ -187,25 +195,31 @@ void hdd_hostapd_channel_prevent_suspend(hdd_adapter_t *pAdapter, } /** - * hdd_hostapd_channel_wakelock_deinit() - destroy the channel wakelock + * hdd_sap_context_destroy() - Destroy SAP context * - * @pHddCtx: pointer to hdd context + * @hdd_ctx: HDD context. + * + * Destroy SAP context. * * Return: None */ -void hdd_hostapd_channel_wakelock_deinit(hdd_context_t *pHddCtx) +void hdd_sap_context_destroy(hdd_context_t *hdd_ctx) { - if (atomic_read(&pHddCtx->sap_dfs_ref_cnt)) { - /* Release wakelock */ - qdf_wake_lock_release(&pHddCtx->sap_dfs_wakelock, + if (atomic_read(&hdd_ctx->sap_dfs_ref_cnt)) { + qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock, WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT); - /* Reset the reference count */ - atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0); - hddLog(LOGE, FL("DFS: allowing suspend")); + + atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0); + hdd_warn("DFS: Allowing suspend"); } - /* Destroy lock */ - qdf_wake_lock_destroy(&pHddCtx->sap_dfs_wakelock); + qdf_wake_lock_destroy(&hdd_ctx->sap_dfs_wakelock); + + mutex_destroy(&hdd_ctx->sap_lock); + qdf_wake_lock_destroy(&hdd_ctx->sap_wake_lock); + + mutex_destroy(&hdd_ctx->dfs_lock); + } /** diff --git a/core/hdd/src/wlan_hdd_hostapd.h b/core/hdd/src/wlan_hdd_hostapd.h index 223b1c12cf0e..ed8c0ac5d3e0 100644 --- a/core/hdd/src/wlan_hdd_hostapd.h +++ b/core/hdd/src/wlan_hdd_hostapd.h @@ -98,8 +98,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, QDF_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter); void hdd_set_ap_ops(struct net_device *pWlanHostapdDev); int hdd_hostapd_stop(struct net_device *dev); -void hdd_hostapd_channel_wakelock_init(hdd_context_t *pHddCtx); -void hdd_hostapd_channel_wakelock_deinit(hdd_context_t *pHddCtx); +int hdd_sap_context_init(hdd_context_t *hdd_ctx); +void hdd_sap_context_destroy(hdd_context_t *hdd_ctx); #ifdef FEATURE_WLAN_FORCE_SAP_SCC void hdd_restart_softap(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter); #endif /* FEATURE_WLAN_FORCE_SAP_SCC */ diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 450c3e0281a3..883853f671f7 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -55,6 +55,7 @@ #include "wlan_hdd_ftm.h" #include "wlan_hdd_power.h" #include "wlan_hdd_stats.h" +#include "wlan_hdd_scan.h" #include "qdf_types.h" #include "qdf_trace.h" #include @@ -3914,20 +3915,94 @@ out: return ret; } +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK +/** + * hdd_rx_wake_lock_destroy() - Destroy RX wakelock + * @hdd_ctx: HDD context. + * + * Destroy RX wakelock. + * + * Return: None. + */ +static void hdd_rx_wake_lock_destroy(hdd_context_t *hdd_ctx) +{ + qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock); +} + +/** + * hdd_rx_wake_lock_create() - Create RX wakelock + * @hdd_ctx: HDD context. + * + * Create RX wakelock. + * + * Return: None. + */ +static void hdd_rx_wake_lock_create(hdd_context_t *hdd_ctx) +{ + qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock"); +} +#else +static void hdd_rx_wake_lock_destroy(hdd_context_t *hdd_ctx) { } +static void hdd_rx_wake_lock_create(hdd_context_t *hdd_ctx) { } +#endif + +/** + * hdd_roc_context_init() - Init ROC context + * @hdd_ctx: HDD context. + * + * Initialize ROC context. + * + * Return: 0 on success and errno on failure. + */ +static int hdd_roc_context_init(hdd_context_t *hdd_ctx) +{ + qdf_spinlock_create(&hdd_ctx->hdd_roc_req_q_lock); + qdf_list_create(&hdd_ctx->hdd_roc_req_q, MAX_ROC_REQ_QUEUE_ENTRY); + + INIT_DELAYED_WORK(&hdd_ctx->roc_req_work, wlan_hdd_roc_request_dequeue); + + return 0; +} + +/** + * hdd_roc_context_destroy() - Destroy ROC context + * @hdd_ctx: HDD context. + * + * Destroy roc list and flush the pending roc work. + * + * Return: None. + */ +static void hdd_roc_context_destroy(hdd_context_t *hdd_ctx) +{ + flush_delayed_work(&hdd_ctx->roc_req_work); + qdf_list_destroy(&hdd_ctx->hdd_roc_req_q); +} /** - * hdd_free_context - Free HDD context - * @hdd_ctx: HDD context to be freed. + * hdd_context_destroy() - Destroy HDD context + * @hdd_ctx: HDD context to be destroyed. * - * Free config and HDD context. + * Free config and HDD context as well as destroy all the resources. * * Return: None */ -static void hdd_free_context(hdd_context_t *hdd_ctx) +static void hdd_context_destroy(hdd_context_t *hdd_ctx) { if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam()) hdd_logging_sock_deactivate_svc(hdd_ctx); + hdd_roc_context_destroy(hdd_ctx); + + hdd_sap_context_destroy(hdd_ctx); + + hdd_rx_wake_lock_destroy(hdd_ctx); + + hdd_tdls_context_destroy(hdd_ctx); + + hdd_scan_context_destroy(hdd_ctx); + + qdf_list_destroy(&hdd_ctx->hddAdapters); + qdf_mem_free(hdd_ctx->config); hdd_ctx->config = NULL; @@ -4039,14 +4114,6 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx) FL("Failed to close CDS Scheduler")); QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status)); } -#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK - /* Destroy the wake lock */ - qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock); -#endif - /* Destroy the wake lock */ - qdf_wake_lock_destroy(&hdd_ctx->sap_wake_lock); - - hdd_hostapd_channel_wakelock_deinit(hdd_ctx); /* * Close CDS @@ -4065,8 +4132,6 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx) /* Free up RoC request queue and flush workqueue */ cds_flush_work(&hdd_ctx->roc_req_work); - qdf_list_destroy(&hdd_ctx->hdd_roc_req_q); - qdf_list_destroy(&hdd_ctx->hdd_scan_req_q); if (!QDF_IS_STATUS_SUCCESS(cds_deinit_policy_mgr())) { hdd_err("Failed to deinit policy manager"); @@ -4077,7 +4142,7 @@ free_hdd_ctx: wiphy_unregister(wiphy); - hdd_free_context(hdd_ctx); + hdd_context_destroy(hdd_ctx); } void __hdd_wlan_exit(void) @@ -5329,7 +5394,77 @@ static void hdd_set_trace_level_for_each(hdd_context_t *hdd_ctx) } /** - * hdd_init_context - Alloc and initialize HDD context + * hdd_context_init() - Initialize HDD context + * @hdd_ctx: HDD context. + * + * Initialize HDD context along with all the feature specific contexts. + * + * return: 0 on success and errno on failure. + */ +static int hdd_context_init(hdd_context_t *hdd_ctx) +{ + int ret; + + hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; + hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX; + + hdd_init_ll_stats_ctx(); + + init_completion(&hdd_ctx->mc_sus_event_var); + init_completion(&hdd_ctx->ready_to_suspend); + + qdf_spinlock_create(&hdd_ctx->connection_status_lock); + + qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock); + qdf_list_create(&hdd_ctx->hddAdapters, MAX_NUMBER_OF_ADAPTERS); + + init_completion(&hdd_ctx->set_antenna_mode_cmpl); + + ret = hdd_scan_context_init(hdd_ctx); + if (ret) + goto list_destroy; + + hdd_tdls_context_init(hdd_ctx); + + hdd_rx_wake_lock_create(hdd_ctx); + + ret = hdd_sap_context_init(hdd_ctx); + if (ret) + goto scan_destroy; + + ret = hdd_roc_context_init(hdd_ctx); + if (ret) + goto sap_destroy; + + wlan_hdd_cfg80211_extscan_init(hdd_ctx); + + hdd_init_offloaded_packets_ctx(hdd_ctx); + + ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy, + hdd_ctx->config); + if (ret) + goto roc_destroy; + + return 0; + +roc_destroy: + hdd_roc_context_destroy(hdd_ctx); + +sap_destroy: + hdd_sap_context_destroy(hdd_ctx); + +scan_destroy: + hdd_scan_context_destroy(hdd_ctx); + hdd_rx_wake_lock_destroy(hdd_ctx); + hdd_tdls_context_destroy(hdd_ctx); + +list_destroy: + qdf_list_destroy(&hdd_ctx->hddAdapters); + return ret; +} + +/** + * hdd_context_create() - Allocate and inialize HDD context. * @dev: Pointer to the underlying device * @hif_sc: HIF context * @@ -5338,7 +5473,7 @@ static void hdd_set_trace_level_for_each(hdd_context_t *hdd_ctx) * * Return: HDD context on success and ERR_PTR on failure */ -hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc) +hdd_context_t *hdd_context_create(struct device *dev, void *hif_sc) { QDF_STATUS status; int ret = 0; @@ -5363,6 +5498,7 @@ hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc) } hdd_ctx->pcds_context = p_cds_context; + hdd_ctx->parent_dev = dev; hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config)); if (hdd_ctx->config == NULL) { @@ -5380,39 +5516,6 @@ hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc) goto err_free_config; } - ((cds_context_type *) (p_cds_context))->pHDDContext = (void *)hdd_ctx; - - hdd_ctx->parent_dev = dev; - - hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; - - hdd_init_ll_stats_ctx(); - - init_completion(&hdd_ctx->mc_sus_event_var); - init_completion(&hdd_ctx->ready_to_suspend); - - qdf_spinlock_create(&hdd_ctx->connection_status_lock); - qdf_spinlock_create(&hdd_ctx->sched_scan_lock); - - qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock); - qdf_list_create(&hdd_ctx->hddAdapters, MAX_NUMBER_OF_ADAPTERS); - - wlan_hdd_cfg80211_extscan_init(hdd_ctx); - - hdd_tdls_pre_init(hdd_ctx); - mutex_init(&hdd_ctx->dfs_lock); - mutex_init(&hdd_ctx->sap_lock); - - init_completion(&hdd_ctx->set_antenna_mode_cmpl); - - hdd_ctx->target_type = tgt_info->target_type; - - hdd_init_offloaded_packets_ctx(hdd_ctx); - - icnss_set_fw_debug_mode(hdd_ctx->config->enable_fw_log); - - hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX; - hdd_ctx->configuredMcastBcastFilter = hdd_ctx->config->mcastBcastFilterSetting; @@ -5423,12 +5526,16 @@ hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc) hdd_override_ini_config(hdd_ctx); - ret = wlan_hdd_cfg80211_init(dev, hdd_ctx->wiphy, hdd_ctx->config); + ((cds_context_type *) (p_cds_context))->pHDDContext = (void *)hdd_ctx; - if (ret) { - hdd_err("CFG80211 wiphy init failed: %d", ret); + ret = hdd_context_init(hdd_ctx); + + if (ret) goto err_free_config; - } + + hdd_ctx->target_type = tgt_info->target_type; + + icnss_set_fw_debug_mode(hdd_ctx->config->enable_fw_log); hdd_enable_fastpath(hdd_ctx->config, hif_sc); @@ -5793,7 +5900,7 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) return ret; } - hdd_ctx = hdd_init_context(dev, hif_sc); + hdd_ctx = hdd_context_create(dev, hif_sc); if (IS_ERR(hdd_ctx)) return PTR_ERR(hdd_ctx); @@ -5974,15 +6081,6 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) hdd_release_rtnl_lock(); rtnl_held = false; -#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK - /* Initialize the wake lcok */ - qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock"); -#endif - /* Initialize the wake lcok */ - qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock"); - - hdd_hostapd_channel_wakelock_init(hdd_ctx); - if (hdd_ctx->config->fIsImpsEnabled) hdd_set_idle_ps_config(hdd_ctx, true); else @@ -6057,17 +6155,6 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) hdd_ctx->target_hw_version, hdd_ctx->target_hw_name); - qdf_spinlock_create(&hdd_ctx->hdd_roc_req_q_lock); - qdf_list_create((&hdd_ctx->hdd_roc_req_q), MAX_ROC_REQ_QUEUE_ENTRY); - qdf_spinlock_create(&hdd_ctx->hdd_scan_req_q_lock); - qdf_list_create((&hdd_ctx->hdd_scan_req_q), CFG_MAX_SCAN_COUNT_MAX); -#ifdef CONFIG_CNSS - cnss_init_delayed_work(&hdd_ctx->roc_req_work, - wlan_hdd_roc_request_dequeue); -#else - INIT_DELAYED_WORK(&hdd_ctx->roc_req_work, wlan_hdd_roc_request_dequeue); -#endif - wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx); if (hdd_ctx->config->dual_mac_feature_disable) { @@ -6121,7 +6208,7 @@ err_cds_close: cds_close(hdd_ctx->pcds_context); err_hdd_free_context: - hdd_free_context(hdd_ctx); + hdd_context_destroy(hdd_ctx); QDF_BUG(1); return -EIO; diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index b10068bfe99a..bee481fa42e6 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -2495,3 +2495,34 @@ void hdd_cleanup_scan_queue(hdd_context_t *hdd_ctx) return; } + +/** + * hdd_scan_context_destroy() - Destroy scan context + * @hdd_ctx: HDD context. + * + * Destroy scan context. + * + * Return: None. + */ +void hdd_scan_context_destroy(hdd_context_t *hdd_ctx) +{ + qdf_list_destroy(&hdd_ctx->hdd_scan_req_q); +} + +/** + * hdd_scan_context_init() - Initialize scan context + * @hdd_ctx: HDD context. + * + * Initialize scan related resources like spin lock and lists. + * + * Return: 0 on success and errno on failure. + */ +int hdd_scan_context_init(hdd_context_t *hdd_ctx) +{ + qdf_spinlock_create(&hdd_ctx->sched_scan_lock); + + qdf_spinlock_create(&hdd_ctx->hdd_scan_req_q_lock); + qdf_list_create(&hdd_ctx->hdd_scan_req_q, CFG_MAX_SCAN_COUNT_MAX); + + return 0; +} diff --git a/core/hdd/src/wlan_hdd_scan.h b/core/hdd/src/wlan_hdd_scan.h index 8b1d7489d80f..50a6a8ddf273 100644 --- a/core/hdd/src/wlan_hdd_scan.h +++ b/core/hdd/src/wlan_hdd_scan.h @@ -50,6 +50,9 @@ int iw_get_scan(struct net_device *dev, struct iw_request_info *info, int iw_set_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +int hdd_scan_context_init(hdd_context_t *hdd_ctx); +void hdd_scan_context_destroy(hdd_context_t *hdd_ctx); + int wlan_hdd_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index afc1fd62e4c1..cd60b7141134 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -589,20 +589,31 @@ static void wlan_hdd_tdls_del_non_forced_peers(tdlsCtx_t *hdd_tdls_ctx) } /** - * hdd_tdls_pre_init - TDLS pre init + * hdd_tdls_context_init() - Init TDLS context * @hdd_ctx: HDD context * - * tdls_lock is initialized before an hdd_open_adapter ( which is - * invoked by other instances also) to protect the concurrent - * access for the Adapters by TDLS module. + * Initialize TDLS global context. * * Return: None */ -void hdd_tdls_pre_init(hdd_context_t *hdd_ctx) +void hdd_tdls_context_init(hdd_context_t *hdd_ctx) { mutex_init(&hdd_ctx->tdls_lock); } +/** + * hdd_tdls_context_destroy() - Destroy TDLS context + * @hdd_ctx: HDD context + * + * Destroy TDLS global context. + * + * Return: None + */ +void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx) +{ + mutex_destroy(&hdd_ctx->tdls_lock); +} + /** * wlan_hdd_tdls_init() - tdls initializaiton * @pAdapter: hdd adapter -- cgit v1.2.3 From 07998753414ebdc6def8b26d002dcba283df4295 Mon Sep 17 00:00:00 2001 From: Prashanth Bhatta Date: Thu, 28 Apr 2016 12:35:33 -0700 Subject: qcacld-3.0: hdd: Refactor wlan_startup (phase 8) In HDD, hdd_wlan_startup which is called by probe is beast of a function to maintain. Over time it has grown to such an extent that it is almost 800 lines of code with in a single function. Divide the beast into logical smaller functions. Create a separate functions to configure lower layers before cds_enable. Change-Id: Ia6eba5a94889cef4502b71edfab773b6295847d6 CRs-fixed: 996332 --- core/hdd/src/wlan_hdd_main.c | 173 ++++++++++++++++++++++++------------------- 1 file changed, 95 insertions(+), 78 deletions(-) diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 883853f671f7..e750b1a46e82 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5873,6 +5873,95 @@ static void hdd_tsf_init(hdd_context_t *hdd_ctx) } #endif +/** + * hdd_pre_enable_configure() - Configurations prior to cds_enable + * @hdd_ctx: HDD context + * + * Pre configurations to be done at lower layer before calling cds enable. + * + * Return: 0 on success and errno on failure. + */ +static int hdd_pre_enable_configure(hdd_context_t *hdd_ctx) +{ + int ret; + QDF_STATUS status; + tSirRetStatus hal_status; + + ol_txrx_register_pause_cb(wlan_hdd_txrx_pause_cb); + + /* + * Set 802.11p config + * TODO-OCB: This has been temporarily added here to ensure this + * parameter is set in CSR when we init the channel list. This should + * be removed once the 5.9 GHz channels are added to the regulatory + * domain. + */ + hdd_set_dot11p_config(hdd_ctx); + + /* + * Note that the cds_pre_enable() sequence triggers the cfg download. + * The cfg download must occur before we update the SME config + * since the SME config operation must access the cfg database + */ + status = hdd_set_sme_config(hdd_ctx); + + if (QDF_STATUS_SUCCESS != status) { + hdd_alert("Failed hdd_set_sme_config: %d", status); + ret = qdf_status_to_os_return(status); + goto out; + } + + ret = wma_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, + hdd_ctx->config->tx_chain_mask_1ss, + PDEV_CMD); + if (0 != ret) { + hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret); + goto out; + } + + hdd_program_country_code(hdd_ctx); + + status = hdd_set_sme_chan_list(hdd_ctx); + if (status != QDF_STATUS_SUCCESS) { + hdd_alert("Failed to init channel list: %d", status); + ret = qdf_status_to_os_return(status); + goto out; + } + + /* Apply the cfg.ini to cfg.dat */ + if (!hdd_update_config_dat(hdd_ctx)) { + hdd_alert("config update failed"); + ret = -EINVAL; + goto out; + } + + status = hdd_update_mac_config(hdd_ctx); + if (QDF_STATUS_SUCCESS != status) { + hdd_warn("can't update mac config, using MAC from ini file: %d", + status); + } + + /* + * Set the MAC Address Currently this is used by HAL to add self sta. + * Remove this once self sta is added as part of session open. + */ + hal_status = cfg_set_str(hdd_ctx->hHal, WNI_CFG_STA_ID, + hdd_ctx->config->intfMacAddr[0].bytes, + sizeof(hdd_ctx->config->intfMacAddr[0])); + + if (!IS_SIR_STATUS_SUCCESS(hal_status)) { + hdd_err("Failed to set MAC Address. HALStatus is %08d [x%08x]", + hal_status, hal_status); + ret = -EINVAL; + goto out; + } + + hdd_init_channel_avoidance(hdd_ctx); + +out: + return ret; +} + /** * hdd_wlan_startup() - HDD init function * @dev: Pointer to the underlying device @@ -5889,8 +5978,6 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) int ret; tSirTxPowerLimit hddtxlimit; bool rtnl_held; - tSirRetStatus hal_status; - int ret_val; ENTER(); @@ -5937,80 +6024,15 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) goto err_cds_close; } - ol_txrx_register_pause_cb(wlan_hdd_txrx_pause_cb); - - ret_val = hdd_wiphy_init(hdd_ctx); - - if (ret_val) { - hdd_alert("failed to initialize wiphy"); + ret = hdd_wiphy_init(hdd_ctx); + if (ret) { + hdd_alert("Failed to initialize wiphy: %d", ret); goto err_cds_close; } - /* - * Set 802.11p config - * TODO-OCB: This has been temporarily added here to ensure this - * parameter is set in CSR when we init the channel list. This should - * be removed once the 5.9 GHz channels are added to the regulatory - * domain. - */ - hdd_set_dot11p_config(hdd_ctx); - - /* - * Note that the cds_pre_enable() sequence triggers the cfg download. - * The cfg download must occur before we update the SME config - * since the SME config operation must access the cfg database - */ - status = hdd_set_sme_config(hdd_ctx); - - if (QDF_STATUS_SUCCESS != status) { - hddLog(QDF_TRACE_LEVEL_FATAL, FL("Failed hdd_set_sme_config")); - goto err_wiphy_unregister; - } - - ret = wma_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, - hdd_ctx->config->tx_chain_mask_1ss, - PDEV_CMD); - if (0 != ret) { - hddLog(QDF_TRACE_LEVEL_ERROR, - "%s: WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", - __func__, ret); - } - - hdd_program_country_code(hdd_ctx); - - status = hdd_set_sme_chan_list(hdd_ctx); - if (status != QDF_STATUS_SUCCESS) { - hddLog(QDF_TRACE_LEVEL_FATAL, - FL("Failed to init channel list")); - goto err_wiphy_unregister; - } - - /* Apply the cfg.ini to cfg.dat */ - if (false == hdd_update_config_dat(hdd_ctx)) { - hddLog(QDF_TRACE_LEVEL_FATAL, - FL("config update failed")); - goto err_wiphy_unregister; - } - - if (QDF_STATUS_SUCCESS != hdd_update_mac_config(hdd_ctx)) { - hddLog(QDF_TRACE_LEVEL_WARN, - FL("can't update mac config, using MAC from ini file")); - } - - /* - * Set the MAC Address Currently this is used by HAL to add self sta. - * Remove this once self sta is added as part of session open. - */ - hal_status = cfg_set_str(hdd_ctx->hHal, WNI_CFG_STA_ID, - hdd_ctx->config->intfMacAddr[0].bytes, - sizeof(hdd_ctx->config->intfMacAddr[0])); - - if (!IS_SIR_STATUS_SUCCESS(hal_status)) { - hdd_err("Failed to set MAC Address. HALStatus is %08d [x%08x]", - hal_status, hal_status); - ret = -EINVAL; + ret = hdd_pre_enable_configure(hdd_ctx); + if (ret) goto err_wiphy_unregister; - } if (hdd_ipa_init(hdd_ctx) == QDF_STATUS_E_FAILURE) goto err_wiphy_unregister; @@ -6025,8 +6047,6 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) goto err_ipa_cleanup; } - hdd_init_channel_avoidance(hdd_ctx); - status = hdd_post_cds_enable_config(hdd_ctx); if (!QDF_IS_STATUS_SUCCESS(status)) { hddLog(QDF_TRACE_LEVEL_FATAL, @@ -6070,7 +6090,7 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) ret = hdd_init_netlink_services(hdd_ctx); if (ret) - goto err_debugfs_exit; + goto err_close_adapter; /* * Action frame registered in one adapter which will @@ -6181,9 +6201,6 @@ err_exit_nl_srv: /* Proceed and complete the clean up */ } -err_debugfs_exit: - hdd_debugfs_exit(adapter); - err_close_adapter: hdd_release_rtnl_lock(); -- cgit v1.2.3 From 6d2b488d48be7e1e8dd87189d8eadef799eed9c5 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Fri, 22 Apr 2016 16:14:30 -0700 Subject: qcacld-3.0: Fix the issue with VHT SGI settings in SAP mode SGI setting for 80 and 160MHz are not advertised due to checking the wrong channel width parameter in the session entry. Check the correct channel width parameter to advertise the SGI support in 80MHz and 160MHz Change-Id: Ia0c2096f243b649088a9dc5ed5e5374cea972e51 CRs-Fixed: 1000145 --- core/mac/src/sys/legacy/src/utils/src/parser_api.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index db860844cef0..b09657033abc 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -977,8 +977,7 @@ populate_dot11f_vht_caps(tpAniSirGlobal pMac, nCfgValue); pDot11f->ldpcCodingCap = (nCfgValue & 0x0001); - if (psessionEntry->vhtTxChannelWidthSet < - WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) { + if (psessionEntry->ch_width < CH_WIDTH_80MHZ) { pDot11f->shortGI80MHz = 0; } else { nCfgValue = 0; @@ -989,8 +988,7 @@ populate_dot11f_vht_caps(tpAniSirGlobal pMac, pDot11f->shortGI80MHz = (nCfgValue & 0x0001); } - if (psessionEntry->vhtTxChannelWidthSet < - WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) { + if (psessionEntry->ch_width < CH_WIDTH_160MHZ) { pDot11f->shortGI160and80plus80MHz = 0; } else { nCfgValue = 0; -- cgit v1.2.3 From 6e61e8cfba7e3c3de00f9654cae0442e8145b6d3 Mon Sep 17 00:00:00 2001 From: Dhanashri Atre Date: Mon, 25 Apr 2016 13:22:54 -0700 Subject: qcacld-3.0: Increase HTT Rx Ring The firmware would like host to initially populate all 2K entries, so that fw shadow ring will always have 1K entries to fetch after the initial population of 512 entries to each mac. Change-Id: I5f19a1e2693f54f9d7938b723d0d57487f842daf CRs-Fixed: 1006872 --- core/dp/htt/htt_rx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/dp/htt/htt_rx.c b/core/dp/htt/htt_rx.c index 0064a8f282d6..9e5957483a82 100644 --- a/core/dp/htt/htt_rx.c +++ b/core/dp/htt/htt_rx.c @@ -81,8 +81,9 @@ #define HTT_RX_HOST_LATENCY_MAX_MS 20 /* ms */ /* very conservative */ #endif + /* very conservative to ensure enough buffers are allocated */ #ifndef HTT_RX_HOST_LATENCY_WORST_LIKELY_MS -#define HTT_RX_HOST_LATENCY_WORST_LIKELY_MS 10 /* ms */ /* conservative */ +#define HTT_RX_HOST_LATENCY_WORST_LIKELY_MS 20 #endif #ifndef HTT_RX_RING_REFILL_RETRY_TIME_MS @@ -203,7 +204,9 @@ static int htt_rx_ring_fill_level(struct htt_pdev_t *pdev) size = ol_cfg_max_thruput_mbps(pdev->ctrl_pdev) * 1000 /* 1e6 bps/mbps / 1e3 ms per sec = 1000 */ / - 8 * HTT_RX_AVG_FRM_BYTES * HTT_RX_HOST_LATENCY_WORST_LIKELY_MS; + (8 * HTT_RX_AVG_FRM_BYTES) * HTT_RX_HOST_LATENCY_WORST_LIKELY_MS; + + size = qdf_get_pwr2(size); /* * Make sure the fill level is at least 1 less than the ring size. * Leaving 1 element empty allows the SW to easily distinguish -- cgit v1.2.3 From b26f431bb20391e948c4ae4fb9aa50c8d4ef98a0 Mon Sep 17 00:00:00 2001 From: Rakesh Sunki Date: Thu, 28 Apr 2016 16:01:47 -0700 Subject: qcalcd-3.0: Fix DFS-3 segment ID propagation from radar summary Fix the segmentID propagation from radar summary report to phyerror event structure to correctly identify the segment, on which a phyerror is received for pattern match processing. Also, to enhance the debug, add all the radar summary parameters to dfs event and print while processing the phyerror for a pattern match. Change-Id: I1325ad541cf69685606e4905275244e207d95b29 CRs-Fixed: 1009784 --- core/sap/dfs/inc/dfs.h | 47 ++++++++++++++++++++++++++++++ core/sap/dfs/src/dfs_phyerr_tlv.c | 29 +++++++++++-------- core/sap/dfs/src/dfs_process_phyerr.c | 48 +++++++++++++++++++++++++++++++ core/sap/dfs/src/dfs_process_radarevent.c | 35 +++++++++++++++------- 4 files changed, 137 insertions(+), 22 deletions(-) diff --git a/core/sap/dfs/inc/dfs.h b/core/sap/dfs/inc/dfs.h index 56187cbcdc8b..74c0add523a5 100644 --- a/core/sap/dfs/inc/dfs.h +++ b/core/sap/dfs/inc/dfs.h @@ -101,6 +101,16 @@ #define DFS_80P80_SEG0 0 #define DFS_80P80_SEG1 1 +/** + * @DFS_RADAR_SUMMARY_REPORT_VERSION_2: DFS-2 radar summary report + * @DFS_RADAR_SUMMARY_REPORT_VERSION_3: DFS-3 radar summary report + */ +enum { + DFS_RADAR_SUMMARY_REPORT_VERSION_2 = 1, + DFS_RADAR_SUMMARY_REPORT_VERSION_3 = 2, +}; + + /* * Constants to use for chirping detection. * @@ -286,6 +296,19 @@ struct dfs_event { uint32_t re_freq_hi; /* Upper bounds of frequency, KHz */ int sidx; /* Pulse Index as in radar summary report */ int radar_80p80_segid; /* 80p80 segment ID as in radar sum report */ + int delta_peak; /* delta peak reported in radar summary */ + int delta_diff; /* delta diff reported in radar summary */ + int agc_total_gain; /* agc total gain reported in radar summary */ + int agc_mb_gain; /* agc mb gain reported in radar summary */ + int radar_subchan_mask; /* subchan mask reported in radar summary */ + int pulse_height; /* pulse height reported in radar summary */ + int triggering_agc_event; /* triggering agc reported in radar summary */ + int pulse_rssi; /* rssi of phyerr reported in radar summary */ + int radar_fft_pri80_inband_power; /* Pri80MHz pwr reported in summary */ + int radar_fft_ext80_inband_power; /* Ext80MHz pwr reported in summary */ + int rsu_version; /* Radar summary report version */ + int phyerr_serial_num; /* phyerr seq num queued for pattern matching */ + int peak_mag; /* Peak mag reported in radar search FFT report */ STAILQ_ENTRY(dfs_event) re_list; /* List of radar events */ } qdf_packed; #ifdef WIN32 @@ -737,6 +760,30 @@ struct dfs_phy_err { * when SAP is operating in 80p80 channel width. */ int radar_80p80_segid; + /* delta peak reported in radar summary */ + int delta_peak; + /* delta diff reported in radar summary */ + int delta_diff; + /* agc total gain reported in radar summary */ + int agc_total_gain; + /* agc mb gain reported in radar summary */ + int agc_mb_gain; + /* subchan mask reported in radar summary */ + int radar_subchan_mask; + /* pulse height reported in radar summary */ + int pulse_height; + /* triggering agc reported in radar summary */ + int triggering_agc_event; + /* rssi of phyerr reported in radar summary */ + int pulse_rssi; + /* Pri80MHz pwr reported in summary */ + int radar_fft_pri80_inband_power; + /* Ext80MHz pwr reported in summary */ + int radar_fft_ext80_inband_power; + /* Peak mag reported in radar search FFT report */ + int peak_mag; + /* Radar summary report version */ + int rsu_version; }; /* Attach, detach, handle ioctl prototypes */ diff --git a/core/sap/dfs/src/dfs_phyerr_tlv.c b/core/sap/dfs/src/dfs_phyerr_tlv.c index 3ac1d08c1071..058e321d1c38 100644 --- a/core/sap/dfs/src/dfs_phyerr_tlv.c +++ b/core/sap/dfs/src/dfs_phyerr_tlv.c @@ -35,16 +35,6 @@ #include "dfs_phyerr.h" #include "dfs_phyerr_tlv.h" -/** - * enum RADAR_SUMMARY_VERSION - Radar summary report version - * @DFS_RADAR_SUMMARY_REPORT_VERSION_2: DFS-2 radar summary report - * @DFS_RADAR_SUMMARY_REPORT_VERSION_3: DFS-3 radar summary report - */ -typedef enum { -DFS_RADAR_SUMMARY_REPORT_VERSION_2 = 1, -DFS_RADAR_SUMMARY_REPORT_VERSION_3 = 2, -} RADAR_SUMMARY_VERSION; - /* * Parsed radar status */ @@ -62,7 +52,7 @@ struct rx_radar_status { int agc_mb_gain; /*Parsed only for DFS-3*/ int radar_subchan_mask; - RADAR_SUMMARY_VERSION rsu_version; + int rsu_version; /* * The parameters below are present only in * DFS-3 radar summary report and need to be @@ -882,8 +872,23 @@ dfs_process_phyerr_bb_tlv(struct ath_dfs *dfs, void *buf, uint16_t datalen, * Copy the segment ID from the radar summary report * only when radar summary report version is DFS-3. */ - if (rs.rsu_version == DFS_RADAR_SUMMARY_REPORT_VERSION_3) + if (rs.rsu_version == DFS_RADAR_SUMMARY_REPORT_VERSION_3) { e->radar_80p80_segid = rs.radar_80p80_segid; + e->delta_peak = rs.delta_peak; + e->delta_diff = rs.delta_diff; + e->agc_total_gain = rs.agc_total_gain; + e->agc_mb_gain = rs.agc_mb_gain; + e->radar_subchan_mask = rs.radar_subchan_mask; + e->pulse_height = rs.pulse_height; + e->triggering_agc_event = rs.triggering_agc_event; + e->pulse_rssi = rs.pulse_rssi; + e->radar_fft_pri80_inband_power = + rs.radar_fft_pri80_inband_power; + e->radar_fft_ext80_inband_power = + rs.radar_fft_ext80_inband_power; + e->rsu_version = rs.rsu_version; + e->peak_mag = rsfr.peak_mag; + } /* * XXX TODO: add a "chirp detection enabled" capability or config * bit somewhere, in case for some reason the hardware chirp diff --git a/core/sap/dfs/src/dfs_process_phyerr.c b/core/sap/dfs/src/dfs_process_phyerr.c index 8725236b08a8..a78b4ef4ad54 100644 --- a/core/sap/dfs/src/dfs_process_phyerr.c +++ b/core/sap/dfs/src/dfs_process_phyerr.c @@ -560,6 +560,9 @@ dfs_process_phyerr(struct ieee80211com *ic, void *buf, uint16_t datalen, r_fulltsf, &e, enable_log) == 0) { dfs->dfs_phyerr_reject_count++; + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, + "%s:Rejected phyerr count after parsing=%d\n", + __func__, dfs->dfs_phyerr_reject_count); return; } else { if (dfs->dfs_phyerr_freq_min > e.freq) @@ -737,6 +740,22 @@ dfs_process_phyerr(struct ieee80211com *ic, void *buf, uint16_t datalen, event->re_chanindex = dfs->dfs_curchan_radindex; event->re_flags = 0; event->sidx = e.sidx; + if (e.rsu_version == DFS_RADAR_SUMMARY_REPORT_VERSION_3) { + event->delta_peak = e.delta_peak; + event->delta_diff = e.delta_diff; + event->agc_total_gain = e.agc_total_gain; + event->agc_mb_gain = e.agc_mb_gain; + event->radar_subchan_mask = e.radar_subchan_mask; + event->pulse_height = e.pulse_height; + event->triggering_agc_event = e.triggering_agc_event; + event->pulse_rssi = e.pulse_rssi; + event->radar_fft_pri80_inband_power = + e.radar_fft_pri80_inband_power; + event->radar_fft_ext80_inband_power = + e.radar_fft_ext80_inband_power; + event->rsu_version = e.rsu_version; + event->peak_mag = e.peak_mag; + } /* * Copy the segment ID of the phyerror * from the radar summary report only @@ -825,6 +844,35 @@ dfs_process_phyerr(struct ieee80211com *ic, void *buf, uint16_t datalen, event->re_ts = (e.rs_tstamp) & DFS_TSMASK; event->re_rssi = e.rssi; event->sidx = e.sidx; + if (e.rsu_version == + DFS_RADAR_SUMMARY_REPORT_VERSION_3) { + event->delta_peak = e.delta_peak; + event->delta_diff = e.delta_diff; + event->agc_total_gain = e.agc_total_gain; + event->agc_mb_gain = e.agc_mb_gain; + event->radar_subchan_mask = e.radar_subchan_mask; + event->pulse_height = e.pulse_height; + event->triggering_agc_event = + e.triggering_agc_event; + event->pulse_rssi = e.pulse_rssi; + event->radar_fft_pri80_inband_power = + e.radar_fft_pri80_inband_power; + event->radar_fft_ext80_inband_power = + e.radar_fft_ext80_inband_power; + event->rsu_version = e.rsu_version; + event->phyerr_serial_num = + dfs->dfs_phyerr_queued_count; + event->peak_mag = e.peak_mag; + } + /* + * Copy the segment ID of the phyerror + * from the radar summary report only + * if SAP is operating in 80p80 mode + * and both primary and extension segments + * are DFS. + */ + if (chan->ic_80p80_both_dfs) + event->radar_80p80_segid = e.radar_80p80_segid; /* * Handle chirp flags. diff --git a/core/sap/dfs/src/dfs_process_radarevent.c b/core/sap/dfs/src/dfs_process_radarevent.c index 30392b1b41cc..e77d71178642 100644 --- a/core/sap/dfs/src/dfs_process_radarevent.c +++ b/core/sap/dfs/src/dfs_process_radarevent.c @@ -115,8 +115,6 @@ static inline uint8_t dfs_process_pulse_dur(struct ath_dfs *dfs, uint8_t re_dur) int dfs_process_radarevent(struct ath_dfs *dfs, struct dfs_ieee80211_channel *chan) { -/* commenting for now to validate radar indication msg to SAP */ -/* #if 0 */ struct dfs_event re, *event; struct dfs_state *rs = NULL; struct dfs_filtertype *ft; @@ -129,9 +127,7 @@ int dfs_process_radarevent(struct ath_dfs *dfs, struct dfs_pulseline *pl; static uint32_t diff_ts; int ext_chan_event_flag = 0; -#if 0 - int pri_multiplier = 2; -#endif + int is_hw_chirp = 0; int i; int seg_id = DFS_80P80_SEG0; struct dfs_delayline *dl; @@ -404,11 +400,30 @@ int dfs_process_radarevent(struct ath_dfs *dfs, dfs->radar_log[i].dur = re.re_dur; dfs->dfs_event_log_count++; } - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s[%d]:xxxxx ts =%u re.re_dur=%u re.re_rssi =%u diff =%u pl->pl_lastelem.p_time=%llu xxxxx", - __func__, __LINE__, (uint32_t) this_ts, re.re_dur, - re.re_rssi, diff_ts, - (unsigned long long)pl->pl_elems[index].p_time); + if (re.rsu_version == DFS_RADAR_SUMMARY_REPORT_VERSION_3) { + if ((re.re_flags & DFS_EVENT_HW_CHIRP) == + DFS_EVENT_HW_CHIRP) + is_hw_chirp = 1; + + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, + "\n %s[%d]:PHYERR# = %d ts = %u diff_ts = %u ppdu_rssi = %u dur = %u is_hw_chirp = %d segid = %d sidx = %d peak_mag = %d delta_peak = %d delta_diff = %d agc_total_gain = %d agc_mb_gain = %d radar_subchan_mask = 0x%x pulse_height = %d triggering_agc_event = %d rs_pulse_rssi = %d pri80_inband_power = %d ext80_inband_power = %d \n", + __func__, __LINE__, + re.phyerr_serial_num, (uint32_t) this_ts, + diff_ts, re.re_rssi, re.re_dur, is_hw_chirp, + re.radar_80p80_segid, re.sidx, re.peak_mag, + re.delta_peak, re.delta_diff, + re.agc_total_gain, re.agc_mb_gain, + re.radar_subchan_mask, re.pulse_height, + re.triggering_agc_event, re.pulse_rssi, + re.radar_fft_pri80_inband_power, + re.radar_fft_ext80_inband_power); + } else { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, + "%s[%d]:xxxxx ts =%u re.re_dur=%u re.re_rssi =%u diff =%u pl->pl_lastelem.p_time=%llu xxxxx", + __func__, __LINE__, (uint32_t) this_ts, re.re_dur, + re.re_rssi, diff_ts, + (unsigned long long)pl->pl_elems[index].p_time); + } /* If diff_ts is very small, we might be getting false pulse detects * due to heavy interference. We might be getting spectral splatter -- cgit v1.2.3 From 44c44772ad4effec4fa605e1ebe1b1bfb727c7cc Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Mon, 11 Apr 2016 11:11:27 -0700 Subject: qcacld-3.0: Add PM semaphore related APIs in PLD Add PM semaphore related APIs in PLD, which is being used in BMI. CRs-Fixed: 1010156 Change-Id: Ief52f7b078ea62cae18508b9e523e2a19f3519b3 --- core/pld/inc/pld_common.h | 2 ++ core/pld/src/pld_common.c | 40 ++++++++++++++++++++++++++++++++++++++++ core/pld/src/pld_pcie.h | 8 ++++++++ 3 files changed, 50 insertions(+) diff --git a/core/pld/inc/pld_common.h b/core/pld/inc/pld_common.h index 9345eaffe7e7..8f009c43441c 100644 --- a/core/pld/inc/pld_common.h +++ b/core/pld/inc/pld_common.h @@ -342,5 +342,7 @@ 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); +void pld_lock_pm_sem(struct device *dev); +void pld_release_pm_sem(struct device *dev); #endif diff --git a/core/pld/src/pld_common.c b/core/pld/src/pld_common.c index 902c2108cb86..00d0e79368fc 100644 --- a/core/pld/src/pld_common.c +++ b/core/pld/src/pld_common.c @@ -1115,3 +1115,43 @@ int pld_get_ce_id(struct device *dev, int irq) return ret; } + +/** + * pld_lock_pm_sem() - Lock PM semaphore + * @dev: device + * + * Return: void + */ +void pld_lock_pm_sem(struct device *dev) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + cnss_lock_pm_sem(); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_release_pm_sem() - Release PM semaphore + * @dev: device + * + * Return: void + */ +void pld_release_pm_sem(struct device *dev) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE: + cnss_release_pm_sem(); + break; + case PLD_BUS_TYPE_SNOC: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} diff --git a/core/pld/src/pld_pcie.h b/core/pld/src/pld_pcie.h index 16d022b2a9ff..4e3191e4dfdf 100644 --- a/core/pld/src/pld_pcie.h +++ b/core/pld/src/pld_pcie.h @@ -179,6 +179,14 @@ static inline int cnss_auto_resume(void) { return 0; } +static void cnss_lock_pm_sem(void) +{ + return; +} +static void cnss_release_pm_sem(void) +{ + return; +} #else int pld_pcie_get_fw_files_for_target(struct pld_fw_files *pfw_files, u32 target_type, u32 target_version); -- cgit v1.2.3 From d698eb6cd3b7b29cfe73123b150a0cf5be91f008 Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Mon, 11 Apr 2016 11:43:30 -0700 Subject: qcacld-3.0: Add support for registering runtime PM APIs Add support for registering runtime PM APIs in PLD. CRs-Fixed: 1010156 Change-Id: I8747edd0f8fc4bd79f72f7fba4b65d8c6ebd6887 --- core/pld/inc/pld_common.h | 10 +++++++++ core/pld/src/pld_pcie.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/core/pld/inc/pld_common.h b/core/pld/inc/pld_common.h index 8f009c43441c..53f25b4394a1 100644 --- a/core/pld/inc/pld_common.h +++ b/core/pld/inc/pld_common.h @@ -268,6 +268,12 @@ struct pld_soc_info { * is enabled * @modem_status: optional operation, will be called when platform driver * sending modem power status to WLAN FW + * @runtime_suspend: optional operation, prepare the device for a condition + * in which it won't be able to communicate with the CPU(s) + * and RAM due to power management. + * @runtime_resume: optional operation, put the device into the fully + * active state in response to a wakeup event generated by + * hardware or at the request of software. */ struct pld_driver_ops { int (*probe)(struct device *dev, @@ -290,6 +296,10 @@ struct pld_driver_ops { void (*modem_status)(struct device *dev, enum pld_bus_type bus_type, int state); + int (*runtime_suspend)(struct device *dev, + enum pld_bus_type bus_type); + int (*runtime_resume)(struct device *dev, + enum pld_bus_type bus_type); }; int pld_init(void); diff --git a/core/pld/src/pld_pcie.c b/core/pld/src/pld_pcie.c index ca7778059b55..ab3cbd1e52eb 100644 --- a/core/pld/src/pld_pcie.c +++ b/core/pld/src/pld_pcie.c @@ -198,6 +198,48 @@ static void pld_pcie_notify_handler(struct pci_dev *pdev, int state) pld_context->ops->modem_status(&pdev->dev, PLD_BUS_TYPE_PCIE, state); } + +#ifdef FEATURE_RUNTIME_PM +/** + * pld_pcie_runtime_suspend() - PM runtime suspend + * @pdev: PCIE device + * + * PM runtime suspend callback function. + * + * Return: int + */ +static int pld_pcie_runtime_suspend(struct pci_dev *pdev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->runtime_suspend) + return pld_context->ops->runtime_suspend(&pdev->dev, + PLD_BUS_TYPE_PCIE); + + return -ENODEV; +} + +/** + * pld_pcie_runtime_resume() - PM runtime resume + * @pdev: PCIE device + * + * PM runtime resume callback function. + * + * Return: int + */ +static int pld_pcie_runtime_resume(struct pci_dev *pdev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->runtime_resume) + return pld_context->ops->runtime_resume(&pdev->dev, + PLD_BUS_TYPE_PCIE); + + return -ENODEV; +} +#endif #endif /** @@ -246,6 +288,13 @@ static struct pci_device_id pld_pcie_id_table[] = { }; #ifdef CONFIG_CNSS +#ifdef FEATURE_RUNTIME_PM +struct cnss_wlan_runtime_ops runtime_pm_ops = { + .runtime_suspend = pld_pcie_runtime_suspend, + .runtime_resume = pld_pcie_runtime_resume, +}; +#endif + struct cnss_wlan_driver pld_pcie_ops = { .name = "pld_pcie", .id_table = pld_pcie_id_table, @@ -259,6 +308,9 @@ struct cnss_wlan_driver pld_pcie_ops = { .suspend = pld_pcie_suspend, .resume = pld_pcie_resume, #endif +#ifdef FEATURE_RUNTIME_PM + .runtime_ops = &runtime_pm_ops, +#endif }; /** -- cgit v1.2.3 From 466ccb70fbff445200431b5700f5230ae09c46e6 Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Thu, 21 Apr 2016 15:13:22 -0700 Subject: qcacld-3.0: Protect cnss_wlan_pm_control under CONFIG_PCI_MSM Add CONFIG_PCI_MSM flag for cnss_wlan_pm_control. CRs-Fixed: 1010156 Change-Id: Icba6ec0952f899a2602751340a45f597eaf87d35 --- core/pld/src/pld_pcie.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/core/pld/src/pld_pcie.h b/core/pld/src/pld_pcie.h index 4e3191e4dfdf..adc830e4cda7 100644 --- a/core/pld/src/pld_pcie.h +++ b/core/pld/src/pld_pcie.h @@ -88,6 +88,13 @@ static inline void *cnss_get_fw_ptr(void) } #endif +#if (!defined(CONFIG_CNSS)) || (!defined(CONFIG_PCI_MSM)) +static inline int cnss_wlan_pm_control(bool vote) +{ + return 0; +} +#endif + #ifndef CONFIG_CNSS static inline int pld_pcie_get_fw_files_for_target(struct pld_fw_files *pfw_files, @@ -131,10 +138,6 @@ 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; -- cgit v1.2.3 From 9a7ba50ddd7280a03c2d32be069178ec21aaf2f1 Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Fri, 8 Apr 2016 14:15:36 -0700 Subject: qcacld-3.0: BMI: Clean up BMI unused code Clean up bmi_2 related code. These code are hardware/platform specific which is no longer supported. CRs-Fixed: 1001252 Change-Id: I783f4a411044268d24ba660ce9f10dabe0cce8bf --- Kbuild | 12 -- core/bmi/src/bmi.c | 71 -------- core/bmi/src/bmi_2.c | 490 --------------------------------------------------- core/bmi/src/ol_fw.c | 4 - 4 files changed, 577 deletions(-) delete mode 100644 core/bmi/src/bmi_2.c diff --git a/Kbuild b/Kbuild index 11eed090633c..5440b8ac1d24 100755 --- a/Kbuild +++ b/Kbuild @@ -129,10 +129,6 @@ ifeq ($(KERNEL_BUILD), 0) CONFIG_LINUX_QCMBR :=y endif - ifeq ($(CONFIG_CNSS_EOS),y) - CONFIG_FEATURE_BMI_2 :=y - endif - CONFIG_MPC_UT_FRAMEWORK := y #Flag to enable offload packets feature @@ -675,11 +671,7 @@ BMI_INC := -I$(WLAN_ROOT)/$(BMI_DIR)/inc BMI_OBJS := $(BMI_DIR)/src/bmi.o \ $(BMI_DIR)/src/ol_fw.o -ifeq ($(CONFIG_FEATURE_BMI_2), y) -BMI_OBJS += $(BMI_DIR)/src/bmi_2.o -else BMI_OBJS += $(BMI_DIR)/src/bmi_1.o -endif ########### WMI ########### WMI_ROOT_DIR := wmi @@ -1015,10 +1007,6 @@ CDEFINES += -DFEATURE_NAPI_DEBUG endif endif -ifeq ($(CONFIG_FEATURE_BMI_2), y) -CDEFINES += -DFEATURE_BMI_2 -endif - ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM))) CDEFINES += -DMSM_PLATFORM endif diff --git a/core/bmi/src/bmi.c b/core/bmi/src/bmi.c index 5752ccc0d6e9..fc9969d7d993 100644 --- a/core/bmi/src/bmi.c +++ b/core/bmi/src/bmi.c @@ -30,38 +30,6 @@ /* APIs visible to the driver */ -/* BMI_1 refers QCA6174 target; the ADDR is AXI addr */ -#define BMI_1_TEST_ADDR (0xa0000) -/* BMI_2 ; */ -#define BMI_2_TEST_ADDR (0x6E0000) -/* Enable BMI_TEST COMMANDs; The Value 0x09 is randomly choosen */ -#define BMI_TEST_ENABLE (0x09) - -#ifndef CONFIG_CNSS -#define SHOULD_RUN_BMI_TEST_COMMANDS false -#else -#define SHOULD_RUN_BMI_TEST_COMMANDS (BMI_TEST_ENABLE == cnss_get_bmi_setup()) -#endif - -static QDF_STATUS -bmi_command_test(uint32_t command, uint32_t address, uint8_t *data, - uint32_t length, struct ol_context *ol_ctx) -{ - switch (command) { - case BMI_NO_COMMAND: - return bmi_no_command(ol_ctx); - case BMI_WRITE_MEMORY: - return bmi_write_memory(address, data, length, ol_ctx); - case BMI_READ_MEMORY: - return bmi_read_memory(address, data, length, ol_ctx); - case BMI_EXECUTE: - return bmi_execute(address, (uint32_t *)data, ol_ctx); - default: - break; - } - return QDF_STATUS_SUCCESS; -} - QDF_STATUS bmi_init(struct ol_context *ol_ctx) { struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx); @@ -214,43 +182,6 @@ bmi_get_target_info(struct bmi_target_info *targ_info, return QDF_STATUS_SUCCESS; } -#ifdef FEATURE_BMI_2 -static inline uint32_t bmi_get_test_addr(void) -{ - return BMI_2_TEST_ADDR; -} -#else -static inline uint32_t bmi_get_test_addr(void) -{ - return BMI_1_TEST_ADDR; -} -#endif - -/** - * run_bmi_test() - run some bmi tests - * @ol_ctx: bmi context - * - */ -static void run_bmi_test(struct ol_context *ol_ctx) -{ - uint8_t data[10], out[10]; - uint32_t address; - int32_t ret; - - ret = snprintf(data, 10, "ABCDEFGHI"); - BMI_DBG("ret:%d writing data:%s\n", ret, data); - address = bmi_get_test_addr(); - - if (bmi_init(ol_ctx) != QDF_STATUS_SUCCESS) { - BMI_WARN("BMI_INIT Failed; No Memory!"); - return; - } - bmi_command_test(BMI_NO_COMMAND, address, data, 9, ol_ctx); - bmi_command_test(BMI_WRITE_MEMORY, address, data, 9, ol_ctx); - bmi_command_test(BMI_READ_MEMORY, address, out, 9, ol_ctx); - BMI_DBG("Output:%s", out); -} - QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx) { struct hif_opaque_softc *scn = ol_ctx->scn; @@ -264,8 +195,6 @@ QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx) return QDF_STATUS_NOT_INITIALIZED; } - if (SHOULD_RUN_BMI_TEST_COMMANDS) - run_bmi_test(ol_ctx); return bmi_firmware_download(ol_ctx); } diff --git a/core/bmi/src/bmi_2.c b/core/bmi/src/bmi_2.c deleted file mode 100644 index 59c6dd605461..000000000000 --- a/core/bmi/src/bmi_2.c +++ /dev/null @@ -1,490 +0,0 @@ -/* - * copyright (c) 2014-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 "i_bmi.h" -#include "cds_api.h" -/* This need to defined in firmware interface files. - * Defining here to address compilation issues. - * Will be deleted once firmware interface files for - * target are merged - */ -#define BMI_LOAD_IMAGE 18 - -QDF_STATUS -bmi_no_command(struct ol_context *ol_ctx) -{ - struct hif_opaque_softc *scn = ol_ctx->scn; - uint32_t cid; - int status; - uint32_t length; - uint8_t ret = 0; - struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx); - uint8_t *bmi_cmd_buff = info->bmi_cmd_buff; - uint8_t *bmi_rsp_buff = info->bmi_rsp_buff; - qdf_dma_addr_t cmd = info->bmi_cmd_da; - qdf_dma_addr_t rsp = info->bmi_rsp_da; - - if (info->bmi_done) { - BMI_ERR("Command disallowed: BMI DONE ALREADY"); - return QDF_STATUS_E_PERM; - } - - if (!bmi_cmd_buff || !bmi_rsp_buff) { - BMI_ERR("No Memory Allocated for BMI CMD/RSP Buffer"); - return QDF_STATUS_NOT_INITIALIZED; - } - cid = BMI_NO_COMMAND; - - qdf_mem_copy(bmi_cmd_buff, &cid, sizeof(cid)); - length = sizeof(ret); - - status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, sizeof(cid), - bmi_rsp_buff, &length, BMI_EXCHANGE_TIMEOUT_MS); - - if (status) { - BMI_ERR("Failed to write bmi no command status:%d", status); - return QDF_STATUS_E_FAILURE; - } - - qdf_mem_copy(&ret, bmi_rsp_buff, length); - if (ret != 0) { - BMI_ERR("bmi no command response error ret 0x%x", ret); - return QDF_STATUS_E_FAILURE; - } - return QDF_STATUS_SUCCESS; -} - -QDF_STATUS -bmi_done_local(struct ol_context *ol_ctx) -{ - struct hif_opaque_softc *scn = ol_ctx->scn; - uint32_t cid; - int status; - uint32_t length; - uint8_t ret = 0; - struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx); - uint8_t *bmi_cmd_buff = info->bmi_cmd_buff; - uint8_t *bmi_rsp_buff = info->bmi_rsp_buff; - qdf_device_t qdf_dev = ol_ctx->qdf_dev; - qdf_dma_addr_t cmd = info->bmi_cmd_da; - qdf_dma_addr_t rsp = info->bmi_rsp_da; - - if (info->bmi_done) { - BMI_ERR("Command disallowed"); - return QDF_STATUS_E_PERM; - } - - if (!bmi_cmd_buff || !bmi_rsp_buff) { - BMI_ERR("No Memory Allocated for BMI CMD/RSP Buffer"); - return QDF_STATUS_NOT_INITIALIZED; - } - - if (!qdf_dev->dev) { - BMI_ERR("%s Invalid Device pointer", __func__); - return QDF_STATUS_NOT_INITIALIZED; - } - - cid = BMI_DONE; - - qdf_mem_copy(bmi_cmd_buff, &cid, sizeof(cid)); - length = sizeof(ret); - - status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, sizeof(cid), - bmi_rsp_buff, &length, BMI_EXCHANGE_TIMEOUT_MS); - - if (status) { - BMI_ERR("Failed to close BMI on target status:%d", status); - return QDF_STATUS_E_FAILURE; - } - qdf_mem_copy(&ret, bmi_rsp_buff, length); - - if (ret != 0) { - BMI_ERR("BMI DONE response failed:%d", ret); - return QDF_STATUS_E_FAILURE; - } - - if (info->bmi_cmd_buff) { - qdf_mem_free_consistent(qdf_dev, qdf_dev->dev, - MAX_BMI_CMDBUF_SZ, - info->bmi_cmd_buff, info->bmi_cmd_da, 0); - info->bmi_cmd_buff = NULL; - info->bmi_cmd_da = 0; - } - - if (info->bmi_rsp_buff) { - qdf_mem_free_consistent(qdf_dev, qdf_dev->dev, - MAX_BMI_CMDBUF_SZ, - info->bmi_rsp_buff, info->bmi_rsp_da, 0); - info->bmi_rsp_buff = NULL; - info->bmi_rsp_da = 0; - } - - return QDF_STATUS_SUCCESS; -} - -QDF_STATUS bmi_write_memory(uint32_t address, uint8_t *buffer, uint32_t length, - struct ol_context *ol_ctx) -{ - uint32_t cid; - int status; - uint32_t rsp_len; - uint8_t ret = 0; - uint32_t offset; - uint32_t remaining, txlen; - const uint32_t header = sizeof(cid) + sizeof(address) + sizeof(length); - uint8_t aligned_buffer[BMI_DATASZ_MAX]; - uint8_t *src; - struct hif_opaque_softc *scn = ol_ctx->scn; - struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx); - uint8_t *bmi_cmd_buff = info->bmi_cmd_buff; - uint8_t *bmi_rsp_buff = info->bmi_rsp_buff; - qdf_dma_addr_t cmd = info->bmi_cmd_da; - qdf_dma_addr_t rsp = info->bmi_rsp_da; - - if (info->bmi_done) { - BMI_ERR("Command disallowed"); - return QDF_STATUS_E_PERM; - } - - if (!bmi_cmd_buff || !bmi_rsp_buff) { - BMI_ERR("BMI Initialization is not happened"); - return QDF_STATUS_NOT_INITIALIZED; - } - - bmi_assert(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header)); - qdf_mem_set(bmi_cmd_buff, 0, BMI_DATASZ_MAX + header); - - cid = BMI_WRITE_MEMORY; - rsp_len = sizeof(ret); - - remaining = length; - while (remaining) { - src = &buffer[length - remaining]; - if (remaining < (BMI_DATASZ_MAX - header)) { - if (remaining & 3) { - /* align it with 4 bytes */ - remaining = remaining + (4 - (remaining & 3)); - memcpy(aligned_buffer, src, remaining); - src = aligned_buffer; - } - txlen = remaining; - } else { - txlen = (BMI_DATASZ_MAX - header); - } - offset = 0; - qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - qdf_mem_copy(&(bmi_cmd_buff[offset]), &address, - sizeof(address)); - offset += sizeof(address); - qdf_mem_copy(&(bmi_cmd_buff[offset]), &txlen, sizeof(txlen)); - offset += sizeof(txlen); - qdf_mem_copy(&(bmi_cmd_buff[offset]), src, txlen); - offset += txlen; - status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, - offset, bmi_rsp_buff, &rsp_len, - BMI_EXCHANGE_TIMEOUT_MS); - if (status) { - BMI_ERR("BMI Write Memory Failed status:%d", status); - return QDF_STATUS_E_FAILURE; - } - qdf_mem_copy(&ret, bmi_rsp_buff, rsp_len); - if (ret != 0) { - BMI_ERR("BMI Write memory response fail: %x", ret); - return QDF_STATUS_E_FAILURE; - } - remaining -= txlen; address += txlen; - } - - return QDF_STATUS_SUCCESS; -} - -QDF_STATUS -bmi_read_memory(uint32_t address, uint8_t *buffer, - uint32_t length, struct ol_context *ol_ctx) -{ - struct hif_opaque_softc *scn = ol_ctx->scn; - uint32_t cid; - int status; - uint8_t ret = 0; - uint32_t offset; - uint32_t remaining, rxlen, rsp_len, total_len; - struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx); - uint8_t *bmi_cmd_buff = info->bmi_cmd_buff; - /* note we reuse the same buffer to receive on */ - uint8_t *bmi_rsp_buff = info->bmi_rsp_buff; - uint32_t size = sizeof(cid) + sizeof(address) + sizeof(length); - qdf_dma_addr_t cmd = info->bmi_cmd_da; - qdf_dma_addr_t rsp = info->bmi_rsp_da; - - if (info->bmi_done) { - BMI_ERR("Command disallowed"); - return QDF_STATUS_E_PERM; - } - if (!bmi_cmd_buff || !bmi_rsp_buff) { - BMI_ERR("BMI Initialization is not done"); - return QDF_STATUS_NOT_INITIALIZED; - } - - bmi_assert(BMI_COMMAND_FITS(BMI_DATASZ_MAX + size)); - qdf_mem_set(bmi_cmd_buff, 0, BMI_DATASZ_MAX + size); - qdf_mem_set(bmi_rsp_buff, 0, BMI_DATASZ_MAX + size); - - cid = BMI_READ_MEMORY; - rsp_len = sizeof(ret); - remaining = length; - - while (remaining) { - rxlen = (remaining < BMI_DATASZ_MAX - rsp_len) ? remaining : - (BMI_DATASZ_MAX - rsp_len); - offset = 0; - qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - qdf_mem_copy(&(bmi_cmd_buff[offset]), &address, - sizeof(address)); - offset += sizeof(address); - qdf_mem_copy(&(bmi_cmd_buff[offset]), &rxlen, sizeof(rxlen)); - offset += sizeof(length); - - total_len = rxlen + rsp_len; - - status = hif_exchange_bmi_msg(scn, cmd, rsp, - bmi_cmd_buff, - offset, - bmi_rsp_buff, - &total_len, - BMI_EXCHANGE_TIMEOUT_MS); - - if (status) { - BMI_ERR("BMI Read memory failed status:%d", status); - return QDF_STATUS_E_FAILURE; - } - - qdf_mem_copy(&ret, bmi_rsp_buff, rsp_len); - - if (ret != 0) { - BMI_ERR("bmi read memory response fail %x", ret); - return QDF_STATUS_E_FAILURE; - } - - qdf_mem_copy(&buffer[length - remaining], - (uint8_t *)bmi_rsp_buff + rsp_len, rxlen); - remaining -= rxlen; address += rxlen; - } - - return QDF_STATUS_SUCCESS; -} - -QDF_STATUS -bmi_execute(uint32_t address, uint32_t *param, struct ol_context *ol_ctx) -{ - struct hif_opaque_softc *scn = ol_ctx->scn; - uint32_t cid; - int status; - uint32_t length; - uint8_t ret = 0; - struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx); - uint8_t *bmi_cmd_buff = info->bmi_cmd_buff; - uint8_t *bmi_rsp_buff = info->bmi_rsp_buff; - qdf_dma_addr_t cmd = info->bmi_cmd_da; - qdf_dma_addr_t rsp = info->bmi_rsp_da; - - if (info->bmi_done) { - BMI_ERR("Command disallowed"); - return QDF_STATUS_E_PERM; - } - - if (!bmi_cmd_buff || !bmi_rsp_buff) { - BMI_ERR("No Memory Allocated for bmi buffers"); - return QDF_STATUS_NOT_INITIALIZED; - } - - cid = BMI_EXECUTE; - - qdf_mem_copy(bmi_cmd_buff, &cid, sizeof(cid)); - length = sizeof(ret); - - status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, sizeof(cid), - bmi_rsp_buff, &length, BMI_EXCHANGE_TIMEOUT_MS); - - if (status) { - BMI_ERR("Failed to do BMI_EXECUTE status:%d", status); - return QDF_STATUS_E_FAILURE; - } - - qdf_mem_copy(&ret, bmi_rsp_buff, length); - - if (ret != 0) { - BMI_ERR("%s: ret 0x%x", __func__, ret); - return QDF_STATUS_E_FAILURE; - } - return QDF_STATUS_SUCCESS; -} - -static QDF_STATUS -bmi_load_image(dma_addr_t address, - uint32_t size, struct ol_context *ol_ctx) -{ - uint32_t cid; - QDF_STATUS status; - uint32_t offset; - uint32_t length; - uint8_t ret = 0; - struct hif_opaque_softc *scn = ol_ctx->scn; - struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx); - uint8_t *bmi_cmd_buff = info->bmi_cmd_buff; - uint8_t *bmi_rsp_buff = info->bmi_rsp_buff; - qdf_dma_addr_t cmd = info->bmi_cmd_da; - qdf_dma_addr_t rsp = info->bmi_rsp_da; - - uint32_t addr_h, addr_l; - - if (info->bmi_done) { - BMI_ERR("Command disallowed"); - return QDF_STATUS_E_PERM; - } - - if (!bmi_cmd_buff || !bmi_rsp_buff) { - BMI_ERR("No Memory Allocated for BMI CMD/RSP Buffer"); - return QDF_STATUS_NOT_INITIALIZED; - } - - bmi_assert(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); - qdf_mem_set(bmi_cmd_buff, 0, sizeof(cid) + sizeof(address)); - - - BMI_DBG("%s: Enter device: 0x%p, size %d", __func__, scn, size); - - cid = BMI_LOAD_IMAGE; - - offset = 0; - qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - addr_l = address & 0xffffffff; - addr_h = 0x00; - qdf_mem_copy(&(bmi_cmd_buff[offset]), &addr_l, sizeof(addr_l)); - offset += sizeof(addr_l); - qdf_mem_copy(&(bmi_cmd_buff[offset]), &addr_h, sizeof(addr_h)); - offset += sizeof(addr_h); - qdf_mem_copy(&(bmi_cmd_buff[offset]), &size, sizeof(size)); - offset += sizeof(size); - length = sizeof(ret); - - status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, offset, - bmi_rsp_buff, &length, BMI_EXCHANGE_TIMEOUT_MS); - - if (status) { - BMI_ERR("BMI Load Image Failed; status:%d", status); - return QDF_STATUS_E_FAILURE; - } - - qdf_mem_copy(&ret, bmi_rsp_buff, length); - if (ret != 0) { - BMI_ERR("%s: ret 0x%x", __func__, ret); - return QDF_STATUS_E_FAILURE; - } - return QDF_STATUS_SUCCESS; -} - -static QDF_STATUS bmi_enable(struct ol_context *ol_ctx) -{ - struct hif_opaque_softc *scn = ol_ctx->scn; - struct bmi_target_info targ_info; - struct image_desc_info image_desc_info; - QDF_STATUS status; - struct hif_target_info *tgt_info; - struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx); - - if (!scn) { - BMI_ERR("Invalid scn context"); - bmi_assert(0); - return QDF_STATUS_NOT_INITIALIZED; - } - - tgt_info = hif_get_target_info_handle(scn); - - if (info->bmi_cmd_buff == NULL || info->bmi_rsp_buff == NULL) { - BMI_ERR("bmi_open failed!"); - return QDF_STATUS_NOT_INITIALIZED; - } - - status = bmi_get_target_info(&targ_info, ol_ctx); - if (status != QDF_STATUS_SUCCESS) - return status; - - BMI_DBG("%s: target type 0x%x, target ver 0x%x", __func__, - targ_info.target_type, targ_info.target_ver); - - tgt_info->target_type = targ_info.target_type; - tgt_info->target_version = targ_info.target_ver; - - if (cnss_get_fw_image(&image_desc_info) != 0) { - BMI_ERR("Failed to get fw image"); - return QDF_STATUS_E_FAILURE; - } - - status = bmi_load_image(image_desc_info.bdata_addr, - image_desc_info.bdata_size, - ol_ctx); - if (status != QDF_STATUS_SUCCESS) { - BMI_ERR("Load board data failed! status:%d", status); - return status; - } - - status = bmi_load_image(image_desc_info.fw_addr, - image_desc_info.fw_size, - ol_ctx); - if (status != QDF_STATUS_SUCCESS) - BMI_ERR("Load fw image failed! status:%d", status); - - return status; -} - -QDF_STATUS bmi_firmware_download(struct ol_context *ol_ctx) -{ - QDF_STATUS status; - - if (NO_BMI) - return QDF_STATUS_SUCCESS; - - status = bmi_init(ol_ctx); - if (status != QDF_STATUS_SUCCESS) { - BMI_ERR("BMI_INIT Failed status:%d", status); - goto end; - } - - status = bmi_enable(ol_ctx); - if (status != QDF_STATUS_SUCCESS) { - BMI_ERR("BMI_ENABLE failed status:%d\n", status); - goto err_bmi_enable; - } - - return status; -err_bmi_enable: - bmi_cleanup(ol_ctx); -end: - return status; -} diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c index 2950a69ebd50..3314d75c7e36 100644 --- a/core/bmi/src/ol_fw.c +++ b/core/bmi/src/ol_fw.c @@ -1264,9 +1264,7 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx) /* Execute the OTP code only if entry found and downloaded */ if (status == EOK) { param = 0; -#ifndef FEATURE_BMI_2 bmi_execute(address, ¶m, ol_ctx); -#endif } else if (status < 0) { return status; } @@ -1275,9 +1273,7 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx) if (ol_transfer_bin_file(ol_ctx, ATH_SETUP_FILE, BMI_SEGMENTED_WRITE_ADDR, true) == EOK) { param = 0; -#ifndef FEATURE_BMI_2 bmi_execute(address, ¶m, ol_ctx); -#endif } /* Download Target firmware -- cgit v1.2.3 From f21b3b64fdc76e3f6a249f0e315ce005ef78914e Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Mon, 2 May 2016 16:33:55 +0530 Subject: qcacld-3.0: Fix the missing propagation in MCC to SCC switch scenarios Fix the missing propagation while sending channel switch request instead of doing SAP restart. A couple of lines of the change I79e7317219503de0a9957940f3cf7a4e91c7a521 that are missing have been restored. Change-Id: I7f881d4f6793ec8c85e6f4ab41b90fb77d16f828 CRs-Fixed: 1010524 --- core/sme/src/csr/csr_util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index 1a3a2b67d7fb..7e44a7c12371 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -788,7 +788,9 @@ uint16_t csr_check_concurrent_channel_overlap(tpAniSirGlobal mac_ctx, (intf_hfreq > sap_lfreq && intf_hfreq < sap_hfreq)))) intf_ch = 0; } else if (intf_ch && sap_ch != intf_ch && - cc_switch_mode == QDF_MCC_TO_SCC_SWITCH_FORCE) { + ((cc_switch_mode == QDF_MCC_TO_SCC_SWITCH_FORCE) || + (cc_switch_mode == + QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION))) { if (!((intf_ch < 14 && sap_ch < 14) || (intf_ch > 14 && sap_ch > 14))) intf_ch = 0; -- cgit v1.2.3 From 009d6cfbe74ac202c6d4435fcf8a2097acb88d6a Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Wed, 4 May 2016 12:22:46 +0530 Subject: qcacld-3.0: Wait for Nss update only in the case of beaconing modes Ensure that the wait for Nss update happens only in the case of beaconing modes. Nss update request is done only in the case of beaconing modes. As part of Nss update callback, check for Nss update is being done for all modes due to which subsequent hardware mode change is not getting initiated. Fix the same by ensuring that the check for Nss update happens only in the case of beaconing modes. Change-Id: Icf975661236dba54d2948484445b0509e15f1da0 CRs-Fixed: 1011483 --- core/cds/src/cds_concurrency.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index 478a27f19083..9d41c9fd5c76 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -5976,7 +5976,11 @@ bool cds_wait_for_nss_update(uint8_t action) [conn_index].tx_spatial_stream == 2) && (conc_connection_list [conn_index].rx_spatial_stream == 2) && - conc_connection_list[conn_index].in_use) { + conc_connection_list[conn_index].in_use && + ((conc_connection_list[conn_index].mode == + CDS_P2P_GO_MODE) || + (conc_connection_list[conn_index].mode == + CDS_SAP_MODE))) { wait = true; break; } @@ -5991,7 +5995,11 @@ bool cds_wait_for_nss_update(uint8_t action) [conn_index].tx_spatial_stream == 1) && (conc_connection_list [conn_index].rx_spatial_stream == 1) && - conc_connection_list[conn_index].in_use) { + conc_connection_list[conn_index].in_use && + ((conc_connection_list[conn_index].mode == + CDS_P2P_GO_MODE) || + (conc_connection_list[conn_index].mode == + CDS_SAP_MODE))) { wait = true; break; } -- cgit v1.2.3 From b58786d4026f771c2471fe6d96e168b8d4381c6c Mon Sep 17 00:00:00 2001 From: Dhanashri Atre Date: Thu, 21 Apr 2016 16:37:20 -0700 Subject: qcacld-3.0: Enable LRO Enable Large Receive Offload (LRO) on the data path. Change-Id: Ia0dff3ebbfd557f247a14bcff614b9ccc793cb13 CRs-Fixed: 974833 --- config/WCNSS_qcom_cfg.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/WCNSS_qcom_cfg.ini b/config/WCNSS_qcom_cfg.ini index 8b05331feb13..da8550c68556 100644 --- a/config/WCNSS_qcom_cfg.ini +++ b/config/WCNSS_qcom_cfg.ini @@ -593,6 +593,10 @@ gEnableFastPath=1 # 1 - enable TSOEnable=1 +# Enable Large Receive Offload +# 0 - disable +# 1 - enable +LROEnable=1 END # Note: Configuration parser would not read anything past the END marker -- cgit v1.2.3 From 27a7eabd9438c926d21702c1cd69ac04ef449a0a Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Fri, 22 Apr 2016 16:34:05 -0700 Subject: qcacld-3.0: Remove the vhtTxChannelWidthSet parameter vhtTxChannelWidthSet is redundant parameter for channel width as phy_ch_width is used to represent the channel width. So remove the redundant parameter Change-Id: Ied9ef3dddfcb89bac8d49c5c0dd2f21b3d041567 CRs-Fixed: 1007367 --- core/mac/inc/sir_api.h | 1 - core/mac/src/pe/include/lim_session.h | 1 - core/mac/src/pe/lim/lim_api.c | 2 -- core/mac/src/pe/lim/lim_prop_exts_utils.c | 2 -- core/mac/src/pe/lim/lim_send_sme_rsp_messages.c | 4 ---- core/mac/src/sys/legacy/src/utils/src/parser_api.c | 2 +- core/sme/inc/csr_api.h | 1 - core/sme/src/csr/csr_api_roam.c | 1 - 8 files changed, 1 insertion(+), 13 deletions(-) diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index bc35820e756e..af34c8ef786e 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -682,7 +682,6 @@ typedef struct sSirSmeHTProfile { uint8_t htRecommendedTxWidthSet; ePhyChanBondState htSecondaryChannelOffset; uint8_t vhtCapability; - uint8_t vhtTxChannelWidthSet; uint8_t apCenterChan; uint8_t apChanWidth; } tSirSmeHTProfile; diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index c44aecc887aa..483c9bd77768 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -309,7 +309,6 @@ typedef struct sPESession /* Added to Support BT-AMP */ tBeaconParams beaconParams; uint8_t vhtCapability; - uint8_t vhtTxChannelWidthSet; tLimOperatingModeInfo gLimOperatingMode; uint8_t vhtCapabilityPresentInBeacon; uint8_t ch_center_freq_seg0; diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index 5912165c93aa..c893536b0d18 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -1699,8 +1699,6 @@ void lim_fill_join_rsp_ht_caps(tpPESession session, tpSirSmeJoinRsp join_rsp) ht_profile->dot11mode = session->dot11mode; ht_profile->htCapability = session->htCapability; ht_profile->vhtCapability = session->vhtCapability; - ht_profile->vhtTxChannelWidthSet = - session->vhtTxChannelWidthSet; ht_profile->apCenterChan = session->ch_center_freq_seg0; ht_profile->apChanWidth = session->ch_width; } diff --git a/core/mac/src/pe/lim/lim_prop_exts_utils.c b/core/mac/src/pe/lim/lim_prop_exts_utils.c index 93f820141d72..8961a2c9b411 100644 --- a/core/mac/src/pe/lim/lim_prop_exts_utils.c +++ b/core/mac/src/pe/lim/lim_prop_exts_utils.c @@ -123,8 +123,6 @@ lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie, beacon_struct->VHTOperation.present && session->vhtCapability) { session->vhtCapabilityPresentInBeacon = 1; - session->vhtTxChannelWidthSet = - beacon_struct->VHTOperation.chanWidth; if (((beacon_struct->Vendor1IEPresent && beacon_struct->vendor2_ie.present && beacon_struct->Vendor3IEPresent)) && diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c index 50719daca663..0f87a6dc6874 100644 --- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c @@ -353,8 +353,6 @@ static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx, ht_profile->htCapability = session_entry->htCapability; ht_profile->vhtCapability = session_entry->vhtCapability; - ht_profile->vhtTxChannelWidthSet = - session_entry->vhtTxChannelWidthSet; ht_profile->apCenterChan = session_entry->ch_center_freq_seg0; ht_profile->apChanWidth = session_entry->ch_width; } @@ -648,8 +646,6 @@ lim_send_sme_start_bss_rsp(tpAniSirGlobal pMac, psessionEntry->htCapability; pSirSmeRsp->HTProfile.vhtCapability = psessionEntry->vhtCapability; - pSirSmeRsp->HTProfile.vhtTxChannelWidthSet = - psessionEntry->vhtTxChannelWidthSet; pSirSmeRsp->HTProfile.apCenterChan = psessionEntry->ch_center_freq_seg0; pSirSmeRsp->HTProfile.apChanWidth = diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index b09657033abc..550443955588 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -304,7 +304,7 @@ populate_dot11_supp_operating_classes(tpAniSirGlobal mac_ptr, { uint8_t ch_bandwidth; - if (session_entry->vhtTxChannelWidthSet == eHT_CHANNEL_WIDTH_80MHZ) { + if (session_entry->ch_width == CH_WIDTH_80MHZ) { ch_bandwidth = BW80; } else { switch (session_entry->htSecondaryChannelOffset) { diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 3071a777c1c7..3b74d5ef9a08 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -939,7 +939,6 @@ typedef struct tagCsrRoamHTProfile { uint8_t htRecommendedTxWidthSet; ePhyChanBondState htSecondaryChannelOffset; uint8_t vhtCapability; - uint8_t vhtTxChannelWidthSet; uint8_t apCenterChan; uint8_t apChanWidth; } tCsrRoamHTProfile; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index d0b29e2129a8..1a732e3ee09d 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -5946,7 +5946,6 @@ static void csr_roam_copy_ht_profile(tCsrRoamHTProfile *dst_profile, dst_profile->htSecondaryChannelOffset = src_profile->htSecondaryChannelOffset; dst_profile->vhtCapability = src_profile->vhtCapability; - dst_profile->vhtTxChannelWidthSet = src_profile->vhtTxChannelWidthSet; dst_profile->apCenterChan = src_profile->apCenterChan; dst_profile->apChanWidth = src_profile->apChanWidth; } -- cgit v1.2.3 From ba3b431b293a26f96157997f949ccb31e7b7153c Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Fri, 29 Apr 2016 16:40:20 -0700 Subject: qcacld-3.0: Fix the issue in processing the del_tspec req SME qos expects the RIC data and RIC data length to process the add_ts response after roaming and updates the qos state to QOS_ON after the successful processing. RIC data is included in re-assoc response frame and updated in pe session. Since the RIC data info is not given to SME qos in roam sync event processing, qos state is not updated, hence the del_tspec command is buffered and not processed. Send the RIC data info to SME qos in roam sync processing so that the SME qos state is updated properly and processes any buffered commands. Change-Id: I7551b0bab4f11fe2d68c014cf89834ba199ad5ff CRs-Fixed: 1010374 --- core/mac/src/pe/lim/lim_api.c | 26 ++++++++++++++++++++++++++ core/sme/src/csr/csr_api_roam.c | 14 ++++++++++++++ core/sme/src/csr/csr_neighbor_roam.c | 10 +++++----- core/sme/src/qos/sme_qos.c | 7 ++++++- core/wma/src/wma_scan_roam.c | 5 +---- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index c893536b0d18..31df90976b53 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -1878,6 +1878,7 @@ QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx, tpAddBssParams add_bss_params; uint8_t local_nss; QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint16_t join_rsp_len; if (!roam_sync_ind_ptr) { lim_log(mac_ctx, LOGE, FL("LFR3:roam_sync_ind_ptr is NULL")); @@ -1987,6 +1988,31 @@ QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx, curr_sta_ds->nss = local_nss; ft_session_ptr->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; lim_init_tdls_data(mac_ctx, ft_session_ptr); + join_rsp_len = ft_session_ptr->RICDataLen + sizeof(tSirSmeJoinRsp) - + sizeof(uint8_t); + roam_sync_ind_ptr->join_rsp = qdf_mem_malloc(join_rsp_len); + if (NULL == roam_sync_ind_ptr->join_rsp) { + lim_log(mac_ctx, LOGE, FL("LFR3:mem alloc failed")); + ft_session_ptr->bRoamSynchInProgress = false; + if (mac_ctx->roam.pReassocResp) + qdf_mem_free(mac_ctx->roam.pReassocResp); + mac_ctx->roam.pReassocResp = NULL; + return QDF_STATUS_E_NOMEM; + } + qdf_mem_zero(roam_sync_ind_ptr->join_rsp, join_rsp_len); + + lim_log(mac_ctx, LOG1, FL("Session RicLength = %d"), + ft_session_ptr->RICDataLen); + if (ft_session_ptr->ricData != NULL) { + roam_sync_ind_ptr->join_rsp->parsedRicRspLen = + ft_session_ptr->RICDataLen; + qdf_mem_copy(roam_sync_ind_ptr->join_rsp->frames, + ft_session_ptr->ricData, + roam_sync_ind_ptr->join_rsp->parsedRicRspLen); + qdf_mem_free(ft_session_ptr->ricData); + ft_session_ptr->ricData = NULL; + ft_session_ptr->RICDataLen = 0; + } roam_sync_ind_ptr->join_rsp->vht_channel_width = ft_session_ptr->ch_width; roam_sync_ind_ptr->join_rsp->staId = curr_sta_ds->staIndex; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 1a732e3ee09d..4e921b45b316 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -18723,6 +18723,7 @@ void csr_roam_synch_callback(tpAniSirGlobal mac_ctx, struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BROADCAST_INITIALIZER; tpAddBssParams add_bss_params; QDF_STATUS status = QDF_STATUS_SUCCESS; + uint16_t len; #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH tSirSmeHTProfile *src_profile = NULL; tCsrRoamHTProfile *dst_profile = NULL; @@ -18883,6 +18884,19 @@ void csr_roam_synch_callback(tpAniSirGlobal mac_ctx, FL("LFR3:Clear Connected info")); csr_roam_free_connected_info(mac_ctx, &session->connectedInfo); + len = roam_synch_data->join_rsp->parsedRicRspLen; + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + FL("LFR3: RIC length - %d"), len); + if (len) { + session->connectedInfo.pbFrames = + qdf_mem_malloc(len); + if (session->connectedInfo.pbFrames != NULL) { + qdf_mem_copy(session->connectedInfo.pbFrames, + roam_synch_data->join_rsp->frames, len); + session->connectedInfo.nRICRspLength = + roam_synch_data->join_rsp->parsedRicRspLen; + } + } conn_profile->vht_channel_width = roam_synch_data->join_rsp->vht_channel_width; add_bss_params = (tpAddBssParams)roam_synch_data->add_bss_params; diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c index 4667d82ef3ab..e285f5394a84 100644 --- a/core/sme/src/csr/csr_neighbor_roam.c +++ b/core/sme/src/csr/csr_neighbor_roam.c @@ -1397,8 +1397,8 @@ static void csr_neighbor_roam_info_ctx_init( ngbr_roam_info->is11rAssoc = true; } else ngbr_roam_info->is11rAssoc = false; - NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("11rAssoc is = %d"), - ngbr_roam_info->is11rAssoc); + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_HIGH, + FL("11rAssoc is = %d"), ngbr_roam_info->is11rAssoc); #ifdef FEATURE_WLAN_ESE /* Based on the auth scheme tell if we are 11r */ @@ -1408,9 +1408,9 @@ static void csr_neighbor_roam_info_ctx_init( ngbr_roam_info->isESEAssoc = true; } else ngbr_roam_info->isESEAssoc = false; - NEIGHBOR_ROAM_DEBUG(pMac, LOG2, - FL("isESEAssoc is = %d ft = %d"), - ngbr_roam_info->isESEAssoc, init_ft_flag); + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_HIGH, + FL("isESEAssoc is = %d ft = %d"), + ngbr_roam_info->isESEAssoc, init_ft_flag); #endif /* If "Legacy Fast Roaming" is enabled */ if (csr_roam_is_fast_roam_enabled(pMac, session_id)) diff --git a/core/sme/src/qos/sme_qos.c b/core/sme/src/qos/sme_qos.c index 1aaf22a735b5..641943e38f76 100644 --- a/core/sme/src/qos/sme_qos.c +++ b/core/sme/src/qos/sme_qos.c @@ -4632,7 +4632,12 @@ QDF_STATUS sme_qos_process_reassoc_success_ev(tpAniSirGlobal mac_ctx, if (csr_roam_session && csr_roam_session->connectedInfo.nRICRspLength) { status = sme_qos_process_ft_reassoc_rsp_ev( - mac_ctx, sessionid, event_info); + mac_ctx, sessionid, + event_info); + } else { + QDF_TRACE(QDF_MODULE_ID_SME, + QDF_TRACE_LEVEL_ERROR, FL( + "session or RIC data is not present")); } } #ifdef FEATURE_WLAN_ESE diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 73f6e6fc4884..f47b43e9325d 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -2078,15 +2078,12 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, goto cleanup_label; } bss_desc_ptr = qdf_mem_malloc(sizeof(tSirBssDescription) + ie_len); - roam_synch_ind_ptr->join_rsp = qdf_mem_malloc(sizeof(tSirSmeJoinRsp)); - if ((NULL == roam_synch_ind_ptr->join_rsp) || (NULL == bss_desc_ptr)) { + if (NULL == bss_desc_ptr) { WMA_LOGE("LFR3: mem alloc failed!"); QDF_ASSERT(bss_desc_ptr != NULL); - QDF_ASSERT(roam_synch_ind_ptr->join_rsp != NULL); status = -ENOMEM; goto cleanup_label; } - qdf_mem_zero(roam_synch_ind_ptr->join_rsp, sizeof(tSirSmeJoinRsp)); qdf_mem_zero(bss_desc_ptr, sizeof(tSirBssDescription) + ie_len); wma->pe_roam_synch_cb((tpAniSirGlobal)wma->mac_context, roam_synch_ind_ptr, bss_desc_ptr); -- cgit v1.2.3 From 0e116c6d33f03e3ed147ad8dd527b6eedbd9be18 Mon Sep 17 00:00:00 2001 From: Amar Singhal Date: Thu, 21 Apr 2016 16:52:30 -0700 Subject: qcacld-3.0: Add new country XA Add new user country XA to regulatory tables. This is an 'engineered' country for Japan that has channels 5150-5230 marked as passive. Change-Id: I6c582bc0635ecae2c37b98d761f72f222c408d2f CRS-Fixed: 1007217 --- core/cds/inc/cds_regdomain.h | 1 + core/cds/src/cds_regdomain.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/cds/inc/cds_regdomain.h b/core/cds/inc/cds_regdomain.h index 447eec39821a..9fc4d744d63d 100644 --- a/core/cds/inc/cds_regdomain.h +++ b/core/cds/inc/cds_regdomain.h @@ -290,6 +290,7 @@ enum country_code { CTRY_JAPAN49 = 4049, CTRY_JAPAN55 = 4055, CTRY_JAPAN56 = 4056, + CTRY_XA = 4100, }; enum reg_domain { diff --git a/core/cds/src/cds_regdomain.c b/core/cds/src/cds_regdomain.c index 11e62813ec28..5fffb2d6de2d 100644 --- a/core/cds/src/cds_regdomain.c +++ b/core/cds/src/cds_regdomain.c @@ -379,7 +379,8 @@ static const struct country_code_to_reg_dmn g_all_countries[] = { {CTRY_WALLIS_AND_FUTUNA, ETSI1_WORLD, "WF" "WALLIS"}, {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN"}, {CTRY_ZIMBABWE, ETSI1_WORLD, "ZW", "ZIMBABWE"}, - {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN"} + {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN"}, + {CTRY_XA, MKK5_MKKA2, "XA", "JAPAN PASSIVE"} }; static const struct reg_dmn g_reg_dmns[] = { -- cgit v1.2.3 From 9632da55bbae250a92888f588198dd70dad0abdf Mon Sep 17 00:00:00 2001 From: Amar Singhal Date: Thu, 28 Apr 2016 12:13:23 -0700 Subject: qcacld-3.0: Correct comparison for 5G channel width Correct comparison for 5G and 2G channel width. Currently the maximum channel width test in cds_set_5g_channel_pararms() or cds_set_2g_channel_params is incorrect. Set input channel width to 80p80 if input width is more than equal to maximum channel width. Change-Id: I5a418c15474b355ea3c62c2de45052908f28113c CRs-Fixed: 1009720 --- core/cds/src/cds_reg_service.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/cds/src/cds_reg_service.c b/core/cds/src/cds_reg_service.c index cd0ed13839c2..dcdc20031e6c 100644 --- a/core/cds/src/cds_reg_service.c +++ b/core/cds/src/cds_reg_service.c @@ -450,7 +450,7 @@ static void cds_set_5g_channel_params(uint16_t oper_ch, enum channel_state chan_state2 = CHANNEL_STATE_ENABLE; const struct bonded_chan *bonded_chan_ptr; - if (CH_WIDTH_MAX >= ch_params->ch_width) + if (CH_WIDTH_MAX <= ch_params->ch_width) ch_params->ch_width = CH_WIDTH_80P80MHZ; while (ch_params->ch_width != CH_WIDTH_INVALID) { @@ -506,8 +506,8 @@ static void cds_set_2g_channel_params(uint16_t oper_ch, { enum channel_state chan_state = CHANNEL_STATE_ENABLE; - if (CH_WIDTH_MAX >= ch_params->ch_width) - ch_params->ch_width = CH_WIDTH_80P80MHZ; + if (CH_WIDTH_MAX <= ch_params->ch_width) + ch_params->ch_width = CH_WIDTH_40MHZ; while (ch_params->ch_width != CH_WIDTH_INVALID) { chan_state = cds_get_2g_bonded_channel_state(oper_ch, -- cgit v1.2.3 From 2476ef58f4d4bf2d6859f3d6033a2bcf62f46c92 Mon Sep 17 00:00:00 2001 From: Arun Khandavalli Date: Tue, 26 Apr 2016 20:19:43 +0530 Subject: qcacld-3.0: Add support for BPF data offload qcacld-2.0 to qcacld-3.0 propagation Currently wlan firmware has multiple different packet filters, offload features such as Magic Pattern filter, MCBC filter, RA filter and Bitmap pattern filter. Firmware has to maintain different filter settings and different source code to compare the filters. BPF data offload is common architecture for packet filter offload. Implement BPF data offload in driver. Change-Id: I63a5f7222de74cbb80d656f20f42d1b8453dce26 CRs-Fixed: 960473 --- core/hdd/inc/wlan_hdd_cfg.h | 1 + core/hdd/inc/wlan_hdd_main.h | 16 ++ core/hdd/src/wlan_hdd_cfg80211.c | 366 +++++++++++++++++++++++++++++++++++++- core/hdd/src/wlan_hdd_cfg80211.h | 38 ++++ core/hdd/src/wlan_hdd_main.c | 8 + core/mac/inc/sir_api.h | 36 ++++ core/mac/src/include/sir_params.h | 3 + core/sme/inc/sme_api.h | 8 + core/sme/inc/sme_internal.h | 2 + core/sme/src/common/sme_api.c | 127 ++++++++++++- core/wma/inc/wma.h | 7 + core/wma/inc/wma_tgt_cfg.h | 1 + core/wma/inc/wma_types.h | 3 + core/wma/src/wma_features.c | 169 ++++++++++++++++++ core/wma/src/wma_main.c | 11 ++ 15 files changed, 794 insertions(+), 2 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index fd581b48f628..39f0f2d014bd 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -3605,6 +3605,7 @@ struct hdd_config { bool ignore_peer_ht_opmode; uint32_t roam_dense_min_aps; bool enable_fatal_event; + bool bpf_enabled; }; #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var)) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 31cb452da246..be49ab0c6d7f 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -150,6 +150,8 @@ #define WLAN_WAIT_TIME_ANTENNA_MODE_REQ 3000 #define WLAN_WAIT_TIME_SET_DUAL_MAC_CFG 1500 +#define WLAN_WAIT_TIME_BPF 1000 + #define MAX_NUMBER_OF_ADAPTERS 4 #define MAX_CFG_STRING_LEN 255 @@ -315,6 +317,7 @@ extern spinlock_t hdd_context_lock; #define LINK_CONTEXT_MAGIC 0x4C494E4B /* LINKSPEED */ #define LINK_STATUS_MAGIC 0x4C4B5354 /* LINKSTATUS(LNST) */ #define TEMP_CONTEXT_MAGIC 0x74656d70 /* TEMP (temperature) */ +#define BPF_CONTEXT_MAGIC 0x4575354 /* BPF */ /* MAX OS Q block time value in msec * Prevent from permanent stall, resume OS Q if timer expired */ @@ -1132,6 +1135,18 @@ struct hdd_offloaded_packets_ctx { }; #endif +/** + * struct hdd_bpf_context - hdd Context for bpf + * @magic: magic number + * @completion: Completion variable for BPF Get Capability + * @capability_response: capabilities response received from fw + */ +struct hdd_bpf_context { + unsigned int magic; + struct completion completion; + struct sir_bpf_get_offload capability_response; +}; + /** Adapter structure definition */ struct hdd_context_s { @@ -1373,6 +1388,7 @@ struct hdd_context_s { struct completion set_antenna_mode_cmpl; /* Current number of TX X RX chains being used */ enum antenna_mode current_antenna_mode; + bool bpf_enabled; }; /*--------------------------------------------------------------------------- diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index cc8427103cba..4019b623ad87 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -585,7 +585,7 @@ static struct ieee80211_iface_combination }; static struct cfg80211_ops wlan_hdd_cfg80211_ops; - +struct hdd_bpf_context bpf_context; #ifdef WLAN_NL80211_TESTMODE enum wlan_hdd_tm_attr { @@ -4914,7 +4914,363 @@ static int wlan_hdd_cfg80211_txpower_scale_decr_db(struct wiphy *wiphy, return ret; } +/* + * define short names for the global vendor params + * used by __wlan_hdd_cfg80211_bpf_offload() + */ +#define BPF_INVALID \ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_INVALID +#define BPF_SET_RESET \ + QCA_WLAN_VENDOR_ATTR_SET_RESET_PACKET_FILTER +#define BPF_VERSION \ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION +#define BPF_FILTER_ID \ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID +#define BPF_PACKET_SIZE \ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE +#define BPF_CURRENT_OFFSET \ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET +#define BPF_PROGRAM \ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM +#define BPF_MAX \ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX + +static const struct nla_policy +wlan_hdd_bpf_offload_policy[BPF_MAX + 1] = { + [BPF_SET_RESET] = {.type = NLA_U32}, + [BPF_VERSION] = {.type = NLA_U32}, + [BPF_FILTER_ID] = {.type = NLA_U32}, + [BPF_PACKET_SIZE] = {.type = NLA_U32}, + [BPF_CURRENT_OFFSET] = {.type = NLA_U32}, + [BPF_PROGRAM] = {.type = NLA_U8}, +}; + +/** + * hdd_get_bpf_offload_cb() - Callback function to BPF Offload + * @hdd_context: hdd_context + * @bpf_get_offload: struct for get offload + * + * This function receives the response/data from the lower layer and + * checks to see if the thread is still waiting then post the results to + * upper layer, if the request has timed out then ignore. + * + * Return: None + */ +void hdd_get_bpf_offload_cb(void *hdd_context, + struct sir_bpf_get_offload *data) +{ + hdd_context_t *hdd_ctx = hdd_context; + struct hdd_bpf_context *context; + + ENTER(); + + if (wlan_hdd_validate_context(hdd_ctx) || !data) { + hddLog(LOGE, FL("HDD context is invalid or data(%p) is null"), + data); + return; + } + + spin_lock(&hdd_context_lock); + + context = &bpf_context; + /* The caller presumably timed out so there is nothing we can do */ + if (context->magic != BPF_CONTEXT_MAGIC) { + spin_unlock(&hdd_context_lock); + return; + } + + /* context is valid so caller is still waiting */ + /* paranoia: invalidate the magic */ + context->magic = 0; + + context->capability_response = *data; + complete(&context->completion); + + spin_unlock(&hdd_context_lock); + + return; +} + +/** + * hdd_post_get_bpf_capabilities_rsp() - Callback function to BPF Offload + * @hdd_context: hdd_context + * @bpf_get_offload: struct for get offload + * + * Return: 0 on success, error number otherwise. + */ +static int hdd_post_get_bpf_capabilities_rsp(hdd_context_t *hdd_ctx, + struct sir_bpf_get_offload *bpf_get_offload) +{ + struct sk_buff *skb; + uint32_t nl_buf_len; + + ENTER(); + + nl_buf_len = NLMSG_HDRLEN; + nl_buf_len += + (sizeof(bpf_get_offload->max_bytes_for_bpf_inst) + NLA_HDRLEN) + + (sizeof(bpf_get_offload->bpf_version) + NLA_HDRLEN); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); + if (!skb) { + hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed")); + return -ENOMEM; + } + + hddLog(LOG1, "BPF Version: %u BPF max bytes: %u", + bpf_get_offload->bpf_version, + bpf_get_offload->max_bytes_for_bpf_inst); + + if (nla_put_u32(skb, BPF_PACKET_SIZE, + bpf_get_offload->max_bytes_for_bpf_inst) || + nla_put_u32(skb, BPF_VERSION, bpf_get_offload->bpf_version)) { + hddLog(LOGE, FL("nla put failure")); + goto nla_put_failure; + } + + cfg80211_vendor_cmd_reply(skb); + EXIT(); + return 0; + +nla_put_failure: + kfree_skb(skb); + return -EINVAL; +} + +/** + * hdd_get_bpf_offload - Get BPF offload Capabilities + * @hdd_ctx: Hdd context + * + * Return: 0 on success, errno on failure + */ +static int hdd_get_bpf_offload(hdd_context_t *hdd_ctx) +{ + unsigned long rc; + struct hdd_bpf_context *context; + QDF_STATUS status; + int ret; + + ENTER(); + + spin_lock(&hdd_context_lock); + context = &bpf_context; + context->magic = BPF_CONTEXT_MAGIC; + INIT_COMPLETION(context->completion); + spin_unlock(&hdd_context_lock); + + status = sme_get_bpf_offload_capabilities(hdd_ctx->hHal); + if (!QDF_IS_STATUS_SUCCESS(status)) { + hddLog(LOGE, FL("Unable to retrieve BPF caps")); + return -EINVAL; + } + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout(&context->completion, + msecs_to_jiffies(WLAN_WAIT_TIME_BPF)); + if (!rc) { + hddLog(LOGE, FL("Target response timed out")); + spin_lock(&hdd_context_lock); + context->magic = 0; + spin_unlock(&hdd_context_lock); + + return -ETIMEDOUT; + } + ret = hdd_post_get_bpf_capabilities_rsp(hdd_ctx, + &bpf_context.capability_response); + if (ret) + hddLog(LOGE, FL("Failed to post get bpf capabilities")); + + EXIT(); + return ret; +} + +/** + * hdd_set_reset_bpf_offload - Post set/reset bpf to SME + * @hdd_ctx: Hdd context + * @tb: Length of @data + * @session_id: Session identifier + * + * Return: 0 on success; errno on failure + */ +static int hdd_set_reset_bpf_offload(hdd_context_t *hdd_ctx, + struct nlattr **tb, + uint8_t session_id) +{ + struct sir_bpf_set_offload *bpf_set_offload; + QDF_STATUS status; + int prog_len; + + ENTER(); + + bpf_set_offload = qdf_mem_malloc(sizeof(*bpf_set_offload)); + if (bpf_set_offload == NULL) { + hddLog(LOGE, FL("qdf_mem_malloc failed for bpf_set_offload")); + return -ENOMEM; + } + qdf_mem_zero(bpf_set_offload, sizeof(*bpf_set_offload)); + + /* Parse and fetch bpf packet size */ + if (!tb[BPF_PACKET_SIZE]) { + hddLog(LOGE, FL("attr bpf packet size failed")); + goto fail; + } + bpf_set_offload->total_length = nla_get_u32(tb[BPF_PACKET_SIZE]); + + if (!bpf_set_offload->total_length) { + hddLog(LOG1, FL("BPF reset packet filter received")); + goto post_sme; + } + /* Parse and fetch bpf program */ + if (!tb[BPF_PROGRAM]) { + hddLog(LOGE, FL("attr bpf program failed")); + goto fail; + } + + prog_len = nla_len(tb[BPF_PROGRAM]); + bpf_set_offload->program = qdf_mem_malloc(sizeof(uint8_t) * prog_len); + bpf_set_offload->current_length = prog_len; + nla_memcpy(bpf_set_offload->program, tb[BPF_PROGRAM], prog_len); + bpf_set_offload->session_id = session_id; + + /* Parse and fetch filter Id */ + if (!tb[BPF_FILTER_ID]) { + hddLog(LOGE, FL("attr filter id failed")); + goto fail; + } + bpf_set_offload->filter_id = nla_get_u32(tb[BPF_FILTER_ID]); + + /* Parse and fetch current offset */ + if (!tb[BPF_CURRENT_OFFSET]) { + hddLog(LOGE, FL("attr current offset failed")); + goto fail; + } + bpf_set_offload->current_offset = nla_get_u32(tb[BPF_CURRENT_OFFSET]); + +post_sme: + hddLog(LOG1, FL("Posting BPF SET/RESET to SME, session_id: %d Bpf Version: %d filter ID: %d total_length: %d current_length: %d current offset: %d"), + bpf_set_offload->session_id, + bpf_set_offload->version, + bpf_set_offload->filter_id, + bpf_set_offload->total_length, + bpf_set_offload->current_length, + bpf_set_offload->current_offset); + + status = sme_set_bpf_instructions(hdd_ctx->hHal, bpf_set_offload); + if (!QDF_IS_STATUS_SUCCESS(status)) { + hddLog(LOGE, + FL("sme_set_bpf_instructions failed(err=%d)"), status); + goto fail; + } + EXIT(); + if (bpf_set_offload->current_length) + qdf_mem_free(bpf_set_offload->program); + qdf_mem_free(bpf_set_offload); + return 0; + +fail: + if (bpf_set_offload->current_length) + qdf_mem_free(bpf_set_offload->program); + qdf_mem_free(bpf_set_offload); + return -EINVAL; +} + +/** + * wlan_hdd_cfg80211_bpf_offload() - Set/Reset to BPF Offload + * @wiphy: wiphy structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of @data + * + * Return: 0 on success; errno on failure + */ +static int +__wlan_hdd_cfg80211_bpf_offload(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct nlattr *tb[BPF_MAX + 1]; + int ret_val, packet_filter_subcmd; + + ENTER(); + + ret_val = wlan_hdd_validate_context(hdd_ctx); + if (ret_val) + return ret_val; + + if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + hddLog(LOGE, FL("Command not allowed in FTM mode")); + return -EINVAL; + } + + if (!hdd_ctx->bpf_enabled) { + hddLog(LOGE, FL("BPF offload is not supported by firmware")); + return -ENOTSUPP; + } + + if (nla_parse(tb, BPF_MAX, data, data_len, + wlan_hdd_bpf_offload_policy)) { + hddLog(LOGE, FL("Invalid ATTR")); + return -EINVAL; + } + + if (!tb[BPF_SET_RESET]) { + hddLog(LOGE, FL("attr bpf set reset failed")); + return -EINVAL; + } + + packet_filter_subcmd = nla_get_u32(tb[BPF_SET_RESET]); + + if (packet_filter_subcmd == QCA_WLAN_GET_PACKET_FILTER) + return hdd_get_bpf_offload(hdd_ctx); + else + return hdd_set_reset_bpf_offload(hdd_ctx, tb, + pAdapter->sessionId); +} + +/** + * wlan_hdd_cfg80211_bpf_offload() - SSR Wrapper to BPF Offload + * @wiphy: wiphy structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of @data + * + * Return: 0 on success; errno on failure + */ + +static int wlan_hdd_cfg80211_bpf_offload(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret; + + cds_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_bpf_offload(wiphy, wdev, data, data_len); + cds_ssr_unprotect(__func__); + + return ret; +} + +/** + * hdd_init_bpf_completion() - Initialize the completion event for bpf + * + * Return: None + */ +void hdd_init_bpf_completion(void) +{ + init_completion(&bpf_context.completion); +} + +#undef BPF_INVALID +#undef BPF_SET_RESET +#undef BPF_VERSION +#undef BPF_ID +#undef BPF_PACKET_SIZE +#undef BPF_CURRENT_OFFSET +#undef BPF_PROGRAM +#undef BPF_MAX const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { { .info.vendor_id = QCA_NL80211_VENDOR_ID, @@ -5369,6 +5725,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { WIPHY_VENDOR_CMD_NEED_RUNNING, .doit = wlan_hdd_cfg80211_txpower_scale_decr_db }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_bpf_offload + }, }; /** diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index 9ba52bb31790..1a185b0e30fd 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -344,6 +344,7 @@ enum qca_nl80211_vendor_subcmds { QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS = 79, QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI = 80, + QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER = 83, /* OCB commands */ QCA_NL80211_VENDOR_SUBCMD_OCB_SET_CONFIG = 92, QCA_NL80211_VENDOR_SUBCMD_OCB_SET_UTC_TIME = 93, @@ -2138,6 +2139,40 @@ enum qca_wlan_vendor_attr_rssi_monitoring { QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_AFTER_LAST - 1, }; +/** + * enum set_reset_packet_filter - set packet filter control commands + * @QCA_WLAN_SET_PACKET_FILTER: Set Packet Filter + * @QCA_WLAN_GET_PACKET_FILTER: Get Packet filter + */ +enum set_reset_packet_filter { + QCA_WLAN_SET_PACKET_FILTER = 1, + QCA_WLAN_GET_PACKET_FILTER = 2, +}; + +/** + * enum qca_wlan_vendor_attr_packet_filter - BPF control commands + * @QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_INVALID: Invalid + * @QCA_WLAN_VENDOR_ATTR_SET_RESET_PACKET_FILTER: Filter ID + * @QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION: Filter Version + * @QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE: Total Length + * @QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET: Current offset + * @QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM: length of BPF instructions + */ +enum qca_wlan_vendor_attr_packet_filter { + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_SET_RESET_PACKET_FILTER, + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION, + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID, + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE, + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET, + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX = + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_AFTER_LAST - 1, +}; + /** * enum qca_vendor_attr_get_preferred_freq_list - get preferred channel list * @QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_INVALID: invalid value @@ -2435,4 +2470,7 @@ int wlan_hdd_disable_dfs_chan_scan(hdd_context_t *hdd_ctx, int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand); + +void hdd_get_bpf_offload_cb(void *hdd_context, struct sir_bpf_get_offload *); +void hdd_init_bpf_completion(void); #endif diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index e750b1a46e82..c616f48260de 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -1337,6 +1337,7 @@ void hdd_update_tgt_cfg(void *context, void *param) hdd_info("Init current antenna mode: %d", hdd_ctx->current_antenna_mode); + hdd_ctx->bpf_enabled = cfg->bpf_enabled; } /** @@ -5413,6 +5414,8 @@ static int hdd_context_init(hdd_context_t *hdd_ctx) init_completion(&hdd_ctx->mc_sus_event_var); init_completion(&hdd_ctx->ready_to_suspend); + hdd_init_bpf_completion(); + qdf_spinlock_create(&hdd_ctx->connection_status_lock); qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock); @@ -6168,6 +6171,11 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) sme_set_rssi_threshold_breached_cb(hdd_ctx->hHal, hdd_rssi_threshold_breached); + status = sme_bpf_offload_register_callback(hdd_ctx->hHal, + hdd_get_bpf_offload_cb); + if (QDF_IS_STATUS_SUCCESS(status)) + hdd_err("set bpf offload callback failed"); + hdd_cfg80211_link_layer_stats_init(hdd_ctx); wlan_hdd_tsf_init(hdd_ctx); wlan_hdd_send_all_scan_intf_info(hdd_ctx); diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index af34c8ef786e..0f6854fa15d6 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -5713,4 +5713,40 @@ struct obss_scanparam { uint16_t obss_activity_threshold; }; +/** + * struct sir_bpf_set_offload - set bpf filter instructions + * @session_id: session identifier + * @version: host bpf version + * @filter_id: Filter ID for BPF filter + * @total_length: The total length of the full instruction + * total_length equal to 0 means reset + * @current_offset: current offset, 0 means start a new setting + * @current_length: Length of current @program + * @program: BPF instructions + */ +struct sir_bpf_set_offload { + uint8_t session_id; + uint32_t version; + uint32_t filter_id; + uint32_t total_length; + uint32_t current_offset; + uint32_t current_length; + uint8_t *program; +}; + +/** + * struct sir_bpf_offload_capabilities - get bpf Capabilities + * @bpf_version: fw's implement version + * @max_bpf_filters: max filters that fw supports + * @max_bytes_for_bpf_inst: the max bytes that can be used as bpf instructions + * @remaining_bytes_for_bpf_inst: remaining bytes for bpf instructions + * + */ +struct sir_bpf_get_offload { + uint32_t bpf_version; + uint32_t max_bpf_filters; + uint32_t max_bytes_for_bpf_inst; + uint32_t remaining_bytes_for_bpf_inst; +}; + #endif /* __SIR_API_H */ diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index af4faed28d75..9959dda2df43 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -604,6 +604,9 @@ typedef struct sSirMbMsgP2p { #define SIR_HAL_ADD_BCN_FILTER_CMDID (SIR_HAL_ITC_MSG_TYPES_BEGIN + 339) #define SIR_HAL_REMOVE_BCN_FILTER_CMDID (SIR_HAL_ITC_MSG_TYPES_BEGIN + 340) +#define SIR_HAL_BPF_GET_CAPABILITIES_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 341) +#define SIR_HAL_BPF_SET_INSTRUCTIONS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 342) + #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) /* CFG message types */ diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 0906720997c2..64ef4362a757 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1117,4 +1117,12 @@ bool sme_is_sta_smps_allowed(tHalHandle hHal, uint8_t session_id); QDF_STATUS sme_add_beacon_filter(tHalHandle hal, uint32_t session_id, uint32_t *ie_map); QDF_STATUS sme_remove_beacon_filter(tHalHandle hal, uint32_t session_id); +QDF_STATUS sme_bpf_offload_register_callback(tHalHandle hal, + void (*pbpf_get_offload_cb)(void *, + struct sir_bpf_get_offload *)); + +QDF_STATUS sme_get_bpf_offload_capabilities(tHalHandle hal); +QDF_STATUS sme_set_bpf_instructions(tHalHandle hal, + struct sir_bpf_set_offload *); + #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index 674e8b597846..6414ae8a243e 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -234,6 +234,8 @@ typedef struct tagSmeStruct { ocb_callback dcc_stats_event_callback; sme_set_thermal_level_callback set_thermal_level_cb; void *saved_scan_cmd; + void (*pbpf_get_offload_cb)(void *context, + struct sir_bpf_get_offload *); } tSmeStruct, *tpSmeStruct; #endif /* #if !defined( __SMEINTERNAL_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index c691401bebee..120f306b8dc7 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -14445,7 +14445,7 @@ QDF_STATUS sme_wifi_start_logger(tHalHandle hal, status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); if (!QDF_IS_STATUS_SUCCESS(status)) { sms_log(mac, LOGE, - FL("vos_mq_post_message failed!(err=%d)"), + FL("cds_mq_post_message failed!(err=%d)"), status); qdf_mem_free(req_msg); status = QDF_STATUS_E_FAILURE; @@ -15629,3 +15629,128 @@ QDF_STATUS sme_remove_beacon_filter(tHalHandle hal, uint32_t session_id) } return qdf_status; } + + +/** + * sme_get_bpf_offload_capabilities() - Get length for BPF offload + * @hal: Global HAL handle + * This function constructs the cds message and fill in message type, + * post the same to WDA. + * Return: QDF_STATUS enumeration + */ +QDF_STATUS sme_get_bpf_offload_capabilities(tHalHandle hal) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + cds_msg_t cds_msg; + + sms_log(mac_ctx, LOG1, FL("enter")); + + status = sme_acquire_global_lock(&mac_ctx->sme); + if (QDF_STATUS_SUCCESS == status) { + /* Serialize the req through MC thread */ + cds_msg.bodyptr = NULL; + cds_msg.type = WDA_BPF_GET_CAPABILITIES_REQ; + status = cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_msg); + if (!QDF_IS_STATUS_SUCCESS(status)) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Post bpf get offload msg fail")); + status = QDF_STATUS_E_FAILURE; + } + sme_release_global_lock(&mac_ctx->sme); + } else { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("sme_acquire_global_lock error")); + } + sms_log(mac_ctx, LOG1, FL("exit")); + return status; +} + + +/** + * sme_set_bpf_instructions() - Set BPF bpf filter instructions. + * @hal: HAL handle + * @bpf_set_offload: struct to set bpf filter instructions. + * + * Return: QDF_STATUS enumeration. + */ +QDF_STATUS sme_set_bpf_instructions(tHalHandle hal, + struct sir_bpf_set_offload *req) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + cds_msg_t cds_msg; + struct sir_bpf_set_offload *set_offload; + + set_offload = qdf_mem_malloc(sizeof(*set_offload)); + + if (NULL == set_offload) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Failed to alloc set_offload")); + return QDF_STATUS_E_NOMEM; + } + + set_offload->session_id = req->session_id; + set_offload->filter_id = req->filter_id; + set_offload->current_offset = req->current_offset; + set_offload->total_length = req->total_length; + if (set_offload->total_length) { + set_offload->current_length = req->current_length; + set_offload->program = qdf_mem_malloc(sizeof(uint8_t) * + req->current_length); + qdf_mem_copy(set_offload->program, req->program, + set_offload->current_length); + } + status = sme_acquire_global_lock(&mac_ctx->sme); + if (QDF_STATUS_SUCCESS == status) { + /* Serialize the req through MC thread */ + cds_msg.bodyptr = set_offload; + cds_msg.type = WDA_BPF_SET_INSTRUCTIONS_REQ; + status = cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_msg); + + if (!QDF_IS_STATUS_SUCCESS(status)) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Post BPF set offload msg fail")); + status = QDF_STATUS_E_FAILURE; + if (set_offload->total_length) + qdf_mem_free(set_offload->program); + qdf_mem_free(set_offload); + } + sme_release_global_lock(&mac_ctx->sme); + } else { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("sme_acquire_global_lock failed")); + if (set_offload->total_length) + qdf_mem_free(set_offload->program); + qdf_mem_free(set_offload); + } + return status; +} + +/** + * sme_bpf_offload_register_callback() - Register get bpf offload callbacK + * + * @hal - MAC global handle + * @callback_routine - callback routine from HDD + * + * This API is invoked by HDD to register its callback in SME + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_bpf_offload_register_callback(tHalHandle hal, + void (*pbpf_get_offload_cb)(void *context, + struct sir_bpf_get_offload *)) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + mac->sme.pbpf_get_offload_cb = pbpf_get_offload_cb; + sme_release_global_lock(&mac->sme); + } else { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("sme_acquire_global_lock failed")); + } + return status; +} diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index a7959ae1335b..3f1ac3b5fac4 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -2048,5 +2048,12 @@ QDF_STATUS wma_ht40_stop_obss_scan(tp_wma_handle wma_handle, int32_t vdev_id); QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma, struct obss_ht40_scanind *req); + +int wma_get_bpf_caps_event_handler(void *handle, + u_int8_t *cmd_param_info, + u_int32_t len); +QDF_STATUS wma_get_bpf_capabilities(tp_wma_handle wma); +QDF_STATUS wma_set_bpf_instructions(tp_wma_handle wma, + struct sir_bpf_set_offload *bpf_set_offload); #endif struct wma_ini_config *wma_get_ini_handle(tp_wma_handle wma_handle); diff --git a/core/wma/inc/wma_tgt_cfg.h b/core/wma/inc/wma_tgt_cfg.h index 94c5b05fca14..e6a8c86a9f80 100644 --- a/core/wma/inc/wma_tgt_cfg.h +++ b/core/wma/inc/wma_tgt_cfg.h @@ -165,5 +165,6 @@ struct wma_tgt_cfg { bool egap_support; #endif uint32_t fine_time_measurement_cap; + bool bpf_enabled; }; #endif /* WMA_TGT_CFG_H */ diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index 791f0f88910b..252d271220f0 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -468,6 +468,9 @@ #define WMA_ADD_BCN_FILTER_CMDID SIR_HAL_ADD_BCN_FILTER_CMDID #define WMA_REMOVE_BCN_FILTER_CMDID SIR_HAL_REMOVE_BCN_FILTER_CMDID +#define WDA_BPF_GET_CAPABILITIES_REQ SIR_HAL_BPF_GET_CAPABILITIES_REQ +#define WDA_BPF_SET_INSTRUCTIONS_REQ SIR_HAL_BPF_SET_INSTRUCTIONS_REQ + /* Bit 6 will be used to control BD rate for Management frames */ #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index b8727ca1d3e7..00c2df030d6f 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -6904,3 +6904,172 @@ QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma, return ret; } +/** + * wma_get_bpf_caps_event_handler() - Event handler for get bpf capability + * @handle: WMA global handle + * @cmd_param_info: command event data + * @len: Length of @cmd_param_info + * + * Return: 0 on Success or Errno on failure + */ +int wma_get_bpf_caps_event_handler(void *handle, + u_int8_t *cmd_param_info, + u_int32_t len) +{ + WMI_BPF_CAPABILIY_INFO_EVENTID_param_tlvs *param_buf; + wmi_bpf_capability_info_evt_fixed_param *event; + struct sir_bpf_get_offload *bpf_get_offload; + tpAniSirGlobal pmac = (tpAniSirGlobal)cds_get_context( + QDF_MODULE_ID_PE); + + if (!pmac) { + WMA_LOGE("%s: Invalid pmac", __func__); + return -EINVAL; + } + if (!pmac->sme.pbpf_get_offload_cb) { + WMA_LOGE("%s: Callback not registered", __func__); + return -EINVAL; + } + + param_buf = (WMI_BPF_CAPABILIY_INFO_EVENTID_param_tlvs *)cmd_param_info; + event = param_buf->fixed_param; + bpf_get_offload = qdf_mem_malloc(sizeof(*bpf_get_offload)); + + if (!bpf_get_offload) { + WMA_LOGP("%s: Memory allocation failed.", __func__); + return -ENOMEM; + } + + bpf_get_offload->bpf_version = event->bpf_version; + bpf_get_offload->max_bpf_filters = event->max_bpf_filters; + bpf_get_offload->max_bytes_for_bpf_inst = + event->max_bytes_for_bpf_inst; + WMA_LOGD("%s: BPF capabilities version: %d max bpf filter size: %d", + __func__, bpf_get_offload->bpf_version, + bpf_get_offload->max_bytes_for_bpf_inst); + + WMA_LOGD("%s: sending bpf capabilities event to hdd", __func__); + pmac->sme.pbpf_get_offload_cb(pmac->hHdd, bpf_get_offload); + qdf_mem_free(bpf_get_offload); + return 0; +} + +/** + * wma_get_bpf_capabilities - Send get bpf capability to firmware + * @wma_handle: wma handle + * + * Return: QDF_STATUS enumeration. + */ +QDF_STATUS wma_get_bpf_capabilities(tp_wma_handle wma) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + wmi_bpf_get_capability_cmd_fixed_param *cmd; + wmi_buf_t wmi_buf; + uint32_t len; + u_int8_t *buf_ptr; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE(FL("WMA is closed, can not issue get BPF capab")); + return QDF_STATUS_E_INVAL; + } + + if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_BPF_OFFLOAD)) { + WMA_LOGE(FL("BPF cababilities feature bit not enabled")); + return QDF_STATUS_E_FAILURE; + } + + len = sizeof(*cmd); + wmi_buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return QDF_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + cmd = (wmi_bpf_get_capability_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_bpf_get_capability_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_bpf_get_capability_cmd_fixed_param)); + + if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len, + WMI_BPF_GET_CAPABILITY_CMDID)) { + WMA_LOGE(FL("Failed to send BPF capability command")); + wmi_buf_free(wmi_buf); + return QDF_STATUS_E_FAILURE; + } + return status; +} + +/** + * wma_set_bpf_instructions - Set bpf instructions to firmware + * @wma: wma handle + * @bpf_set_offload: Bpf offload information to set to firmware + * + * Return: QDF_STATUS enumeration + */ +QDF_STATUS wma_set_bpf_instructions(tp_wma_handle wma, + struct sir_bpf_set_offload *bpf_set_offload) +{ + wmi_bpf_set_vdev_instructions_cmd_fixed_param *cmd; + wmi_buf_t wmi_buf; + uint32_t len = 0, len_aligned = 0; + u_int8_t *buf_ptr; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue set BPF capability", + __func__); + return QDF_STATUS_E_INVAL; + } + + if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_BPF_OFFLOAD)) { + WMA_LOGE(FL("BPF offload feature Disabled")); + return QDF_STATUS_E_NOSUPPORT; + } + + if (bpf_set_offload->total_length) { + len_aligned = roundup(bpf_set_offload->current_length, + sizeof(A_UINT32)); + len = len_aligned + WMI_TLV_HDR_SIZE; + } + + len += sizeof(*cmd); + wmi_buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return QDF_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + cmd = (wmi_bpf_set_vdev_instructions_cmd_fixed_param *) buf_ptr; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_bpf_set_vdev_instructions_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_bpf_set_vdev_instructions_cmd_fixed_param)); + cmd->vdev_id = bpf_set_offload->session_id; + cmd->filter_id = bpf_set_offload->filter_id; + cmd->total_length = bpf_set_offload->total_length; + cmd->current_offset = bpf_set_offload->current_offset; + cmd->current_length = bpf_set_offload->current_length; + + if (bpf_set_offload->total_length) { + buf_ptr += + sizeof(wmi_bpf_set_vdev_instructions_cmd_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, len_aligned); + buf_ptr += WMI_TLV_HDR_SIZE; + qdf_mem_copy(buf_ptr, bpf_set_offload->program, + bpf_set_offload->current_length); + qdf_mem_free(bpf_set_offload->program); + } + + if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len, + WMI_BPF_SET_VDEV_INSTRUCTIONS_CMDID)) { + WMA_LOGE(FL("Failed to send config bpf instructions command")); + wmi_buf_free(wmi_buf); + return QDF_STATUS_E_FAILURE; + } + return QDF_STATUS_SUCCESS; +} diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 89889ddca52e..4db22b02b596 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -2063,6 +2063,10 @@ QDF_STATUS wma_open(void *cds_context, WMI_PEER_DELETE_RESP_EVENTID, wma_peer_delete_handler, WMA_RX_SERIALIZER_CTX); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_BPF_CAPABILIY_INFO_EVENTID, + wma_get_bpf_caps_event_handler, + WMA_RX_SERIALIZER_CTX); return QDF_STATUS_SUCCESS; err_dbglog_init: @@ -5315,6 +5319,13 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg) wma_remove_beacon_filter(wma_handle, msg->bodyptr); qdf_mem_free(msg->bodyptr); break; + case WDA_BPF_GET_CAPABILITIES_REQ: + wma_get_bpf_capabilities(wma_handle); + break; + case WDA_BPF_SET_INSTRUCTIONS_REQ: + wma_set_bpf_instructions(wma_handle, msg->bodyptr); + qdf_mem_free(msg->bodyptr); + break; default: WMA_LOGD("unknow msg type %x", msg->type); -- cgit v1.2.3 From 59f861d11d0daf043e33b23f2e3a050453ca6cb0 Mon Sep 17 00:00:00 2001 From: Manjunathappa Prakash Date: Thu, 21 Apr 2016 10:33:31 -0700 Subject: qcacld-3.0: Add monitor mode support Add monitor mode support. Configure target to deliver 802.11 packets in raw mode. Below is the procedure to start the monitor mode. insmod /system/lib/modules/wlan.ko con_mode=4 ifconfig wlan0 up "iwpriv wlan0 setMonChan 36 2" or "iw dev mon0 set channel 36 HT40+" tcpdump -i wlan0 -w In this mode concurrency is not supported and module doesnot support Tx. Change-Id: I211ece0a66e2d43bc111e523714942e1557e36f4 CRs-Fixed: 963060 --- core/hdd/inc/wlan_hdd_main.h | 16 ++++ core/hdd/inc/wlan_hdd_tx_rx.h | 4 +- core/hdd/src/wlan_hdd_cfg.c | 63 +++++++++++++++ core/hdd/src/wlan_hdd_cfg80211.c | 165 ++++++++++++++++++++++++++++++++++----- core/hdd/src/wlan_hdd_main.c | 100 +++++++++++++++++++++++- core/hdd/src/wlan_hdd_tx_rx.c | 121 ++++++++++++++++++++++++++++ core/hdd/src/wlan_hdd_wext.c | 55 +++++++++++++ core/mac/inc/sir_api.h | 13 +++ core/mac/inc/wni_api.h | 1 + core/sme/inc/sme_api.h | 1 + core/sme/src/common/sme_api.c | 24 +++++- 11 files changed, 538 insertions(+), 25 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index be49ab0c6d7f..0262528886b8 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -631,6 +631,20 @@ typedef struct hdd_cfg80211_state_s { eP2PActionFrameState actionFrmState; } hdd_cfg80211_state_t; +/** + * struct hdd_mon_set_ch_info - Holds monitor mode channel switch params + * @channel: Channel number. + * @cb_mode: Channel bonding + * @channel_width: Channel width 0/1/2 for 20/40/80MHz respectively. + * @phy_mode: PHY mode + */ +struct hdd_mon_set_ch_info { + uint8_t channel; + uint8_t cb_mode; + uint32_t channel_width; + eCsrPhyMode phy_mode; +}; + struct hdd_station_ctx { /** Handle to the Wireless Extension State */ hdd_wext_state_t WextState; @@ -665,6 +679,8 @@ struct hdd_station_ctx { int staDebugState; uint8_t broadcast_ibss_staid; + + struct hdd_mon_set_ch_info ch_info; }; #define BSS_STOP 0 diff --git a/core/hdd/inc/wlan_hdd_tx_rx.h b/core/hdd/inc/wlan_hdd_tx_rx.h index df570cd83e48..526d8d098536 100644 --- a/core/hdd/inc/wlan_hdd_tx_rx.h +++ b/core/hdd/inc/wlan_hdd_tx_rx.h @@ -128,11 +128,9 @@ static inline void wlan_hdd_log_eapol(struct sk_buff *skb, } #endif /* FEATURE_WLAN_DIAG_SUPPORT */ - const char *hdd_reason_type_to_string(enum netif_reason_type reason); const char *hdd_action_type_to_string(enum netif_action_type action); void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter, enum netif_action_type action, enum netif_reason_type reason); - - +int hdd_set_mon_rx_cb(struct net_device *dev); #endif /* end #if !defined(WLAN_HDD_TX_RX_H) */ diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 23513f5677c5..6cf3949a18dc 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -44,6 +44,7 @@ #include #include #include +#include static void cb_notify_set_roam_prefer5_g_hz(hdd_context_t *pHddCtx, unsigned long notifyId) @@ -5474,6 +5475,66 @@ config_exit: return qdf_status; } +/** + * hdd_disable_runtime_pm() - Override to disable runtime_pm. + * @cfg_ini: Handle to struct hdd_config + * + * Return: None + */ +#ifdef FEATURE_RUNTIME_PM +static void hdd_disable_runtime_pm(struct hdd_config *cfg_ini) +{ + cfg_ini->runtime_pm = 0; +} +#else +static void hdd_disable_runtime_pm(struct hdd_config *cfg_ini) +{ +} +#endif + +/** + * hdd_disable_auto_shutdown() - Override to disable auto_shutdown. + * @cfg_ini: Handle to struct hdd_config + * + * Return: None + */ +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN +static void hdd_disable_auto_shutdown(struct hdd_config *cfg_ini) +{ + cfg_ini->WlanAutoShutdown = 0; +} +#else +static void hdd_disable_auto_shutdown(struct hdd_config *cfg_ini) +{ +} +#endif + +/** + * hdd_override_all_ps() - overrides to disables all the powersave features. + * @hdd_ctx: Pointer to HDD context. + * Overrides below powersave ini configurations. + * gEnableImps=0 + * gEnableBmps=0 + * gRuntimePM=0 + * gWlanAutoShutdown = 0 + * gEnableSuspend=0 + * gEnablePowerSaveOffload=0 + * gEnableWoW=0 + * + * Return: None + */ +static void hdd_override_all_ps(hdd_context_t *hdd_ctx) +{ + struct hdd_config *cfg_ini = hdd_ctx->config; + + cfg_ini->fIsImpsEnabled = 0; + cfg_ini->is_ps_enabled = 0; + hdd_disable_runtime_pm(cfg_ini); + hdd_disable_auto_shutdown(cfg_ini); + cfg_ini->enablePowersaveOffload = 0; + cfg_ini->wowEnable = 0; +} + /** * hdd_parse_config_ini() - parse the ini configuration file * @pHddCtx: the pointer to hdd context @@ -5577,6 +5638,8 @@ QDF_STATUS hdd_parse_config_ini(hdd_context_t *pHddCtx) hdd_napi_event(NAPI_EVT_INI_FILE, (void *)pHddCtx->config->napi_enable); #endif /* FEATURE_NAPI */ + if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) + hdd_override_all_ps(pHddCtx); config_exit: release_firmware(fw); diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 4019b623ad87..104aa9396064 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -505,6 +505,24 @@ wlan_hdd_p2p_p2p_iface_limit[] = { }, }; +static const struct ieee80211_iface_limit + wlan_hdd_mon_iface_limit[] = { + { + .max = 3, /* Monitor interface */ + .types = BIT(NL80211_IFTYPE_MONITOR), + }, +}; + +static struct ieee80211_iface_combination + wlan_hdd_mon_iface[] = { + { + .limits = wlan_hdd_mon_iface_limit, + .max_interfaces = 3, + .num_different_channels = 2, + .n_limits = ARRAY_SIZE(wlan_hdd_mon_iface_limit), + }, +}; + static struct ieee80211_iface_combination wlan_hdd_iface_combination[] = { /* STA */ @@ -5908,26 +5926,35 @@ int wlan_hdd_cfg80211_init(struct device *dev, wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS; - /* Supports STATION & AD-HOC modes right now */ - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) - | BIT(NL80211_IFTYPE_ADHOC) - | BIT(NL80211_IFTYPE_P2P_CLIENT) - | BIT(NL80211_IFTYPE_P2P_GO) - | BIT(NL80211_IFTYPE_AP); - - if (pCfg->advertiseConcurrentOperation) { - if (pCfg->enableMCC) { - int i; - for (i = 0; i < ARRAY_SIZE(wlan_hdd_iface_combination); - i++) { - if (!pCfg->allowMCCGODiffBI) - wlan_hdd_iface_combination[i]. - beacon_int_infra_match = true; + if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE) { + /* Supports STATION & AD-HOC modes right now */ + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) + | BIT(NL80211_IFTYPE_ADHOC) + | BIT(NL80211_IFTYPE_P2P_CLIENT) + | BIT(NL80211_IFTYPE_P2P_GO) + | BIT(NL80211_IFTYPE_AP); + + if (pCfg->advertiseConcurrentOperation) { + if (pCfg->enableMCC) { + int i; + + for (i = 0; + i < ARRAY_SIZE(wlan_hdd_iface_combination); + i++) { + if (!pCfg->allowMCCGODiffBI) + wlan_hdd_iface_combination[i]. + beacon_int_infra_match = true; + } } + wiphy->n_iface_combinations = + ARRAY_SIZE(wlan_hdd_iface_combination); + wiphy->iface_combinations = wlan_hdd_iface_combination; } + } else { + wiphy->interface_modes = BIT(NL80211_IFTYPE_MONITOR); wiphy->n_iface_combinations = - ARRAY_SIZE(wlan_hdd_iface_combination); - wiphy->iface_combinations = wlan_hdd_iface_combination; + ARRAY_SIZE(wlan_hdd_mon_iface); + wiphy->iface_combinations = wlan_hdd_mon_iface; } /* Before registering we need to update the ht capabilitied based @@ -8242,6 +8269,10 @@ void hdd_select_cbmode(hdd_adapter_t *pAdapter, uint8_t operationChannel) uint8_t iniDot11Mode = (WLAN_HDD_GET_CTX(pAdapter))->config->dot11Mode; eHddDot11Mode hddDot11Mode = iniDot11Mode; struct ch_params_s ch_params; + hdd_station_ctx_t *station_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + uint32_t cb_mode; + struct hdd_mon_set_ch_info *ch_info = &station_ctx->ch_info; + ch_params.ch_width = (WLAN_HDD_GET_CTX(pAdapter))->config->vhtChannelWidth; @@ -8264,10 +8295,20 @@ void hdd_select_cbmode(hdd_adapter_t *pAdapter, uint8_t operationChannel) break; } /* This call decides required channel bonding mode */ - sme_set_ch_params((WLAN_HDD_GET_CTX(pAdapter)->hHal), + cb_mode = sme_set_ch_params((WLAN_HDD_GET_CTX(pAdapter)->hHal), hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode), operationChannel, 0, &ch_params); + + if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) { + ch_info->channel_width = ch_params.ch_width; + ch_info->phy_mode = hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode); + ch_info->channel = operationChannel; + ch_info->cb_mode = cb_mode; + hdd_info("ch_info width %d, phymode %d channel %d", + ch_info->channel_width, ch_info->phy_mode, + ch_info->channel); + } } /** @@ -11841,6 +11882,93 @@ enum cds_con_mode wlan_hdd_convert_nl_iftype_to_hdd_type( return mode; } +/** + * wlan_hdd_cfg80211_set_mon_ch() - Set monitor mode capture channel + * @wiphy: Handle to struct wiphy to get handle to module context. + * @chandef: Contains information about the capture channel to be set. + * + * This interface is called if and only if monitor mode interface alone is + * active. + * + * Return: 0 success or error code on failure. + */ +static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef) +{ + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + hdd_adapter_t *adapter; + hdd_station_ctx_t *sta_ctx; + struct hdd_mon_set_ch_info *ch_info; + QDF_STATUS status; + tHalHandle hal_hdl; + struct qdf_mac_addr bssid; + tCsrRoamProfile roam_profile; + struct ch_params_s ch_params; + int ret; + uint16_t chan_num = cds_freq_to_chan(chandef->chan->center_freq); + + ENTER(); + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret) + return ret; + + hal_hdl = hdd_ctx->hHal; + + adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); + if (!adapter) + return -EIO; + + hdd_info("%s: set monitor mode Channel %d and freq %d", + adapter->dev->name, chan_num, chandef->chan->center_freq); + + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + ch_info = &sta_ctx->ch_info; + hdd_select_cbmode(adapter, chan_num); + roam_profile.ChannelInfo.ChannelList = &ch_info->channel; + roam_profile.ChannelInfo.numOfChannels = 1; + roam_profile.phyMode = ch_info->phy_mode; + roam_profile.ch_params.ch_width = chandef->width; + + qdf_mem_copy(bssid.bytes, adapter->macAddressCurrent.bytes, + QDF_MAC_ADDR_SIZE); + + ch_params.ch_width = chandef->width; + sme_set_ch_params(hal_hdl, ch_info->phy_mode, chan_num, 0, + &ch_params); + status = sme_roam_channel_change_req(hal_hdl, bssid, &ch_params, + &roam_profile); + if (status) { + hdd_err("Status: %d Failed to set sme_RoamChannel for monitor mode", + status); + ret = qdf_status_to_os_return(status); + return ret; + } + EXIT(); + return 0; +} + +/** + * wlan_hdd_cfg80211_set_mon_ch() - Set monitor mode capture channel + * @wiphy: Handle to struct wiphy to get handle to module context. + * @chandef: Contains information about the capture channel to be set. + * + * This interface is called if and only if monitor mode interface alone is + * active. + * + * Return: 0 success or error code on failure. + */ +static int wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef) +{ + int ret; + + cds_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_mon_ch(wiphy, chandef); + cds_ssr_unprotect(__func__); + return ret; +} + /** * struct cfg80211_ops - cfg80211_ops * @@ -11956,4 +12084,5 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops = { #ifdef CHANNEL_SWITCH_SUPPORTED .channel_switch = wlan_hdd_cfg80211_channel_switch, #endif + .set_monitor_channel = wlan_hdd_cfg80211_set_mon_ch, }; diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index c616f48260de..cf03f2014d06 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -1435,6 +1435,42 @@ bool hdd_is_valid_mac_address(const uint8_t *pMacAddr) return xdigit == 12 && (separator == 5 || separator == 0); } +/** + * __hdd__mon_open() - HDD Open function + * @dev: Pointer to net_device structure + * + * This is called in response to ifconfig up + * + * Return: 0 for success; non-zero for failure + */ +static int __hdd_mon_open(struct net_device *dev) +{ + int ret; + + ENTER_DEV(dev); + ret = hdd_set_mon_rx_cb(dev); + return ret; +} + +/** + * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR + * @dev: Pointer to net_device structure + * + * This is called in response to ifconfig up + * + * Return: 0 for success; non-zero for failure + */ +int hdd_mon_open(struct net_device *dev) +{ + int ret; + + cds_ssr_protect(__func__); + ret = __hdd_mon_open(dev); + cds_ssr_unprotect(__func__); + + return ret; +} + /** * __hdd_open() - HDD Open function * @dev: Pointer to net_device structure @@ -1892,9 +1928,44 @@ static struct net_device_ops wlan_drv_ops = { #endif }; +/* Monitor mode net_device_ops, doesnot Tx and most of operations. */ +static struct net_device_ops wlan_mon_drv_ops = { + .ndo_open = hdd_mon_open, + .ndo_stop = hdd_stop, + .ndo_get_stats = hdd_get_stats, +}; + +/** + * hdd_set_station_ops() - update net_device ops for monitor mode + * @pWlanDev: Handle to struct net_device to be updated. + * Return: None + */ void hdd_set_station_ops(struct net_device *pWlanDev) { - pWlanDev->netdev_ops = &wlan_drv_ops; + if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) + pWlanDev->netdev_ops = &wlan_mon_drv_ops; + else + pWlanDev->netdev_ops = &wlan_drv_ops; +} + +/** + * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device. + * @dev: Handle to struct net_device to be updated. + * + * Return: None + */ +static void hdd_mon_mode_ether_setup(struct net_device *dev) +{ + dev->header_ops = NULL; + dev->type = ARPHRD_IEEE80211_RADIOTAP; + dev->hard_header_len = ETH_HLEN; + dev->mtu = ETH_DATA_LEN; + dev->addr_len = ETH_ALEN; + dev->tx_queue_len = 1000; /* Ethernet wants good queues */ + dev->flags = IFF_BROADCAST|IFF_MULTICAST; + dev->priv_flags |= IFF_TX_SKB_SHARING; + + memset(dev->broadcast, 0xFF, ETH_ALEN); } /** @@ -1922,7 +1993,9 @@ static hdd_adapter_t *hdd_alloc_station_adapter(hdd_context_t *hdd_ctx, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS) name_assign_type, #endif - ether_setup, NUM_TX_QUEUES); + (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() ? + hdd_mon_mode_ether_setup : ether_setup), + NUM_TX_QUEUES); if (pWlanDev != NULL) { @@ -2434,6 +2507,7 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type, case QDF_P2P_CLIENT_MODE: case QDF_P2P_DEVICE_MODE: case QDF_OCB_MODE: + case QDF_MONITOR_MODE: { adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr, name_assign_type, @@ -2450,6 +2524,8 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type, adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT; else if (QDF_P2P_DEVICE_MODE == session_type) adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE; + else if (QDF_MONITOR_MODE == session_type) + adapter->wdev.iftype = NL80211_IFTYPE_MONITOR; else adapter->wdev.iftype = NL80211_IFTYPE_STATION; @@ -5635,6 +5711,21 @@ static inline int hdd_open_p2p_interface(struct hdd_context_t *hdd_ctx, } #endif +/** + * hdd_open_monitor_interface() - Open monitor mode interface + * @hdd_ctx: HDD context + * @rtnl_held: True if RTNL lock is held + * + * Return: Primary adapter on success and PTR_ERR on failure + */ +static hdd_adapter_t *hdd_open_monitor_interface(hdd_context_t *hdd_ctx, + bool rtnl_held) +{ + return hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d", + wlan_hdd_get_intf_addr(hdd_ctx), + NET_NAME_UNKNOWN, rtnl_held); +} + /** * hdd_open_interfaces - Open all required interfaces * hdd_ctx: HDD context @@ -6059,7 +6150,10 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) rtnl_held = hdd_hold_rtnl_lock(); - adapter = hdd_open_interfaces(hdd_ctx, rtnl_held); + if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) + adapter = hdd_open_monitor_interface(hdd_ctx, rtnl_held); + else + adapter = hdd_open_interfaces(hdd_ctx, rtnl_held); if (IS_ERR(adapter)) { ret = PTR_ERR(adapter); diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index 60d3162afaed..2e390476d5ef 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -55,6 +55,7 @@ #include "wlan_hdd_lro.h" #include "cdp_txrx_peer_ops.h" +#include "ol_txrx.h" #ifdef FEATURE_WLAN_DIAG_SUPPORT #define HDD_EAPOL_ETHER_TYPE (0x888E) @@ -669,6 +670,84 @@ QDF_STATUS hdd_deinit_tx_rx(hdd_adapter_t *pAdapter) return status; } +/** + * hdd_mon_rx_packet_cbk() - Receive callback registered with OL layer. + * @context: [in] pointer to qdf context + * @rxBuf: [in] pointer to rx qdf_nbuf + * + * TL will call this to notify the HDD when one or more packets were + * received for a registered STA. + * + * Return: QDF_STATUS_E_FAILURE if any errors encountered, QDF_STATUS_SUCCESS + * otherwise + */ +static QDF_STATUS hdd_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf) +{ + hdd_adapter_t *adapter; + int rxstat; + struct sk_buff *skb; + struct sk_buff *skb_next; + unsigned int cpu_index; + + /* Sanity check on inputs */ + if ((NULL == context) || (NULL == rxbuf)) { + QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR, + "%s: Null params being passed", __func__); + return QDF_STATUS_E_FAILURE; + } + + adapter = (hdd_adapter_t *)context; + if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) { + QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR, + "invalid adapter %p", adapter); + return QDF_STATUS_E_FAILURE; + } + + cpu_index = wlan_hdd_get_cpu(); + + /* walk the chain until all are processed */ + skb = (struct sk_buff *) rxbuf; + while (NULL != skb) { + skb_next = skb->next; + skb->dev = adapter->dev; + + ++adapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index]; + ++adapter->stats.rx_packets; + adapter->stats.rx_bytes += skb->len; + + /* Remove SKB from internal tracking table before submitting + * it to stack + */ + qdf_net_buf_debug_release_skb(skb); + + /* + * If this is not a last packet on the chain + * Just put packet into backlog queue, not scheduling RX sirq + */ + if (skb->next) { + rxstat = netif_rx(skb); + } else { + /* + * This is the last packet on the chain + * Scheduling rx sirq + */ + rxstat = netif_rx_ni(skb); + } + + if (NET_RX_SUCCESS == rxstat) + ++adapter-> + hdd_stats.hddTxRxStats.rxDelivered[cpu_index]; + else + ++adapter->hdd_stats.hddTxRxStats.rxRefused[cpu_index]; + + skb = skb_next; + } + + adapter->dev->last_rx = jiffies; + + return QDF_STATUS_SUCCESS; +} + /** * hdd_rx_packet_cbk() - Receive packet handler * @context: pointer to HDD context @@ -1108,3 +1187,45 @@ void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter, return; } +/** + * hdd_set_mon_rx_cb() - Set Monitor mode Rx callback + * @dev: Pointer to net_device structure + * + * Return: 0 for success; non-zero for failure + */ +int hdd_set_mon_rx_cb(struct net_device *dev) +{ + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + int ret; + QDF_STATUS qdf_status; + struct ol_txrx_desc_type sta_desc = {0}; + struct ol_txrx_ops txrx_ops; + + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) + return ret; + + qdf_mem_zero(&txrx_ops, sizeof(txrx_ops)); + txrx_ops.rx.rx = hdd_mon_rx_packet_cbk; + ol_txrx_vdev_register( + ol_txrx_get_vdev_from_vdev_id(adapter->sessionId), + adapter, &txrx_ops); + /* peer is created wma_vdev_attach->wma_create_peer */ + qdf_status = ol_txrx_register_peer(&sta_desc); + if (QDF_STATUS_SUCCESS != qdf_status) { + hdd_err("WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]", + qdf_status, qdf_status); + goto exit; + } + + qdf_status = sme_create_mon_session(hdd_ctx->hHal, + adapter->macAddressCurrent.bytes); + if (QDF_STATUS_SUCCESS != qdf_status) { + hdd_err("sme_create_mon_session() failed to register. Status= %d [0x%08X]", + qdf_status, qdf_status); + } +exit: + ret = qdf_status_to_os_return(qdf_status); + return ret; +} diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index e741530bce03..28a9522582cc 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -367,6 +367,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { #define WE_SET_DUAL_MAC_SCAN_CONFIG 21 #define WE_SET_DUAL_MAC_FW_MODE_CONFIG 22 +#define WE_SET_MON_MODE_CHAN 23 #ifdef FEATURE_WLAN_TDLS #undef MAX_VAR_ARGS @@ -9728,6 +9729,53 @@ static int iw_set_band_config(struct net_device *dev, return ret; } +/** + * wlan_hdd_set_mon_chan() - Set capture channel on the monitor mode interface. + * @adapter: Handle to adapter + * @chan: Monitor mode channel + * @bandwidth: Capture channel bandwidth + * + * Return: 0 on success else error code. + */ +static int wlan_hdd_set_mon_chan(hdd_adapter_t *adapter, uint32_t chan, + uint32_t bandwidth) +{ + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info; + QDF_STATUS status; + tHalHandle hal_hdl = hdd_ctx->hHal; + struct qdf_mac_addr bssid; + tCsrRoamProfile roam_profile; + struct ch_params_s ch_params; + + if (QDF_GLOBAL_MONITOR_MODE != hdd_get_conparam()) { + hdd_err("Not supported, device is not in monitor mode"); + return -EINVAL; + } + + hdd_info("Set monitor mode Channel %d", chan); + hdd_select_cbmode(adapter, chan); + roam_profile.ChannelInfo.ChannelList = &ch_info->channel; + roam_profile.ChannelInfo.numOfChannels = 1; + roam_profile.phyMode = ch_info->phy_mode; + roam_profile.ch_params.ch_width = bandwidth; + + qdf_mem_copy(bssid.bytes, adapter->macAddressCurrent.bytes, + QDF_MAC_ADDR_SIZE); + + ch_params.ch_width = bandwidth; + sme_set_ch_params(hal_hdl, ch_info->phy_mode, chan, 0, &ch_params); + status = sme_roam_channel_change_req(hal_hdl, bssid, &ch_params, + &roam_profile); + if (status) { + hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode", + status); + } + + return qdf_status_to_os_return(status); +} + static int __iw_set_two_ints_getnone(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -9793,6 +9841,9 @@ static int __iw_set_two_ints_getnone(struct net_device *dev, if (value[1] == DUMP_DP_TRACE) qdf_dp_trace_dump_all(value[2]); break; + case WE_SET_MON_MODE_CHAN: + ret = wlan_hdd_set_mon_chan(pAdapter, value[1], value[2]); + break; default: hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd); break; @@ -11014,6 +11065,10 @@ static const struct iw_priv_args we_private_args[] = { IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dump_dp_trace"} , + {WE_SET_MON_MODE_CHAN, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + 0, "setMonChan"} + , }; const struct iw_handler_def we_handler_def = { diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 0f6854fa15d6..0a58715270b2 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -494,6 +494,7 @@ typedef enum eSirBssType { eSIR_INFRA_AP_MODE, /* Added for softAP support */ eSIR_IBSS_MODE, eSIR_AUTO_MODE, + eSIR_MONITOR_MODE, eSIR_DONOT_USE_BSS_TYPE = SIR_MAX_ENUM_SIZE } tSirBssType; @@ -2429,6 +2430,18 @@ typedef struct sSirUpdateParams { uint8_t ssidHidden; /* Hide SSID */ } tSirUpdateParams, *tpSirUpdateParams; +/** + * struct sir_create_session - Used for creating session in monitor mode + * @type: SME host message type. + * @msg_len: Length of the message. + * @bss_id: bss_id for creating the session. + */ +struct sir_create_session { + uint16_t type; + uint16_t msg_len; + struct qdf_mac_addr bss_id; +}; + /* Beacon Interval */ typedef struct sSirChangeBIParams { uint16_t messageType; diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index 93aae032223e..e6dfb2dda66a 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -249,6 +249,7 @@ enum eWniMsgTypes { eWNI_SME_SET_ANTENNA_MODE_REQ, eWNI_SME_SET_ANTENNA_MODE_RESP, eWNI_SME_TSF_EVENT, + eWNI_SME_MON_INIT_SESSION, eWNI_SME_MSG_TYPES_END }; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 64ef4362a757..7b74226e7fde 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1125,4 +1125,5 @@ QDF_STATUS sme_get_bpf_offload_capabilities(tHalHandle hal); QDF_STATUS sme_set_bpf_instructions(tHalHandle hal, struct sir_bpf_set_offload *); +QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, uint8_t *bssid); #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 120f306b8dc7..03a9ee6bcad4 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -15630,7 +15630,6 @@ QDF_STATUS sme_remove_beacon_filter(tHalHandle hal, uint32_t session_id) return qdf_status; } - /** * sme_get_bpf_offload_capabilities() - Get length for BPF offload * @hal: Global HAL handle @@ -15754,3 +15753,26 @@ QDF_STATUS sme_bpf_offload_register_callback(tHalHandle hal, } return status; } + +/** + * sme_create_mon_session() - post message to create PE session for monitormode + * operation + * @hal_handle: Handle to the HAL + * @bssid: pointer to bssid + * + * Return: QDF_STATUS_SUCCESS on success, non-zero error code on failure. + */ +QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, tSirMacAddr bss_id) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct sir_create_session *msg; + + msg = qdf_mem_malloc(sizeof(*msg)); + if (NULL != msg) { + msg->type = eWNI_SME_MON_INIT_SESSION; + msg->msg_len = sizeof(*msg); + qdf_mem_copy(msg->bss_id.bytes, bss_id, QDF_MAC_ADDR_SIZE); + status = cds_send_mb_message_to_mac(msg); + } + return status; +} -- cgit v1.2.3 From 0e6e6b5a47c3e6cbd10ed600cda8ae904fc3d098 Mon Sep 17 00:00:00 2001 From: Manjunathappa Prakash Date: Thu, 21 Apr 2016 11:48:48 -0700 Subject: qcacld-3.0: Create PE session for monitor mode Handle monitor mode set capture channel, first set capture channel will start the monitor mode vdev along with setting the monitor mode channel. Subsequent set channel commands use the WMI_PDEV_SET_CHANNEL_CMDID to set the capture channel. Change-Id: Ibae71a4799e569bf1f1f4d39b23a7d2183fa40e5 CRs-Fixed: 963060 --- core/mac/src/pe/include/lim_api.h | 11 ++ core/mac/src/pe/lim/lim_api.c | 26 +++++ core/mac/src/pe/lim/lim_process_message_queue.c | 5 + core/mac/src/pe/lim/lim_session.c | 6 + core/wma/src/wma_dev_if.c | 15 ++- core/wma/src/wma_main.c | 3 + core/wma/src/wma_scan_roam.c | 140 ++++++++++++++++++++++-- target/inc/wlan_tgt_def_config.h | 2 + 8 files changed, 195 insertions(+), 13 deletions(-) diff --git a/core/mac/src/pe/include/lim_api.h b/core/mac/src/pe/include/lim_api.h index e66de6befda7..dabb6b4d76e5 100644 --- a/core/mac/src/pe/include/lim_api.h +++ b/core/mac/src/pe/include/lim_api.h @@ -172,6 +172,17 @@ static inline QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx, return QDF_STATUS_E_NOSUPPORT; } #endif + +/** + * lim_mon_init_session() - create PE session for monitor mode operation + * @mac_ptr: mac pointer + * @msg: Pointer to struct sir_create_session type. + * + * Return: NONE + */ +void lim_mon_init_session(tpAniSirGlobal mac_ptr, + struct sir_create_session *msg); + #define limGetQosMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limQosEnabled) #define limGetWmeMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWmeEnabled) #define limGetWsmMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWsmEnabled) diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index 31df90976b53..3c440df4627b 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -2169,3 +2169,29 @@ QDF_STATUS pe_release_global_lock(tAniSirLim *psPe) return status; } +/** + * lim_mon_init_session() - create PE session for monitor mode operation + * @mac_ptr: mac pointer + * @msg: Pointer to struct sir_create_session type. + * + * Return: NONE + */ +void lim_mon_init_session(tpAniSirGlobal mac_ptr, + struct sir_create_session *msg) +{ + tpPESession psession_entry; + uint8_t session_id; + + lim_print_mac_addr(mac_ptr, msg->bss_id.bytes, LOGE); + psession_entry = pe_create_session(mac_ptr, msg->bss_id.bytes, + &session_id, + mac_ptr->lim.maxStation, + eSIR_MONITOR_MODE); + if (psession_entry == NULL) { + QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, + ("Monitor mode: Session Can not be created")); + lim_print_mac_addr(mac_ptr, msg->bss_id.bytes, LOGE); + return; + } + psession_entry->vhtCapability = 1; +} diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index 499cee125e68..bebe8120dafc 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -1472,6 +1472,11 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) qdf_mem_free(msg->bodyptr); msg->bodyptr = NULL; break; + case eWNI_SME_MON_INIT_SESSION: + lim_mon_init_session(mac_ctx, msg->bodyptr); + qdf_mem_free(msg->bodyptr); + msg->bodyptr = NULL; + break; case SIR_HAL_P2P_NOA_START_IND: session_entry = &mac_ctx->lim.gpSession[0]; lim_log(mac_ctx, LOG1, "LIM received NOA start %x", msg->type); diff --git a/core/mac/src/pe/lim/lim_session.c b/core/mac/src/pe/lim/lim_session.c index 1aa2a6080bf3..8f1a8c139833 100644 --- a/core/mac/src/pe/lim/lim_session.c +++ b/core/mac/src/pe/lim/lim_session.c @@ -295,6 +295,8 @@ pe_create_session(tpAniSirGlobal pMac, uint8_t *bssid, uint8_t *sessionId, session_ptr->gLimNumOfCurrentSTAs = 0; /* Copy the BSSID to the session table */ sir_copy_mac_addr(session_ptr->bssId, bssid); + if (bssType == eSIR_MONITOR_MODE) + sir_copy_mac_addr(pMac->lim.gpSession[i].selfMacAddr, bssid); session_ptr->valid = true; /* Intialize the SME and MLM states to IDLE */ session_ptr->limMlmState = eLIM_MLM_IDLE_STATE; @@ -355,6 +357,10 @@ pe_create_session(tpAniSirGlobal pMac, uint8_t *bssid, uint8_t *sessionId, } if (eSIR_INFRASTRUCTURE_MODE == bssType) lim_ft_open(pMac, &pMac->lim.gpSession[i]); + + if (eSIR_MONITOR_MODE == bssType) + lim_ft_open(pMac, &pMac->lim.gpSession[i]); + if (eSIR_INFRA_AP_MODE == bssType) { session_ptr->old_protection_state = 0; session_ptr->mac_ctx = (void *)pMac; diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 6cc6a04bf1d3..c0ebf22a7339 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -54,6 +54,7 @@ #include "lim_session_utils.h" #include "cds_utils.h" +#include "cds_concurrency.h" #if !defined(REMOVE_PKT_LOG) #include "pktlog_ac.h" @@ -206,6 +207,8 @@ enum wlan_op_mode wma_get_txrx_vdev_type(uint32_t type) vdev_type = wlan_op_mode_ocb; break; case WMI_VDEV_TYPE_MONITOR: + vdev_type = wlan_op_mode_monitor; + break; default: WMA_LOGE("Invalid vdev type %u", type); vdev_type = wlan_op_mode_unknown; @@ -909,8 +912,11 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, } params->smpsMode = host_map_smps_mode(resp_event->smps_mode); params->status = resp_event->status; - if (resp_event->resp_type == WMI_VDEV_RESTART_RESP_EVENT && - (iface->type == WMI_VDEV_TYPE_STA)) { + if (((resp_event->resp_type == WMI_VDEV_RESTART_RESP_EVENT) && + (iface->type == WMI_VDEV_TYPE_STA)) || + ((resp_event->resp_type == WMI_VDEV_START_RESP_EVENT) && + (iface->type == WMI_VDEV_TYPE_MONITOR))) { + param.vdev_id = resp_event->vdev_id; param.assoc_id = iface->aid; status = wmi_unified_vdev_up_send(wma->wmi_handle, @@ -1574,7 +1580,8 @@ ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle, if (((self_sta_req->type == WMI_VDEV_TYPE_AP) && (self_sta_req->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE)) || - (self_sta_req->type == WMI_VDEV_TYPE_OCB)) { + (self_sta_req->type == WMI_VDEV_TYPE_OCB) || + (self_sta_req->type == WMI_VDEV_TYPE_MONITOR)) { WMA_LOGA("Creating self peer %pM, vdev_id %hu", self_sta_req->self_mac_addr, self_sta_req->session_id); status = wma_create_peer(wma_handle, txrx_pdev, @@ -1799,7 +1806,7 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma, */ params.is_dfs = req->is_dfs; params.is_restart = isRestart; - if (req->is_dfs) { + if ((QDF_GLOBAL_MONITOR_MODE != cds_get_conparam()) && req->is_dfs) { params.flag_dfs = WMI_CHAN_FLAG_DFS; temp_chan_info |= (1 << WMI_CHAN_FLAG_DFS); params.dis_hw_ack = true; diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 4db22b02b596..347c745c95d8 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -247,6 +247,9 @@ static void wma_set_default_tgt_config(tp_wma_handle wma_handle) tgt_cfg.rx_decap_mode = CFG_TGT_RX_DECAP_MODE_NWIFI; } #endif /* PERE_IP_HDR_ALIGNMENT_WAR */ + if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) + tgt_cfg.rx_decap_mode = CFG_TGT_RX_DECAP_MODE_RAW; + wma_handle->wlan_resource_config = tgt_cfg; } diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index f47b43e9325d..7c3112925777 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -57,6 +57,7 @@ #include "lim_session_utils.h" #include "cds_utils.h" +#include "cds_concurrency.h" #if !defined(REMOVE_PKT_LOG) #include "pktlog_ac.h" @@ -96,6 +97,8 @@ enum extscan_report_events_type { #define WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION (5 * 1000) /* in msec */ #endif +void ol_cfg_update_mon_chan(ol_txrx_pdev_handle pdev, int mon_ch, + int mon_ch_freq); /** * wma_set_p2p_scan_info() - set p2p scan info in wma handle * @wma_handle: wma handle @@ -2442,6 +2445,112 @@ void wma_process_roam_synch_complete(WMA_HANDLE handle, uint8_t vdev_id) } #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ +/** + * wma_switch_channel() - WMA api to switch channel dynamically + * @wma: Pointer of WMA context + * @req: Pointer vdev_start having channel switch info. + * + * Return: 0 for success, otherwise appropriate error code + */ +QDF_STATUS wma_switch_channel(tp_wma_handle wma, struct wma_vdev_start_req *req) +{ + + wmi_buf_t buf; + wmi_channel *cmd; + int32_t len, ret; + WLAN_PHY_MODE chanmode; + struct wma_txrx_node *intr = wma->interfaces; + tpAniSirGlobal pmac; + + pmac = cds_get_context(QDF_MODULE_ID_PE); + + if (pmac == NULL) { + WMA_LOGE("%s: vdev start failed as pmac is NULL", __func__); + return QDF_STATUS_E_FAILURE; + } + + len = sizeof(*cmd); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return QDF_STATUS_E_NOMEM; + } + cmd = (wmi_channel *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_channel, + WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); + + /* Fill channel info */ + cmd->mhz = cds_chan_to_freq(req->chan); + chanmode = wma_chan_to_mode(req->chan, req->chan_width, + req->vht_capable, req->dot11_mode); + + intr[req->vdev_id].chanmode = chanmode; /* save channel mode */ + intr[req->vdev_id].ht_capable = req->ht_capable; + intr[req->vdev_id].vht_capable = req->vht_capable; + intr[req->vdev_id].config.gtx_info.gtxRTMask[0] = + CFG_TGT_DEFAULT_GTX_HT_MASK; + intr[req->vdev_id].config.gtx_info.gtxRTMask[1] = + CFG_TGT_DEFAULT_GTX_VHT_MASK; + intr[req->vdev_id].config.gtx_info.gtxUsrcfg = + CFG_TGT_DEFAULT_GTX_USR_CFG; + intr[req->vdev_id].config.gtx_info.gtxPERThreshold = + CFG_TGT_DEFAULT_GTX_PER_THRESHOLD; + intr[req->vdev_id].config.gtx_info.gtxPERMargin = + CFG_TGT_DEFAULT_GTX_PER_MARGIN; + intr[req->vdev_id].config.gtx_info.gtxTPCstep = + CFG_TGT_DEFAULT_GTX_TPC_STEP; + intr[req->vdev_id].config.gtx_info.gtxTPCMin = + CFG_TGT_DEFAULT_GTX_TPC_MIN; + intr[req->vdev_id].config.gtx_info.gtxBWMask = + CFG_TGT_DEFAULT_GTX_BW_MASK; + intr[req->vdev_id].mhz = cmd->mhz; + + WMI_SET_CHANNEL_MODE(cmd, chanmode); + cmd->band_center_freq1 = cmd->mhz; + + if (chanmode == MODE_11AC_VHT80) + cmd->band_center_freq1 = + cds_chan_to_freq(req->ch_center_freq_seg0); + + if ((chanmode == MODE_11NA_HT40) || (chanmode == MODE_11NG_HT40) || + (chanmode == MODE_11AC_VHT40)) { + if (req->chan_width == CH_WIDTH_80MHZ) + cmd->band_center_freq1 += 10; + else + cmd->band_center_freq1 -= 10; + } + cmd->band_center_freq2 = 0; + + /* Set half or quarter rate WMI flags */ + if (req->is_half_rate) + WMI_SET_CHANNEL_FLAG(cmd, WMI_CHAN_FLAG_HALF_RATE); + else if (req->is_quarter_rate) + WMI_SET_CHANNEL_FLAG(cmd, WMI_CHAN_FLAG_QUARTER_RATE); + + /* Find out min, max and regulatory power levels */ + WMI_SET_CHANNEL_REG_POWER(cmd, req->max_txpow); + WMI_SET_CHANNEL_MAX_TX_POWER(cmd, req->max_txpow); + + + WMA_LOGE("%s: freq %d channel %d chanmode %d center_chan %d center_freq2 %d reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x", + __func__, cmd->mhz, req->chan, chanmode, + cmd->band_center_freq1, cmd->band_center_freq2, + cmd->reg_info_1, cmd->reg_info_2, req->max_txpow); + + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_PDEV_SET_CHANNEL_CMDID); + + if (ret < 0) { + WMA_LOGP("%s: Failed to send vdev start command", __func__); + qdf_nbuf_free(buf); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + /** * wma_set_channel() - set channel * @wma: wma handle @@ -2518,17 +2627,30 @@ void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params) (params->restart_on_chan_switch == true)) wma->interfaces[req.vdev_id].is_channel_switch = true; - status = wma_vdev_start(wma, &req, + if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() && + wma_is_vdev_up(vdev_id)) { + status = wma_switch_channel(wma, &req); + if (status != QDF_STATUS_SUCCESS) + WMA_LOGE("%s: wma_switch_channel failed %d\n", __func__, + status); + + ol_htt_mon_note_chan(pdev, req.chan); + } else { + status = wma_vdev_start(wma, &req, wma->interfaces[req.vdev_id].is_channel_switch); - if (status != QDF_STATUS_SUCCESS) { - wma_remove_vdev_req(wma, req.vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_START); - WMA_LOGP("%s: vdev start failed status = %d", __func__, status); - goto send_resp; - } + if (status != QDF_STATUS_SUCCESS) { + wma_remove_vdev_req(wma, req.vdev_id, + WMA_TARGET_REQ_TYPE_VDEV_START); + WMA_LOGP("%s: vdev start failed status = %d", __func__, status); + goto send_resp; + } - if (wma->interfaces[req.vdev_id].is_channel_switch) - wma->interfaces[req.vdev_id].is_channel_switch = false; + if (wma->interfaces[req.vdev_id].is_channel_switch) + wma->interfaces[req.vdev_id].is_channel_switch = false; + + if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) + ol_htt_mon_note_chan(pdev, req.chan); + } return; send_resp: WMA_LOGD("%s: channel %d ch_width %d txpower %d status %d", __func__, diff --git a/target/inc/wlan_tgt_def_config.h b/target/inc/wlan_tgt_def_config.h index 0a142008cde2..b1a2582fa19d 100644 --- a/target/inc/wlan_tgt_def_config.h +++ b/target/inc/wlan_tgt_def_config.h @@ -125,6 +125,8 @@ #define CFG_TGT_RX_DECAP_MODE (0x2) /* Decap to native Wifi header */ #define CFG_TGT_RX_DECAP_MODE_NWIFI (0x1) +/* Decap to raw mode header */ +#define CFG_TGT_RX_DECAP_MODE_RAW (0x0) /* maximum number of pending scan requests */ #define CFG_TGT_DEFAULT_SCAN_MAX_REQS 0x4 -- cgit v1.2.3 From b757372528a778ab6d857df23ad5131d94624eb2 Mon Sep 17 00:00:00 2001 From: Manjunathappa Prakash Date: Thu, 21 Apr 2016 11:24:07 -0700 Subject: qcacld-3.0: Add HTT datapath changes to handle monitor mode Make special handling for monitor mode operation. Take care to handle amsdu packets in which case firmware marks the last_frag in msdu_info field. These MSDUs of AMSDU are stiched using frags_list of skb and handed over to network stack. Also take care to extract and update the radiotap header to head of the packet. Change-Id: I4ed9696175e63884b5db682a2a4c4df504a7fb20 CRs-Fixed: 963060 --- core/cds/src/cds_api.c | 3 + core/cds/src/cds_concurrency.c | 2 + core/dp/htt/htt_h2t.c | 13 ++ core/dp/htt/htt_internal.h | 1 + core/dp/htt/htt_rx.c | 478 ++++++++++++++++++++++++++++++++++++++++- core/dp/htt/htt_types.h | 11 + core/dp/htt/rx_desc.h | 10 + core/dp/ol/inc/ol_htt_api.h | 3 + core/dp/txrx/ol_rx.c | 17 +- core/dp/txrx/ol_txrx.c | 9 + core/dp/txrx/ol_txrx_types.h | 1 + core/wma/src/wma_scan_roam.c | 3 +- 12 files changed, 546 insertions(+), 5 deletions(-) diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 12e17cfda911..590179bb590f 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -1588,6 +1588,9 @@ QDF_STATUS cds_get_vdev_types(enum tQDF_ADAPTER_MODE mode, uint32_t *type, case QDF_IBSS_MODE: *type = WMI_VDEV_TYPE_IBSS; break; + case QDF_MONITOR_MODE: + *type = WMI_VDEV_TYPE_MONITOR; + break; default: QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, "Invalid device mode %d", mode); diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index 9d41c9fd5c76..b55ccce7cae3 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -3394,6 +3394,7 @@ void cds_set_concurrency_mode(enum tQDF_ADAPTER_MODE mode) case QDF_P2P_GO_MODE: case QDF_SAP_MODE: case QDF_IBSS_MODE: + case QDF_MONITOR_MODE: hdd_ctx->concurrency_mode |= (1 << mode); hdd_ctx->no_of_open_sessions[mode]++; break; @@ -3428,6 +3429,7 @@ void cds_clear_concurrency_mode(enum tQDF_ADAPTER_MODE mode) case QDF_P2P_CLIENT_MODE: case QDF_P2P_GO_MODE: case QDF_SAP_MODE: + case QDF_MONITOR_MODE: hdd_ctx->no_of_open_sessions[mode]--; if (!(hdd_ctx->no_of_open_sessions[mode])) hdd_ctx->concurrency_mode &= (~(1 << mode)); diff --git a/core/dp/htt/htt_h2t.c b/core/dp/htt/htt_h2t.c index 9662eb4d6980..c7aeb9f70006 100644 --- a/core/dp/htt/htt_h2t.c +++ b/core/dp/htt/htt_h2t.c @@ -51,6 +51,7 @@ #include #include +#include #define HTT_MSG_BUF_SIZE(msg_bytes) \ ((msg_bytes) + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING) @@ -356,6 +357,18 @@ A_STATUS htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev) enable_ppdu_start = 0; enable_ppdu_end = 0; #endif + if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) { + enable_ctrl_data = 1; + enable_mgmt_data = 1; + enable_null_data = 1; + enable_phy_data = 1; + enable_hdr = 1; + enable_ppdu_start = 1; + enable_ppdu_end = 1; + /* Disable ASPM for monitor mode */ + qdf_print("Monitor mode is enabled\n"); + } + HTT_RX_RING_CFG_ENABLED_802_11_HDR_SET(*msg_word, enable_hdr); HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_SET(*msg_word, 1); HTT_RX_RING_CFG_ENABLED_PPDU_START_SET(*msg_word, enable_ppdu_start); diff --git a/core/dp/htt/htt_internal.h b/core/dp/htt/htt_internal.h index 7d3ffbddafcb..271e77eec211 100644 --- a/core/dp/htt/htt_internal.h +++ b/core/dp/htt/htt_internal.h @@ -331,6 +331,7 @@ static inline void htt_print_rx_desc(struct htt_host_rx_desc_base *rx_desc) * rounded up to a cache line size. */ #define HTT_RX_BUF_SIZE 1920 +#define MAX_RX_PAYLOAD_SZ (HTT_RX_BUF_SIZE - RX_STD_DESC_SIZE) /* * DMA_MAP expects the buffer to be an integral number of cache lines. * Rather than checking the actual cache line size, this code makes a diff --git a/core/dp/htt/htt_rx.c b/core/dp/htt/htt_rx.c index 9e5957483a82..b5d8667c5f3a 100644 --- a/core/dp/htt/htt_rx.c +++ b/core/dp/htt/htt_rx.c @@ -53,12 +53,20 @@ #include /* ieee80211_frame, ieee80211_qoscntl */ #include /* ieee80211_rx_status */ +#include +#include #ifdef DEBUG_DMA_DONE #include #include #endif +#ifdef HTT_DEBUG_DATA +#define HTT_PKT_DUMP(x) x +#else +#define HTT_PKT_DUMP(x) /* no-op */ +#endif + /* AR9888v1 WORKAROUND for EV#112367 */ /* FIX THIS - remove this WAR when the bug is fixed */ #define PEREGRINE_1_0_ZERO_LEN_PHY_ERR_WAR @@ -1151,8 +1159,313 @@ htt_rx_offload_paddr_msdu_pop_ll(htt_pdev_handle pdev, return 0; } -extern void -dump_pkt(qdf_nbuf_t nbuf, uint32_t nbuf_paddr, int len); +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#if HTT_PADDR64 +#define NEXT_FIELD_OFFSET_IN32 2 +#else /* ! HTT_PADDR64 */ +#define NEXT_FIELD_OFFSET_IN32 1 +#endif /* HTT_PADDR64 */ + +/** + * htt_mon_rx_handle_amsdu_packet() - Handle consecutive fragments of amsdu + * @msdu: pointer to first msdu of amsdu + * @pdev: Handle to htt_pdev_handle + * @msg_word: Input and output variable, so pointer to HTT msg pointer + * @amsdu_len: remaining length of all N-1 msdu msdu's + * + * This function handles the (N-1) msdu's of amsdu, N'th msdu is already + * handled by calling function. N-1 msdu's are tied using frags_list. + * msdu_info field updated by FW indicates if this is last msdu. All the + * msdu's before last msdu will be of MAX payload. + * + * Return: 1 on success and 0 on failure. + */ +int htt_mon_rx_handle_amsdu_packet(qdf_nbuf_t msdu, htt_pdev_handle pdev, + uint32_t **msg_word, uint32_t amsdu_len) +{ + qdf_nbuf_t frag_nbuf; + qdf_nbuf_t prev_frag_nbuf; + uint32_t len; + uint32_t last_frag; + + *msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS; + frag_nbuf = htt_rx_in_order_netbuf_pop(pdev, + HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(**msg_word)); + if (qdf_unlikely(NULL == frag_nbuf)) { + qdf_print("%s: netbuf pop failed!\n", __func__); + return 0; + } + last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)*msg_word)-> + msdu_info; + qdf_nbuf_append_ext_list(msdu, frag_nbuf, amsdu_len); + qdf_nbuf_set_pktlen(frag_nbuf, HTT_RX_BUF_SIZE); + qdf_nbuf_unmap(pdev->osdev, frag_nbuf, QDF_DMA_FROM_DEVICE); + /* For msdu's other than parent will not have htt_host_rx_desc_base */ + len = MIN(amsdu_len, HTT_RX_BUF_SIZE); + amsdu_len -= len; + qdf_nbuf_trim_tail(frag_nbuf, HTT_RX_BUF_SIZE - len); + + HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX, + QDF_TRACE_LEVEL_FATAL, + qdf_nbuf_data(frag_nbuf), + qdf_nbuf_len(frag_nbuf))); + prev_frag_nbuf = frag_nbuf; + while (!last_frag) { + *msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS; + frag_nbuf = htt_rx_in_order_netbuf_pop(pdev, + HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(**msg_word)); + last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *) + *msg_word)->msdu_info; + + if (qdf_unlikely(NULL == frag_nbuf)) { + qdf_print("%s: netbuf pop failed!\n", __func__); + prev_frag_nbuf->next = NULL; + return 0; + } + qdf_nbuf_set_pktlen(frag_nbuf, HTT_RX_BUF_SIZE); + qdf_nbuf_unmap(pdev->osdev, frag_nbuf, QDF_DMA_FROM_DEVICE); + + len = MIN(amsdu_len, HTT_RX_BUF_SIZE); + amsdu_len -= len; + qdf_nbuf_trim_tail(frag_nbuf, HTT_RX_BUF_SIZE - len); + HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX, + QDF_TRACE_LEVEL_FATAL, + qdf_nbuf_data(frag_nbuf), + qdf_nbuf_len(frag_nbuf))); + + qdf_nbuf_set_next(prev_frag_nbuf, frag_nbuf); + prev_frag_nbuf = frag_nbuf; + } + qdf_nbuf_set_next(prev_frag_nbuf, NULL); + return 1; +} + +/** + * htt_mon_rx_get_phy_info() - Get rate interms of 500Kbps. + * @rx_desc: Pointer to struct htt_host_rx_desc_base + * @rx_status: Return variable updated with phy_info in rx_status + * + * If l_sig_rate_select is 0: + * 0x8: OFDM 48 Mbps + * 0x9: OFDM 24 Mbps + * 0xA: OFDM 12 Mbps + * 0xB: OFDM 6 Mbps + * 0xC: OFDM 54 Mbps + * 0xD: OFDM 36 Mbps + * 0xE: OFDM 18 Mbps + * 0xF: OFDM 9 Mbps + * If l_sig_rate_select is 1: + * 0x8: CCK 11 Mbps long preamble + * 0x9: CCK 5.5 Mbps long preamble + * 0xA: CCK 2 Mbps long preamble + * 0xB: CCK 1 Mbps long preamble + * 0xC: CCK 11 Mbps short preamble + * 0xD: CCK 5.5 Mbps short preamble + * 0xE: CCK 2 Mbps short preamble + * + * Return: None + */ +static void htt_mon_rx_get_phy_info(struct htt_host_rx_desc_base *rx_desc, + struct mon_rx_status *rx_status) +{ +#define SHORT_PREAMBLE 1 +#define LONG_PREAMBLE 0 + char rate = 0x0; + uint8_t preamble = SHORT_PREAMBLE; + uint8_t preamble_type = rx_desc->ppdu_start.preamble_type; + uint8_t mcs = 0, nss = 0, sgi = 0, bw = 0, beamformed = 0; + uint16_t vht_flags = 0; + uint32_t l_sig_rate_select = rx_desc->ppdu_start.l_sig_rate_select; + uint32_t l_sig_rate = rx_desc->ppdu_start.l_sig_rate; + bool is_stbc = 0, ldpc = 0; + + if (l_sig_rate_select == 0) { + switch (l_sig_rate) { + case 0x8: + rate = 0x60; + break; + case 0x9: + rate = 0x30; + break; + case 0xA: + rate = 0x18; + break; + case 0xB: + rate = 0x0c; + break; + case 0xC: + rate = 0x6c; + break; + case 0xD: + rate = 0x48; + break; + case 0xE: + rate = 0x24; + break; + case 0xF: + rate = 0x12; + break; + default: + break; + } + } else if (l_sig_rate_select == 1) { + switch (l_sig_rate) { + case 0x8: + rate = 0x16; + preamble = LONG_PREAMBLE; + break; + case 0x9: + rate = 0x0B; + preamble = LONG_PREAMBLE; + break; + case 0xA: + rate = 0x04; + preamble = LONG_PREAMBLE; + break; + case 0xB: + rate = 0x02; + preamble = LONG_PREAMBLE; + break; + case 0xC: + rate = 0x16; + break; + case 0xD: + rate = 0x0B; + break; + case 0xE: + rate = 0x04; + break; + default: + break; + } + } else { + qdf_print("Invalid rate info\n"); + } + + switch (preamble_type) { + case 8: + is_stbc = ((VHT_SIG_A_2(rx_desc) >> 4) & 3); + /* fallthrough */ + case 9: + vht_flags = 1; + sgi = (VHT_SIG_A_2(rx_desc) >> 7) & 0x01; + bw = (VHT_SIG_A_1(rx_desc) >> 7) & 0x01; + mcs = (VHT_SIG_A_1(rx_desc) & 0x7f); + nss = mcs>>3; + beamformed = + (VHT_SIG_A_2(rx_desc) >> 8) & 0x1; + break; + case 0x0c: + vht_flags = 1; + is_stbc = (VHT_SIG_A_2(rx_desc) >> 3) & 1; + ldpc = (VHT_SIG_A_2(rx_desc) >> 2) & 1; + /* fallthrough */ + case 0x0d: + { + uint8_t gid_in_sig = ((VHT_SIG_A_1(rx_desc) >> 4) & 0x3f); + + vht_flags = 1; + sgi = VHT_SIG_A_2(rx_desc) & 0x01; + bw = (VHT_SIG_A_1(rx_desc) & 0x03); + if (gid_in_sig == 0 || gid_in_sig == 63) { + /* SU case */ + mcs = (VHT_SIG_A_2(rx_desc) >> 4) & + 0xf; + nss = (VHT_SIG_A_1(rx_desc) >> 10) & + 0x7; + } else { + /* SU case */ + uint8_t sta_user_pos = + (uint8_t)((rx_desc->ppdu_start.reserved_4a >> 8) + & 0x3); + mcs = (rx_desc->ppdu_start.vht_sig_b >> 16); + if (bw >= 2) + mcs >>= 3; + else if (bw > 0) + mcs >>= 1; + mcs &= 0xf; + nss = (((VHT_SIG_A_1(rx_desc) >> 10) + + sta_user_pos * 3) & 0x7); + } + beamformed = (VHT_SIG_A_2(rx_desc) >> 8) & 0x1; + } + /* fallthrough */ + default: + break; + } + + rx_status->mcs = mcs; + rx_status->nr_ant = nss; + rx_status->is_stbc = is_stbc; + rx_status->sgi = sgi; + rx_status->ldpc = ldpc; + rx_status->beamformed = beamformed; + rx_status->vht_flag_values3[0] = mcs << 0x4; + rx_status->rate = rate; + rx_status->vht_flags = vht_flags; + rx_status->rtap_flags |= ((preamble == SHORT_PREAMBLE) ? BIT(1) : 0); + rx_status->vht_flag_values2 = 0x01 < bw; +} + +/** + * htt_mon_rx_get_rtap_flags() - Get radiotap flags + * @rx_desc: Pointer to struct htt_host_rx_desc_base + * + * Return: Bitmapped radiotap flags. + */ +static uint8_t htt_mon_rx_get_rtap_flags(struct htt_host_rx_desc_base *rx_desc) +{ + uint8_t rtap_flags = 0; + + /* WEP40 || WEP104 || WEP128 */ + if (rx_desc->mpdu_start.encrypt_type == 0 || + rx_desc->mpdu_start.encrypt_type == 1 || + rx_desc->mpdu_start.encrypt_type == 3) + rtap_flags |= BIT(2); + + /* IEEE80211_RADIOTAP_F_FRAG */ + if (rx_desc->attention.fragment) + rtap_flags |= BIT(3); + + /* IEEE80211_RADIOTAP_F_FCS */ + rtap_flags |= BIT(4); + + /* IEEE80211_RADIOTAP_F_BADFCS */ + if (rx_desc->mpdu_end.fcs_err) + rtap_flags |= BIT(6); + + return rtap_flags; +} + +/** + * htt_rx_mon_get_rx_status() - Update information about the rx status, + * which is used later for radiotap updation. + * @rx_desc: Pointer to struct htt_host_rx_desc_base + * @rx_status: Return variable updated with rx_status + * + * Return: None + */ +void htt_rx_mon_get_rx_status(htt_pdev_handle pdev, + struct htt_host_rx_desc_base *rx_desc, + struct mon_rx_status *rx_status) +{ + uint16_t channel_flags = 0; + struct mon_channel *ch_info = &pdev->mon_ch_info; + + rx_status->tsft = (u_int64_t)TSF_TIMESTAMP(rx_desc); + rx_status->chan_freq = ch_info->ch_freq; + rx_status->chan_num = ch_info->ch_num; + htt_mon_rx_get_phy_info(rx_desc, rx_status); + rx_status->rtap_flags |= htt_mon_rx_get_rtap_flags(rx_desc); + channel_flags |= rx_desc->ppdu_start.l_sig_rate_select ? + IEEE80211_CHAN_CCK : IEEE80211_CHAN_OFDM; + channel_flags |= + (cds_chan_to_band(ch_info->ch_num) == CDS_BAND_2GHZ ? + IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ); + + rx_status->chan_flags = channel_flags; + rx_status->ant_signal_db = rx_desc->ppdu_start.rssi_comb; +} #ifdef RX_HASH_DEBUG #define HTT_RX_CHECK_MSDU_COUNT(msdu_count) HTT_ASSERT_ALWAYS(msdu_count) @@ -1160,6 +1473,164 @@ dump_pkt(qdf_nbuf_t nbuf, uint32_t nbuf_paddr, int len); #define HTT_RX_CHECK_MSDU_COUNT(msdu_count) /* no-op */ #endif +/** + * htt_rx_mon_amsdu_rx_in_order_pop_ll() - Monitor mode HTT Rx in order pop + * function + * @pdev: Handle to htt_pdev_handle + * @rx_ind_msg: In order indication message. + * @head_msdu: Return variable pointing to head msdu. + * @tail_msdu: Return variable pointing to tail msdu. + * + * This function pops the msdu based on paddr:length of inorder indication + * message. + * + * Return: 1 for success, 0 on failure. + */ +int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, + qdf_nbuf_t rx_ind_msg, + qdf_nbuf_t *head_msdu, + qdf_nbuf_t *tail_msdu) +{ + qdf_nbuf_t msdu, next; + uint8_t *rx_ind_data; + uint32_t *msg_word; + uint32_t msdu_count; + struct htt_host_rx_desc_base *rx_desc; + struct mon_rx_status rx_status = {0}; + uint32_t amsdu_len; + uint32_t len; + uint32_t last_frag; + + HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0); + + rx_ind_data = qdf_nbuf_data(rx_ind_msg); + msg_word = (uint32_t *)rx_ind_data; + + HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX, + QDF_TRACE_LEVEL_FATAL, + (void *)rx_ind_data, + (int)qdf_nbuf_len(rx_ind_msg))); + + /* Get the total number of MSDUs */ + msdu_count = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1)); + HTT_RX_CHECK_MSDU_COUNT(msdu_count); + + msg_word = (uint32_t *)(rx_ind_data + + HTT_RX_IN_ORD_PADDR_IND_HDR_BYTES); + + (*head_msdu) = msdu = htt_rx_in_order_netbuf_pop(pdev, + HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*msg_word)); + + if (qdf_unlikely(NULL == msdu)) { + qdf_print("%s: netbuf pop failed!\n", __func__); + *tail_msdu = NULL; + return 0; + } + while (msdu_count > 0) { + + msdu_count--; + /* + * Set the netbuf length to be the entire buffer length + * initially, so the unmap will unmap the entire buffer. + */ + qdf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE); + qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_FROM_DEVICE); + + /* + * cache consistency has been taken care of by the + * qdf_nbuf_unmap + */ + rx_desc = htt_rx_desc(msdu); + HTT_PKT_DUMP(htt_print_rx_desc(rx_desc)); + /* + * Make the netbuf's data pointer point to the payload rather + * than the descriptor. + */ + htt_rx_mon_get_rx_status(pdev, rx_desc, &rx_status); + /* + * 350 bytes of RX_STD_DESC size should be sufficient for + * radiotap. + */ + qdf_nbuf_update_radiotap(&rx_status, msdu, + HTT_RX_STD_DESC_RESERVATION); + amsdu_len = HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_GET(*(msg_word + + NEXT_FIELD_OFFSET_IN32)); + + /* + * MAX_RX_PAYLOAD_SZ when we have AMSDU packet. amsdu_len in + * which case is the total length of sum of all AMSDU's + */ + len = MIN(amsdu_len, MAX_RX_PAYLOAD_SZ); + amsdu_len -= len; + qdf_nbuf_trim_tail(msdu, + HTT_RX_BUF_SIZE - + (RX_STD_DESC_SIZE + len)); + + + HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX, + QDF_TRACE_LEVEL_FATAL, + qdf_nbuf_data(msdu), + qdf_nbuf_len(msdu))); + last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *) + msg_word)->msdu_info; + +#undef NEXT_FIELD_OFFSET_IN32 + /* Handle amsdu packet */ + if (!last_frag) { + /* + * For AMSDU packet msdu->len is sum of all the msdu's + * length, msdu->data_len is sum of length's of + * remaining msdu's other than parent. + */ + if (!htt_mon_rx_handle_amsdu_packet(msdu, pdev, + &msg_word, + amsdu_len)) { + qdf_print("%s: failed to handle amsdu packet\n", + __func__); + return 0; + } + } + /* check if this is the last msdu */ + if (msdu_count) { + msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS; + next = htt_rx_in_order_netbuf_pop(pdev, + HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*msg_word)); + if (qdf_unlikely(NULL == next)) { + qdf_print("%s: netbuf pop failed!\n", + __func__); + *tail_msdu = NULL; + return 0; + } + qdf_nbuf_set_next(msdu, next); + msdu = next; + } else { + *tail_msdu = msdu; + qdf_nbuf_set_next(msdu, NULL); + } + } + + return 1; +} + +/** + * htt_rx_mon_note_capture_channel() - Make note of channel to update in + * radiotap + * @pdev: handle to htt_pdev + * @mon_ch: capture channel number. + * + * Return: None + */ +void htt_rx_mon_note_capture_channel(htt_pdev_handle pdev, int mon_ch) +{ + struct mon_channel *ch_info = &pdev->mon_ch_info; + + ch_info->ch_num = mon_ch; + ch_info->ch_freq = cds_chan_to_freq(mon_ch); +} + +extern void +dump_pkt(qdf_nbuf_t nbuf, uint32_t nbuf_paddr, int len); + /* Return values: 1 - success, 0 - failure */ int htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, @@ -2231,6 +2702,9 @@ int htt_rx_attach(struct htt_pdev_t *pdev) htt_rx_mpdu_desc_list_next = htt_rx_mpdu_desc_list_next_ll; } + if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) + htt_rx_amsdu_pop = htt_rx_mon_amsdu_rx_in_order_pop_ll; + htt_rx_offload_msdu_pop = htt_rx_offload_msdu_pop_ll; htt_rx_mpdu_desc_retry = htt_rx_mpdu_desc_retry_ll; htt_rx_mpdu_desc_seq_num = htt_rx_mpdu_desc_seq_num_ll; diff --git a/core/dp/htt/htt_types.h b/core/dp/htt/htt_types.h index b0bcf811a926..7900d1c6f9e2 100644 --- a/core/dp/htt/htt_types.h +++ b/core/dp/htt/htt_types.h @@ -211,6 +211,16 @@ struct msdu_ext_desc_t { }; #endif /* defined(HELIUMPLUS_PADDR64) */ +/** + * struct mon_channel + * @ch_num: Monitor mode capture channel number + * @ch_freq: channel frequency. + */ +struct mon_channel { + uint32_t ch_num; + uint32_t ch_freq; +}; + struct htt_pdev_t { ol_pdev_handle ctrl_pdev; ol_txrx_pdev_handle txrx_pdev; @@ -385,6 +395,7 @@ struct htt_pdev_t { struct rx_buf_debug *rx_buff_list; int rx_buff_index; #endif + struct mon_channel mon_ch_info; }; #define HTT_EPID_GET(_htt_pdev_hdl) \ diff --git a/core/dp/htt/rx_desc.h b/core/dp/htt/rx_desc.h index 66963d1e2b30..fc1b39ac52f7 100644 --- a/core/dp/htt/rx_desc.h +++ b/core/dp/htt/rx_desc.h @@ -257,6 +257,12 @@ struct rx_ppdu_start { uint32_t service:16, /* [15:0] */ reserved_9:16; /* [31:16] */ }; + +#define VHT_SIG_A_1(rx_desc) ((rx_desc)->ppdu_start.ht_sig_vht_sig_ah_sig_a_1) +#define VHT_SIG_A_2(rx_desc) ((rx_desc)->ppdu_start.ht_sig_vht_sig_ah_sig_a_2) +#define TSF_TIMESTAMP(rx_desc) \ +((rx_desc)->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32) + struct rx_location_info { volatile uint32_t rtt_fac_legacy:14, /* [13:0] */ @@ -469,6 +475,10 @@ struct rx_ppdu_start { reserved_9:16; /* [31:16] */ }; +#define VHT_SIG_A_1(rx_desc) ((rx_desc)->ppdu_start.ht_sig_vht_sig_a_1) +#define VHT_SIG_A_2(rx_desc) ((rx_desc)->ppdu_start.ht_sig_vht_sig_a_2) + +#define TSF_TIMESTAMP(rx_desc) ((rx_desc)->ppdu_end.tsf_timestamp) struct rx_mpdu_start { volatile diff --git a/core/dp/ol/inc/ol_htt_api.h b/core/dp/ol/inc/ol_htt_api.h index f55ddfb730ec..371af50bfa20 100644 --- a/core/dp/ol/inc/ol_htt_api.h +++ b/core/dp/ol/inc/ol_htt_api.h @@ -362,4 +362,7 @@ static inline void htt_ipa_uc_detach(struct htt_pdev_t *pdev) } #endif /* IPA_OFFLOAD */ +void htt_rx_mon_note_capture_channel(htt_pdev_handle pdev, int mon_ch); + +void ol_htt_mon_note_chan(ol_txrx_pdev_handle pdev, int mon_ch); #endif /* _OL_HTT_API__H_ */ diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c index 350d4c7a298d..eea89ab5570a 100644 --- a/core/dp/txrx/ol_rx.c +++ b/core/dp/txrx/ol_rx.c @@ -57,6 +57,7 @@ #include /* IPv6 header defs */ #include #include +#include #ifdef HTT_RX_RESTORE #if defined(CONFIG_CNSS) @@ -1243,7 +1244,10 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev, qdf_nbuf_t head_msdu, tail_msdu = NULL; if (pdev) { - peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (qdf_unlikely(QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())) + peer = pdev->self_peer; + else + peer = ol_txrx_peer_find_by_id(pdev, peer_id); htt_pdev = pdev->htt_pdev; } else { TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, @@ -1374,6 +1378,17 @@ ol_rx_offload_paddr_deliver_ind_handler(htt_pdev_handle htt_pdev, htt_rx_msdu_buff_replenish(htt_pdev); } +/** + * ol_htt_mon_note_chan() - Update monitor channel information + * @pdev: handle to the physical device + * @mon_ch: Monitor channel + * + * Return: None + */ +void ol_htt_mon_note_chan(ol_txrx_pdev_handle pdev, int mon_ch) +{ + htt_rx_mon_note_capture_channel(pdev->htt_pdev, mon_ch); +} #ifdef NEVERDEFINED /** diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 6d8ca0f40a75..c2b2490960dc 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -1569,6 +1569,15 @@ ol_txrx_peer_attach(ol_txrx_vdev_handle vdev, uint8_t *peer_mac_addr) #ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI peer->rssi_dbm = HTT_RSSI_INVALID; #endif + if ((QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) && + !pdev->self_peer) { + pdev->self_peer = peer; + /* + * No Tx in monitor mode, otherwise results in target assert. + * Setting disable_intrabss_fwd to true + */ + ol_vdev_rx_set_intrabss_fwd(vdev, true); + } ol_txrx_local_peer_id_alloc(pdev, peer); diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h index a36346e63f1c..42d7b368427b 100644 --- a/core/dp/txrx/ol_txrx_types.h +++ b/core/dp/txrx/ol_txrx_types.h @@ -767,6 +767,7 @@ struct ol_txrx_pdev_t { void *lro_data; void (*lro_flush_cb)(void *); } lro_info; + struct ol_txrx_peer_t *self_peer; }; struct ol_txrx_ocb_chan_info { diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 7c3112925777..49523a706044 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -51,6 +51,7 @@ #include "qdf_types.h" #include "qdf_mem.h" #include "ol_txrx_peer_find.h" +#include "ol_htt_api.h" #include "wma_types.h" #include "lim_api.h" @@ -97,8 +98,6 @@ enum extscan_report_events_type { #define WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION (5 * 1000) /* in msec */ #endif -void ol_cfg_update_mon_chan(ol_txrx_pdev_handle pdev, int mon_ch, - int mon_ch_freq); /** * wma_set_p2p_scan_info() - set p2p scan info in wma handle * @wma_handle: wma handle -- cgit v1.2.3 From 2e03b41f6358aa54584fb55e501768ba64c40486 Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Wed, 6 Apr 2016 14:36:15 -0700 Subject: qcacld-3.0: Clean up OS wrapper functions Replace CNSS wrapper functions with OS standard APIs. Change-Id: Ic9e8305afc599fa02e80d1b60892cc11b4d4025e CRs-Fixed: 1000113 --- core/cds/src/cds_api.c | 15 +-------------- core/cds/src/cds_concurrency.c | 5 ----- core/cds/src/cds_sched.c | 9 --------- core/hdd/inc/wlan_hdd_main.h | 6 ------ core/hdd/src/wlan_hdd_cfg80211.c | 19 +------------------ core/hdd/src/wlan_hdd_ext_scan.c | 9 ++++----- core/hdd/src/wlan_hdd_ipa.c | 25 ------------------------- core/hdd/src/wlan_hdd_main.c | 10 ---------- core/hdd/src/wlan_hdd_scan.c | 5 ----- core/hdd/src/wlan_hdd_tdls.c | 9 --------- core/hdd/src/wlan_hdd_wmm.c | 5 ----- 11 files changed, 6 insertions(+), 111 deletions(-) diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 590179bb590f..e0648122ad8d 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -1608,11 +1608,7 @@ QDF_STATUS cds_get_vdev_types(enum tQDF_ADAPTER_MODE mode, uint32_t *type, */ void cds_flush_work(void *work) { -#if defined (CONFIG_CNSS) - cnss_flush_work(work); -#elif defined (WLAN_OPEN_SOURCE) cancel_work_sync(work); -#endif } /** @@ -1623,11 +1619,7 @@ void cds_flush_work(void *work) */ void cds_flush_delayed_work(void *dwork) { -#if defined (CONFIG_CNSS) - cnss_flush_delayed_work(dwork); -#elif defined (WLAN_OPEN_SOURCE) cancel_delayed_work_sync(dwork); -#endif } /** @@ -1706,15 +1698,10 @@ void cds_trigger_recovery(void) uint64_t cds_get_monotonic_boottime(void) { -#ifdef CONFIG_CNSS struct timespec ts; - cnss_get_monotonic_boottime(&ts); + get_monotonic_boottime(&ts); return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); -#else - return ((uint64_t)qdf_system_ticks_to_msecs(qdf_system_ticks()) * - 1000); -#endif } /** diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index b55ccce7cae3..0c11fdbeda44 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -6389,13 +6389,8 @@ QDF_STATUS cds_check_and_restart_sap(eCsrRoamResult roam_result, * creating workqueue then our main thread might go to sleep * which is not acceptable. */ -#ifdef CONFIG_CNSS - cnss_init_work(&hdd_ctx->sap_start_work, - cds_sap_restart_handle); -#else INIT_WORK(&hdd_ctx->sap_start_work, cds_sap_restart_handle); -#endif schedule_work(&hdd_ctx->sap_start_work); return QDF_STATUS_SUCCESS; } diff --git a/core/cds/src/cds_sched.c b/core/cds/src/cds_sched.c index bbf9b754d775..4f9a39c5fe2b 100644 --- a/core/cds/src/cds_sched.c +++ b/core/cds/src/cds_sched.c @@ -46,9 +46,6 @@ #include #include #include -#if defined(QCA_CONFIG_SMP) && defined(CONFIG_CNSS) -#include -#endif /* Preprocessor Definitions and Constants */ #define CDS_SCHED_THREAD_HEART_BEAT INFINITE /* Milli seconds to delay SSR thread when an Entry point is Active */ @@ -89,13 +86,7 @@ static QDF_STATUS cds_alloc_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext); #define CDS_CORE_PER_CLUSTER (4) static int cds_set_cpus_allowed_ptr(struct task_struct *task, unsigned long cpu) { -#ifdef WLAN_OPEN_SOURCE return set_cpus_allowed_ptr(task, cpumask_of(cpu)); -#elif defined(CONFIG_CNSS) - return cnss_set_cpus_allowed_ptr(task, cpu); -#else - return 0; -#endif } /** diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 0262528886b8..f8a3837b13ee 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -247,12 +247,6 @@ */ #define WLAN_TFC_IPAUC_TX_DESC_RESERVE 100 -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -#ifdef CONFIG_CNSS -#define cfg80211_vendor_cmd_reply(skb) cnss_vendor_cmd_reply(skb) -#endif -#endif - /* * NET_NAME_UNKNOWN is only introduced after Kernel 3.17, to have a macro * here if the Kernel version is less than 3.17 to avoid the interleave diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 104aa9396064..19b32c755594 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -42,9 +42,6 @@ #include #include #include -#ifdef CONFIG_CNSS -#include -#endif #include #include #include "sir_params.h" @@ -1791,13 +1788,8 @@ void wlan_hdd_cfg80211_acs_ch_select_evt(hdd_adapter_t *adapter) con_sap_adapter = hdd_get_con_sap_adapter(adapter, false); if (con_sap_adapter && test_bit(ACS_PENDING, &con_sap_adapter->event_flags)) { -#ifdef CONFIG_CNSS - cnss_init_delayed_work(&con_sap_adapter->acs_pending_work, - wlan_hdd_cfg80211_start_pending_acs); -#else INIT_DELAYED_WORK(&con_sap_adapter->acs_pending_work, wlan_hdd_cfg80211_start_pending_acs); -#endif /* Lets give 500ms for OBSS + START_BSS to complete */ schedule_delayed_work(&con_sap_adapter->acs_pending_work, msecs_to_jiffies(500)); @@ -7826,9 +7818,7 @@ wlan_hdd_cfg80211_inform_bss_frame(hdd_adapter_t *pAdapter, int rssi = 0; hdd_context_t *pHddCtx; int status; -#ifdef CONFIG_CNSS struct timespec ts; -#endif struct hdd_config *cfg_param; ENTER(); @@ -7847,18 +7837,11 @@ wlan_hdd_cfg80211_inform_bss_frame(hdd_adapter_t *pAdapter, memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN); -#ifdef CONFIG_CNSS /* Android does not want the timestamp from the frame. Instead it wants a monotonic increasing value */ - cnss_get_monotonic_boottime(&ts); + get_monotonic_boottime(&ts); mgmt->u.probe_resp.timestamp = ((u64) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); -#else - /* keep old behavior for non-open source (for now) */ - memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp, - sizeof(bss_desc->timeStamp)); - -#endif mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval; mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo; diff --git a/core/hdd/src/wlan_hdd_ext_scan.c b/core/hdd/src/wlan_hdd_ext_scan.c index 06473990b67c..34a943e47df4 100644 --- a/core/hdd/src/wlan_hdd_ext_scan.c +++ b/core/hdd/src/wlan_hdd_ext_scan.c @@ -772,9 +772,8 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx, { hdd_context_t *pHddCtx = (hdd_context_t *) ctx; struct sk_buff *skb = NULL; -#ifdef CONFIG_CNSS struct timespec ts; -#endif + int flags = cds_get_gfp_flags(); ENTER(); @@ -804,12 +803,12 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx, } pData->ap.channel = cds_chan_to_freq(pData->ap.channel); -#ifdef CONFIG_CNSS + /* Android does not want the time stamp from the frame. Instead it wants a monotonic increasing value since boot */ - cnss_get_monotonic_boottime(&ts); + get_monotonic_boottime(&ts); pData->ap.ts = ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); -#endif + hddLog(LOG1, "Req Id %u More Data %u", pData->requestId, pData->moreData); hddLog(LOG1, "AP Info: Timestamp %llu Ssid: %s " diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c index 84cc0e37cb38..90e6c7228e87 100644 --- a/core/hdd/src/wlan_hdd_ipa.c +++ b/core/hdd/src/wlan_hdd_ipa.c @@ -1743,19 +1743,11 @@ end: * * Return: none */ -#ifdef CONFIG_CNSS -static void hdd_ipa_init_uc_op_work(struct work_struct *work, - work_func_t work_handler) -{ - cnss_init_work(work, work_handler); -} -#else static void hdd_ipa_init_uc_op_work(struct work_struct *work, work_func_t work_handler) { INIT_WORK(work, work_handler); } -#endif /** @@ -2353,19 +2345,11 @@ int hdd_ipa_set_perf_level(hdd_context_t *hdd_ctx, uint64_t tx_packets, * * Return: none */ -#ifdef CONFIG_CNSS -static void hdd_ipa_init_uc_rm_work(struct work_struct *work, - work_func_t work_handler) -{ - cnss_init_work(work, work_handler); -} -#else static void hdd_ipa_init_uc_rm_work(struct work_struct *work, work_func_t work_handler) { INIT_WORK(work, work_handler); } -#endif /** * hdd_ipa_setup_rm() - Setup IPA resource management @@ -2430,13 +2414,8 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa) } qdf_wake_lock_create(&hdd_ipa->wake_lock, "wlan_ipa"); -#ifdef CONFIG_CNSS - cnss_init_delayed_work(&hdd_ipa->wake_lock_work, - hdd_ipa_wake_lock_timer_func); -#else INIT_DELAYED_WORK(&hdd_ipa->wake_lock_work, hdd_ipa_wake_lock_timer_func); -#endif qdf_spinlock_create(&hdd_ipa->rm_lock); hdd_ipa->rm_state = HDD_IPA_RM_RELEASED; hdd_ipa->wake_lock_released = true; @@ -4045,11 +4024,7 @@ QDF_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx) qdf_spinlock_create(&iface_context->interface_lock); } -#ifdef CONFIG_CNSS - cnss_init_work(&hdd_ipa->pm_work, hdd_ipa_pm_send_pkt_to_tl); -#else INIT_WORK(&hdd_ipa->pm_work, hdd_ipa_pm_send_pkt_to_tl); -#endif qdf_spinlock_create(&hdd_ipa->pm_lock); qdf_nbuf_queue_init(&hdd_ipa->pm_queue_head); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index cf03f2014d06..0cfba34472be 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2541,26 +2541,16 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type, * Workqueue which gets scheduled in IPv4 notification * callback */ -#ifdef CONFIG_CNSS - cnss_init_work(&adapter->ipv4NotifierWorkQueue, - hdd_ipv4_notifier_work_queue); -#else INIT_WORK(&adapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue); -#endif #ifdef WLAN_NS_OFFLOAD /* * Workqueue which gets scheduled in IPv6 * notification callback. */ -#ifdef CONFIG_CNSS - cnss_init_work(&adapter->ipv6NotifierWorkQueue, - hdd_ipv6_notifier_work_queue); -#else INIT_WORK(&adapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue); -#endif #endif status = hdd_register_interface(adapter, rtnl_held); if (QDF_STATUS_SUCCESS != status) { diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index bee481fa42e6..b4d68c59042e 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -1331,13 +1331,8 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, */ pAdapter->request = request; -#ifdef CONFIG_CNSS - cnss_init_work(&pAdapter->scan_block_work, - wlan_hdd_cfg80211_scan_block_cb); -#else INIT_WORK(&pAdapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb); -#endif schedule_work(&pAdapter->scan_block_work); return 0; } diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index cd60b7141134..03d233bf1674 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -750,19 +750,10 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED; } -#ifdef CONFIG_CNSS - cnss_init_work(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup); -#else INIT_WORK(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup); -#endif -#ifdef CONFIG_CNSS - cnss_init_delayed_work(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, - wlan_hdd_tdls_schedule_scan); -#else INIT_DELAYED_WORK(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, wlan_hdd_tdls_schedule_scan); -#endif /* * Release tdls lock before calling in SME api diff --git a/core/hdd/src/wlan_hdd_wmm.c b/core/hdd/src/wlan_hdd_wmm.c index 28e96fb7b299..5fbfb179fc9d 100644 --- a/core/hdd/src/wlan_hdd_wmm.c +++ b/core/hdd/src/wlan_hdd_wmm.c @@ -1882,12 +1882,7 @@ QDF_STATUS hdd_wmm_acquire_access(hdd_adapter_t *pAdapter, pQosContext->magic = HDD_WMM_CTX_MAGIC; pQosContext->is_inactivity_timer_running = false; -#ifdef CONFIG_CNSS - cnss_init_work(&pQosContext->wmmAcSetupImplicitQos, - hdd_wmm_do_implicit_qos); -#else INIT_WORK(&pQosContext->wmmAcSetupImplicitQos, hdd_wmm_do_implicit_qos); -#endif QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG, "%s: Scheduling work for AC %d, context %p", -- cgit v1.2.3 From 1d8045cf0c09ad367894f22527744de4de0fac2f Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Wed, 6 Apr 2016 16:40:49 -0700 Subject: qcacld-3.0: HDD: Use PLD APIs (Part 1) PLD is a interface between CLD and CNSS/ICNSS. It hides CNSS/ICNSS APIs from CLD and provides a set of common APIs. CLD modules should use these PLD APIs instead of calling CNSS/ICNSS platform APIs. Register WLAN driver operations with PLD APIs for PCIE/SNOC. SDIO/USB changes need to be done separately by adding SDIO/USB support in PLD and replacing SDIO/USB specific functions with common PLD APIs. Change-Id: Ie329316dd5646aa2130208e2825bedc4f2aef719 CRs-Fixed: 1000113 --- core/hdd/src/wlan_hdd_driver_ops.c | 336 ++++++++++++++----------------------- core/hdd/src/wlan_hdd_main.c | 6 + 2 files changed, 132 insertions(+), 210 deletions(-) diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index 4b80d6933d72..c5fc181def9b 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -54,6 +54,7 @@ #include "qwlan_version.h" #include "bmi.h" #include "cdp_txrx_bus.h" +#include "pld_common.h" #ifdef MODULE #define WLAN_MODULE_NAME module_name(THIS_MODULE) @@ -61,25 +62,7 @@ #define WLAN_MODULE_NAME "wlan" #endif -#ifdef HIF_PCI -#ifdef CONFIG_CNSS -#define WLAN_HDD_REGISTER_DRIVER(wlan_drv_ops) \ - cnss_wlan_register_driver(wlan_drv_ops) -#define WLAN_HDD_UNREGISTER_DRIVER(wlan_drv_ops) \ - cnss_wlan_unregister_driver(wlan_drv_ops) -#else -#define WLAN_HDD_REGISTER_DRIVER(wlan_drv_ops) \ - pci_register_driver(wlan_drv_ops) -#define WLAN_HDD_UNREGISTER_DRIVER(wlan_drv_ops) \ - pci_unregister_driver(wlan_drv_ops) -#endif /* CONFIG_CNSS */ -#else -#define WLAN_HDD_REGISTER_DRIVER(wlan_drv_ops) \ - icnss_register_driver(wlan_drv_ops) -#define WLAN_HDD_UNREGISTER_DRIVER(wlan_drv_ops) \ - icnss_unregister_driver(wlan_drv_ops) -#endif /* HIF_PCI */ -#define DISABLE_KRAIT_IDLE_PS_VAL 1 +#define DISABLE_KRAIT_IDLE_PS_VAL 1 /* * In BMI Phase we are only sending small chunk (256 bytes) of the FW image at @@ -209,6 +192,26 @@ static void hdd_deinit_cds_hif_context(void) return; } +/** + * to_bus_type() - Map PLD bus type to low level bus type + * @bus_type: PLD bus type + * + * Map PLD bus type to low level bus type. + * + * Return: low level bus type. + */ +static enum qdf_bus_type to_bus_type(enum pld_bus_type bus_type) +{ + switch (bus_type) { + case PLD_BUS_TYPE_PCIE: + return QDF_BUS_TYPE_PCI; + case PLD_BUS_TYPE_SNOC: + return QDF_BUS_TYPE_SNOC; + default: + return QDF_BUS_TYPE_NONE; + } +} + /** * hdd_hif_open() - HIF open helper * @dev: wlan device structure @@ -790,268 +793,181 @@ static int wlan_hdd_runtime_resume(void) } #endif -#ifdef HIF_PCI /** - * wlan_hdd_pci_probe() - probe callback for pci platform driver - * @pdev: bus dev + * wlan_hdd_pld_probe() - probe function registered to PLD + * @dev: device + * @pld_bus_type: PLD bus type + * @bdev: bus device structure + * @id: bus identifier for shared busses * - * Return: void + * Return: 0 on success */ -static int wlan_hdd_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) +static int wlan_hdd_pld_probe(struct device *dev, + enum pld_bus_type pld_bus_type, + void *bdev, void *id) { - return wlan_hdd_probe(&pdev->dev, pdev, (void *)id, - QDF_BUS_TYPE_PCI, false); + enum qdf_bus_type bus_type; + + bus_type = to_bus_type(pld_bus_type); + if (bus_type == QDF_BUS_TYPE_NONE) { + hdd_err("Invalid bus type %d->%d", + pld_bus_type, bus_type); + return -EINVAL; + } + + return wlan_hdd_probe(dev, bdev, id, bus_type, false); } /** - * wlan_hdd_pci_remove() - wlan_hdd_pci_remove + * wlan_hdd_pld_remove() - remove function registered to PLD + * @dev: device + * @pld_bus_type: PLD bus type * * Return: void */ -void wlan_hdd_pci_remove(struct pci_dev *pdev) +static void wlan_hdd_pld_remove(struct device *dev, + enum pld_bus_type bus_type) { wlan_hdd_remove(); } /** - * wlan_hdd_pci_reinit() - wlan_hdd_pci_reinit - * @pdev: bus dev - * @id: bus id - * - * Return: int - */ -int wlan_hdd_pci_reinit(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - return wlan_hdd_probe(&pdev->dev, pdev, (void *)id, - QDF_BUS_TYPE_PCI, true); -} - -/** - * wlan_hdd_pci_shutdown() - wlan_hdd_pci_shutdown - * @pdev: pdev + * wlan_hdd_pld_shutdown() - shutdown function registered to PLD + * @dev: device + * @pld_bus_type: PLD bus type * * Return: void */ -void wlan_hdd_pci_shutdown(struct pci_dev *pdev) +static void wlan_hdd_pld_shutdown(struct device *dev, + enum pld_bus_type bus_type) { wlan_hdd_shutdown(); } /** - * wlan_hdd_pci_crash_shutdown() - wlan_hdd_pci_crash_shutdown - * @pdev: pdev + * wlan_hdd_pld_reinit() - reinit function registered to PLD + * @dev: device + * @pld_bus_type: PLD bus type + * @bdev: bus device structure + * @id: bus identifier for shared busses * - * Return: void + * Return: 0 on success */ -void wlan_hdd_pci_crash_shutdown(struct pci_dev *pdev) +static int wlan_hdd_pld_reinit(struct device *dev, + enum pld_bus_type pld_bus_type, + void *bdev, void *id) { - wlan_hdd_crash_shutdown(); -} + enum qdf_bus_type bus_type; -/** - * wlan_hdd_pci_notify_handler() - wlan_hdd_pci_notify_handler - * @pdev: pdev - * @state: state - * - * Return: void - */ -void wlan_hdd_pci_notify_handler(struct pci_dev *pdev, int state) -{ - wlan_hdd_notify_handler(state); -} + bus_type = to_bus_type(pld_bus_type); + if (bus_type == QDF_BUS_TYPE_NONE) { + hdd_err("Invalid bus type %d->%d", + pld_bus_type, bus_type); + return -EINVAL; + } -/** - * wlan_hdd_pci_suspend() - wlan_hdd_pci_suspend - * @pdev: pdev - * @state: state - * - * Return: void - */ -static int wlan_hdd_pci_suspend(struct pci_dev *pdev, pm_message_t state) -{ - return wlan_hdd_bus_suspend(state); + return wlan_hdd_probe(dev, bdev, id, bus_type, true); } /** - * wlan_hdd_pci_resume() - wlan_hdd_pci_resume - * @pdev: pdev + * wlan_hdd_pld_crash_shutdown() - crash_shutdown function registered to PLD + * @dev: device + * @pld_bus_type: PLD bus type * * Return: void */ -static int wlan_hdd_pci_resume(struct pci_dev *pdev) -{ - return wlan_hdd_bus_resume(); -} - -#ifdef FEATURE_RUNTIME_PM -/** - * wlan_hdd_pci_runtime_suspend() - wlan_hdd_pci_suspend - * @pdev: pdev - * @state: state - * - * Return: success or errno - */ -static int wlan_hdd_pci_runtime_suspend(struct pci_dev *pdev) +static void wlan_hdd_pld_crash_shutdown(struct device *dev, + enum pld_bus_type bus_type) { - return wlan_hdd_runtime_suspend(); -} - -/** - * wlan_hdd_pci_runtime_resume() - runtime resume callback to register with pci - * @pdev: pci device id - * - * Return: success or errno - */ -static int wlan_hdd_pci_runtime_resume(struct pci_dev *pdev) -{ - return wlan_hdd_runtime_resume(); -} -#endif - -#else -/** - * wlan_hdd_snoc_probe() - wlan_hdd_snoc_probe - * @dev: dev - * - * Return: int - */ -static int wlan_hdd_snoc_probe(struct device *dev) -{ - return wlan_hdd_probe(dev, NULL, NULL, QDF_BUS_TYPE_SNOC, false); + wlan_hdd_crash_shutdown(); } /** - * wlan_hdd_snoc_remove() - wlan_hdd_snoc_remove - * @dev: dev + * wlan_hdd_pld_suspend() - suspend function registered to PLD + * @dev: device + * @pld_bus_type: PLD bus type + * @state: PM state * - * Return: void + * Return: 0 on success */ -void wlan_hdd_snoc_remove(struct device *dev) -{ - wlan_hdd_remove(); -} +static int wlan_hdd_pld_suspend(struct device *dev, + enum pld_bus_type bus_type, + pm_message_t state) -/** - * wlan_hdd_snoc_shutdown() - wlan_hdd_snoc_shutdown - * @dev: dev - * - * Return: void - */ -void wlan_hdd_snoc_shutdown(struct device *dev) { - wlan_hdd_shutdown(); + return wlan_hdd_bus_suspend(state); } /** - * wlan_hdd_snoc_reinit() - wlan_hdd_snoc_reinit - * @dev: dev + * wlan_hdd_pld_resume() - resume function registered to PLD + * @dev: device + * @pld_bus_type: PLD bus type * - * Return: int + * Return: 0 on success */ -int wlan_hdd_snoc_reinit(struct device *dev) +static int wlan_hdd_pld_resume(struct device *dev, + enum pld_bus_type bus_type) { - return wlan_hdd_probe(dev, NULL, NULL, QDF_BUS_TYPE_SNOC, true); + return wlan_hdd_bus_resume(); } /** - * wlan_hdd_snoc_crash_shutdown() - wlan_hdd_snoc_crash_shutdown - * @dev: dev + * wlan_hdd_pld_notify_handler() - notify_handler function registered to PLD + * @dev: device + * @pld_bus_type: PLD bus type + * @state: Modem power state * * Return: void */ -void wlan_hdd_snoc_crash_shutdown(void *pdev) +static void wlan_hdd_pld_notify_handler(struct device *dev, + enum pld_bus_type bus_type, + int state) { - wlan_hdd_crash_shutdown(); + wlan_hdd_notify_handler(state); } +#ifdef FEATURE_RUNTIME_PM /** - * wlan_hdd_snoc_suspend() - wlan_hdd_snoc_suspend - * @dev: dev - * @state: state + * wlan_hdd_pld_runtime_suspend() - runtime suspend function registered to PLD + * @dev: device + * @pld_bus_type: PLD bus type * - * Return: int + * Return: 0 on success */ -static int wlan_hdd_snoc_suspend(struct device *dev, pm_message_t state) +static int wlan_hdd_pld_runtime_suspend(struct device *dev, + enum pld_bus_type bus_type) { - return wlan_hdd_bus_suspend(state); + return wlan_hdd_runtime_suspend(); } /** - * wlan_hdd_snoc_resume() - wlan_hdd_snoc_resume - * @dev: dev + * wlan_hdd_pld_runtime_resume() - runtime resume function registered to PLD + * @dev: device + * @pld_bus_type: PLD bus type * - * Return: int + * Return: 0 on success */ -static int wlan_hdd_snoc_resume(struct device *dev) +static int wlan_hdd_pld_runtime_resume(struct device *dev, + enum pld_bus_type bus_type) { - return wlan_hdd_bus_resume(); + return wlan_hdd_runtime_resume(); } -#endif /* HIF_PCI */ - -#ifdef HIF_PCI -static struct pci_device_id wlan_hdd_pci_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 - -#ifdef FEATURE_RUNTIME_PM -struct cnss_wlan_runtime_ops runtime_pm_ops = { - .runtime_suspend = wlan_hdd_pci_runtime_suspend, - .runtime_resume = wlan_hdd_pci_runtime_resume, -}; #endif -struct cnss_wlan_driver wlan_drv_ops = { - .name = "wlan_hdd_pci", - .id_table = wlan_hdd_pci_id_table, - .probe = wlan_hdd_pci_probe, - .remove = wlan_hdd_pci_remove, - .reinit = wlan_hdd_pci_reinit, - .shutdown = wlan_hdd_pci_shutdown, - .crash_shutdown = wlan_hdd_pci_crash_shutdown, - .modem_status = wlan_hdd_pci_notify_handler, -#ifdef ATH_BUS_PM - .suspend = wlan_hdd_pci_suspend, - .resume = wlan_hdd_pci_resume, -#endif /* ATH_BUS_PM */ +struct pld_driver_ops wlan_drv_ops = { + .probe = wlan_hdd_pld_probe, + .remove = wlan_hdd_pld_remove, + .shutdown = wlan_hdd_pld_shutdown, + .reinit = wlan_hdd_pld_reinit, + .crash_shutdown = wlan_hdd_pld_crash_shutdown, + .suspend = wlan_hdd_pld_suspend, + .resume = wlan_hdd_pld_resume, + .modem_status = wlan_hdd_pld_notify_handler, #ifdef FEATURE_RUNTIME_PM - .runtime_ops = &runtime_pm_ops, + .runtime_suspend = wlan_hdd_pld_runtime_suspend, + .runtime_resume = wlan_hdd_pld_runtime_resume, #endif }; -#else -MODULE_DEVICE_TABLE(pci, wlan_hdd_pci_id_table); -struct pci_driver wlan_drv_ops = { - .name = "wlan_hdd_pci", - .id_table = wlan_hdd_pci_id_table, - .probe = wlan_hdd_pci_probe, - .remove = wlan_hdd_pci_remove, -#ifdef ATH_BUS_PM - .suspend = wlan_hdd_pci_suspend, - .resume = wlan_hdd_pci_resume, -#endif /* ATH_BUS_PM */ - -}; -#endif /* CONFIG_CNSS */ -#else -struct icnss_driver_ops wlan_drv_ops = { - .name = "wlan_hdd_drv", - .probe = wlan_hdd_snoc_probe, - .remove = wlan_hdd_snoc_remove, - .shutdown = wlan_hdd_snoc_shutdown, - .reinit = wlan_hdd_snoc_reinit, - .crash_shutdown = wlan_hdd_snoc_crash_shutdown, - .suspend = wlan_hdd_snoc_suspend, - .resume = wlan_hdd_snoc_resume, -}; -#endif /** * wlan_hdd_register_driver() - wlan_hdd_register_driver @@ -1060,7 +976,7 @@ struct icnss_driver_ops wlan_drv_ops = { */ int wlan_hdd_register_driver(void) { - return WLAN_HDD_REGISTER_DRIVER(&wlan_drv_ops); + return pld_register_driver(&wlan_drv_ops); } /** @@ -1070,5 +986,5 @@ int wlan_hdd_register_driver(void) */ void wlan_hdd_unregister_driver(void) { - WLAN_HDD_UNREGISTER_DRIVER(&wlan_drv_ops); + pld_unregister_driver(); } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 0cfba34472be..c4f7f9f8488f 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -91,6 +91,7 @@ #include "cds_regdomain.h" #include "cdp_txrx_flow_ctrl_v2.h" #endif /* FEATURE_WLAN_CH_AVOID */ +#include "pld_common.h" #include "wlan_hdd_ocb.h" #include "wlan_hdd_nan.h" #include "wlan_hdd_debugfs.h" @@ -7287,6 +7288,8 @@ static int __hdd_module_init(void) pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR); + pld_init(); + qdf_wake_lock_create(&wlan_wake_lock, "wlan"); hdd_set_conparam((uint32_t) con_mode); @@ -7302,6 +7305,7 @@ static int __hdd_module_init(void) return 0; out: qdf_wake_lock_destroy(&wlan_wake_lock); + pld_deinit(); return ret; } @@ -7319,6 +7323,8 @@ static void __hdd_module_exit(void) qdf_wake_lock_destroy(&wlan_wake_lock); + pld_deinit(); + return; } -- cgit v1.2.3 From 7f63d05a487b0fec49b675cd3c4cdab10782e0a4 Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Sat, 7 May 2016 09:54:00 +0530 Subject: qcacld-3.0: Initialize spinlocks used for STA and SAP information update qcacld-2.0 to qcacld-3.0 propagation Initialize spinlocks sap_update_info_lock and sta_update_info_lock which are used during SAP and STA information update respectively. These uninitialized spinlocks lead to crash during access due to bad magic value of the spinlock. Change-Id: I7d2df8337f9feed352430774907aa095affa5a69 CRs-Fixed: 1011996 --- core/cds/src/cds_concurrency.c | 16 ++++++++-------- core/hdd/inc/wlan_hdd_main.h | 4 ++-- core/hdd/src/wlan_hdd_hostapd.c | 7 +++++-- core/hdd/src/wlan_hdd_main.c | 7 ++++++- core/hdd/src/wlan_hdd_scan.c | 1 + 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index 0c11fdbeda44..bf67f59c75c2 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -1927,9 +1927,9 @@ bool cds_is_sta_connection_pending(void) return false; } - spin_lock(&hdd_ctx->sta_update_info_lock); + qdf_spin_lock(&hdd_ctx->sta_update_info_lock); status = hdd_ctx->is_sta_connection_pending; - spin_unlock(&hdd_ctx->sta_update_info_lock); + qdf_spin_unlock(&hdd_ctx->sta_update_info_lock); return status; } @@ -1952,9 +1952,9 @@ void cds_change_sta_conn_pending_status(bool value) return; } - spin_lock(&hdd_ctx->sta_update_info_lock); + qdf_spin_lock(&hdd_ctx->sta_update_info_lock); hdd_ctx->is_sta_connection_pending = value; - spin_unlock(&hdd_ctx->sta_update_info_lock); + qdf_spin_unlock(&hdd_ctx->sta_update_info_lock); } /** @@ -1976,9 +1976,9 @@ static bool cds_is_sap_restart_required(void) return false; } - spin_lock(&hdd_ctx->sap_update_info_lock); + qdf_spin_lock(&hdd_ctx->sap_update_info_lock); status = hdd_ctx->is_sap_restart_required; - spin_unlock(&hdd_ctx->sap_update_info_lock); + qdf_spin_unlock(&hdd_ctx->sap_update_info_lock); return status; } @@ -2001,9 +2001,9 @@ void cds_change_sap_restart_required_status(bool value) return; } - spin_lock(&hdd_ctx->sap_update_info_lock); + qdf_spin_lock(&hdd_ctx->sap_update_info_lock); hdd_ctx->is_sap_restart_required = value; - spin_unlock(&hdd_ctx->sap_update_info_lock); + qdf_spin_unlock(&hdd_ctx->sap_update_info_lock); } /** diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index f8a3837b13ee..cdd77891d7e1 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1320,8 +1320,8 @@ struct hdd_context_s { struct work_struct sap_start_work; bool is_sap_restart_required; bool is_sta_connection_pending; - spinlock_t sap_update_info_lock; - spinlock_t sta_update_info_lock; + qdf_spinlock_t sap_update_info_lock; + qdf_spinlock_t sta_update_info_lock; uint8_t dev_dfs_cac_status; diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 0cb38a44674e..bf0cb5c310ba 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -116,6 +116,7 @@ int hdd_sap_context_init(hdd_context_t *hdd_ctx) mutex_init(&hdd_ctx->sap_lock); qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock"); + qdf_spinlock_create(&hdd_ctx->sap_update_info_lock); mutex_init(&hdd_ctx->dfs_lock); @@ -220,6 +221,8 @@ void hdd_sap_context_destroy(hdd_context_t *hdd_ctx) mutex_destroy(&hdd_ctx->dfs_lock); + qdf_spinlock_destroy(&hdd_ctx->sap_update_info_lock); + } /** @@ -8161,9 +8164,9 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, (QDF_SAP_MODE == pAdapter->device_mode)) { cds_flush_work(&pHddCtx->sap_start_work); hddLog(LOGW, FL("Canceled the pending restart work")); - spin_lock(&pHddCtx->sap_update_info_lock); + qdf_spin_lock(&pHddCtx->sap_update_info_lock); pHddCtx->is_sap_restart_required = false; - spin_unlock(&pHddCtx->sap_update_info_lock); + qdf_spin_unlock(&pHddCtx->sap_update_info_lock); } pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false; if (pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list) diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index c4f7f9f8488f..eb70039025e4 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -4183,6 +4183,10 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx) QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status)); } + qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock); + qdf_spinlock_destroy(&hdd_ctx->sta_update_info_lock); + qdf_spinlock_destroy(&hdd_ctx->connection_status_lock); + /* * Close CDS * This frees pMac(HAL) context. There should not be any call @@ -5484,8 +5488,9 @@ static int hdd_context_init(hdd_context_t *hdd_ctx) hdd_init_bpf_completion(); qdf_spinlock_create(&hdd_ctx->connection_status_lock); - + qdf_spinlock_create(&hdd_ctx->sta_update_info_lock); qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock); + qdf_list_create(&hdd_ctx->hddAdapters, MAX_NUMBER_OF_ADAPTERS); init_completion(&hdd_ctx->set_antenna_mode_cmpl); diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index b4d68c59042e..bd7e301c2acd 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -2502,6 +2502,7 @@ void hdd_cleanup_scan_queue(hdd_context_t *hdd_ctx) void hdd_scan_context_destroy(hdd_context_t *hdd_ctx) { qdf_list_destroy(&hdd_ctx->hdd_scan_req_q); + qdf_spinlock_destroy(&hdd_ctx->sched_scan_lock); } /** -- cgit v1.2.3 From dd2075b37525443f334f8f571c7a57feba2f5342 Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Fri, 30 Oct 2015 13:05:27 +0530 Subject: qcacld-3.0: TL cleanup is not invoked for TDLS CONNECTING state qcacld-2.0 to qcacld-3.0 propagation When TDLS peer link state is in connecting state; at the time of DISABLE link from upper layer driver is not doing TL cleanup for connecting state. Fix this issue by cleaning up for connecting state as well. Change-Id: Ib97128b96ca13569f8d247e3eaa3c86938e426d1 CRs-Fixed: 773076 --- core/hdd/src/wlan_hdd_assoc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index ecca88729eaa..6bd256cd88e8 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -3172,13 +3172,22 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter, pRoamInfo-> peerMac.bytes, true); - if (NULL != curr_peer - && TDLS_IS_CONNECTED(curr_peer)) { + if (NULL != curr_peer) { + hdd_info("Current status for peer " MAC_ADDRESS_STR " is %d", + MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes), + curr_peer->link_status); + if (TDLS_IS_CONNECTED(curr_peer)) { hdd_roam_deregister_tdlssta (pAdapter, pRoamInfo->staId); wlan_hdd_tdls_decrement_peer_count (pAdapter); + } else if (eTDLS_LINK_CONNECTING == + curr_peer->link_status) { + hdd_roam_deregister_tdlssta + (pAdapter, + pRoamInfo->staId); + } } wlan_hdd_tdls_reset_peer(pAdapter, pRoamInfo-> -- cgit v1.2.3 From 81f3cd479b79585fe3ad9c00b54f7ba17f171b04 Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Wed, 16 Sep 2015 16:35:13 +0530 Subject: qcacld-3.0: Correct log level qcacld-2.0 to qcacld-3.0 propagation Correct log level to avoid excessive logging in wlan_hdd_tdls_exit() Change-Id: Idfde282fe5167c245a3193466db05d73550a7bb4 CRs-Fixed: 637990 --- core/hdd/src/wlan_hdd_tdls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index 03d233bf1674..a23b701faa47 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -831,7 +831,7 @@ void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter) pHddCtx = WLAN_HDD_GET_CTX(pAdapter); if (!pHddCtx) { - QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, FL("pHddCtx is NULL")); return; } -- cgit v1.2.3 From bb09f5eca15d75337874693888a5ecab0411bbd6 Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Wed, 16 Sep 2015 16:39:29 +0530 Subject: qcacld-3.0: Remove redundant logs qcacld-2.0 to qcacld-3.0 propagation Some logs while Processing netlink messages are excessive. Remove these redundant logs. Change-Id: Ic5104e6fb2d306b488adf2a3919e004e5b57e186 CRs-Fixed: 879049 --- core/utils/nlink/src/wlan_nlink_srv.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/utils/nlink/src/wlan_nlink_srv.c b/core/utils/nlink/src/wlan_nlink_srv.c index 80055a64f656..d3b56faef10b 100644 --- a/core/utils/nlink/src/wlan_nlink_srv.c +++ b/core/utils/nlink/src/wlan_nlink_srv.c @@ -258,9 +258,6 @@ static void nl_srv_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return; } - QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO, - "NLINK: Received NL msg type [%d]", type); - /* turn type into dispatch table offset */ type -= WLAN_NL_MSG_BASE; -- cgit v1.2.3 From a5c2bdc4a7399533dc1a7d7730e93dece8a6b54c Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Wed, 16 Sep 2015 16:58:41 +0530 Subject: qcacld-3.0: Modify TDLS log for link setup/Teardown qcacld-2.0 to qcacld-3.0 propagation As a part of logging improvement, modify redundant logs, change certain log levels in TDLS link setup/ teardown path to make logs more useful. Change-Id: Ibb0ee1edb5bbb1aed57bccbc15354031b0362198 CRs-Fixed: 861452 --- core/hdd/src/wlan_hdd_tdls.c | 3 ++- core/sme/src/csr/csr_tdls_process.c | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index a23b701faa47..a0077b4b106c 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -2962,6 +2962,7 @@ void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter, wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_TEARING, eTDLS_LINK_UNSPECIFIED); + hdd_info("Teardown reason %d", reason); cfg80211_tdls_oper_request(pAdapter->dev, curr_peer->peerMac, NL80211_TDLS_TEARDOWN, reason, GFP_KERNEL); @@ -4614,7 +4615,7 @@ static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, return -ENOTSUPP; default: QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, - "%s: unsupported event", __func__); + "%s: unsupported event %d", __func__, oper); return -ENOTSUPP; } EXIT(); diff --git a/core/sme/src/csr/csr_tdls_process.c b/core/sme/src/csr/csr_tdls_process.c index d6baf4ea1525..bfd589fb4b6d 100644 --- a/core/sme/src/csr/csr_tdls_process.c +++ b/core/sme/src/csr/csr_tdls_process.c @@ -129,6 +129,8 @@ QDF_STATUS csr_tdls_send_mgmt_req(tHalHandle hHal, uint8_t sessionId, tdlsSendMgmtCmd->u.tdlsCmd.size = sizeof(tTdlsSendMgmtCmdInfo); sme_push_command(pMac, tdlsSendMgmtCmd, false); status = QDF_STATUS_SUCCESS; + sms_log(pMac, LOG1, + FL("Successfully posted eSmeCommandTdlsSendMgmt to SME")); return status; } @@ -201,6 +203,8 @@ QDF_STATUS csr_tdls_change_peer_sta(tHalHandle hHal, uint8_t sessionId, sizeof(tTdlsAddStaCmdInfo); sme_push_command(pMac, tdlsAddStaCmd, false); status = QDF_STATUS_SUCCESS; + sms_log(pMac, LOG1, + FL("Successfully posted eSmeCommandTdlsAddPeer to SME to modify peer ")); } } @@ -271,6 +275,8 @@ QDF_STATUS csr_tdls_send_link_establish_params(tHalHandle hHal, sizeof(tTdlsLinkEstablishCmdInfo); sme_push_command(pMac, tdlsLinkEstablishCmd, false); status = QDF_STATUS_SUCCESS; + sms_log(pMac, LOG1, + FL("Successfully posted eSmeCommandTdlsLinkEstablish to SME")); } } @@ -308,6 +314,8 @@ QDF_STATUS csr_tdls_add_peer_sta(tHalHandle hHal, uint8_t sessionId, sizeof(tTdlsAddStaCmdInfo); sme_push_command(pMac, tdlsAddStaCmd, false); status = QDF_STATUS_SUCCESS; + sms_log(pMac, LOG1, + FL("Successfully posted eSmeCommandTdlsAddPeer to SME")); } } @@ -344,6 +352,8 @@ QDF_STATUS csr_tdls_del_peer_sta(tHalHandle hHal, uint8_t sessionId, sizeof(tTdlsDelStaCmdInfo); sme_push_command(pMac, tdlsDelStaCmd, false); status = QDF_STATUS_SUCCESS; + sms_log(pMac, LOG1, + FL("Successfully posted eSmeCommandTdlsDelPeer to SME")); } } @@ -423,7 +433,7 @@ QDF_STATUS csr_tdls_process_send_mgmt(tpAniSirGlobal pMac, tSmeCmd *cmd) } /* Send the request to PE. */ - sms_log(pMac, LOG1, "sending TDLS Mgmt Frame req to PE "); + sms_log(pMac, LOG1, FL("sending TDLS Mgmt Frame req to PE ")); status = tdls_send_message(pMac, eWNI_SME_TDLS_SEND_MGMT_REQ, (void *)tdlsSendMgmtReq, sizeof(tSirTdlsSendMgmtReq) + -- cgit v1.2.3 From c38e58df1924b97952336d91cd47a58c30f09373 Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Wed, 16 Sep 2015 17:17:29 +0530 Subject: qcacld-3.0: Remove redundant logs qcacld-2.0 to qcacld-3.0 propagation Some logs are excessive and unnecessary. Remove/modify these redundant logs. Change-Id: Ia7286612d81df3bbb266ba217f548516fa38d3de CRs-Fixed: 885880 --- core/hdd/src/wlan_hdd_p2p.c | 4 +--- core/hdd/src/wlan_hdd_scan.c | 1 - core/mac/src/pe/lim/lim_process_mlm_req_messages.c | 2 -- core/mac/src/pe/lim/lim_send_management_frames.c | 18 ++++++++++++++++++ core/mac/src/pe/lim/lim_send_sme_rsp_messages.c | 3 --- core/mac/src/sys/legacy/src/utils/src/parser_api.c | 9 --------- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index ebdb11f0bfc1..89a25740cde6 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -206,9 +206,7 @@ QDF_STATUS wlan_hdd_remain_on_channel_callback(tHalHandle hHal, void *pCtx, if (REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request) { if (cfgState->buf) { - hddLog(LOGP, - "%s: We need to receive yet an ack from one of tx packet", - __func__); + hdd_info("We need to receive yet an ack from one of tx packet"); } cfg80211_remain_on_channel_expired( pRemainChanCtx->dev-> diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index bd7e301c2acd..b2c367d03288 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -1386,7 +1386,6 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, qdf_mem_zero(&scan_req, sizeof(scan_req)); - hddLog(LOG1, "scan request for ssid = %d", request->n_ssids); scan_req.timestamp = qdf_mc_timer_get_system_ticks(); /* Even though supplicant doesn't provide any SSIDs, n_ssids is diff --git a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c index d57a1ca3735e..897f3621a52e 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c @@ -315,7 +315,6 @@ void lim_set_dfs_channel_list(tpAniSirGlobal mac_ctx, uint8_t chan_num, dfs_ch_list->timeStamp[chan_num] = qdf_mc_timer_get_system_time(); } else { - lim_log(mac_ctx, LOG1, FL("Channel %d is Active"), chan_num); return; } @@ -2309,7 +2308,6 @@ static void lim_process_periodic_probe_req_timer(tpAniSirGlobal mac_ctx) } mlm_scan_req = mac_ctx->lim.gpLimMlmScanReq; - lim_log(mac_ctx, LOG1, FL("Scanning : Periodic scanning")); mac_ctx->lim.probeCounter++; /* Periodic channel timer timed out to send probe request. */ channel_num = lim_get_current_scan_channel(mac_ctx); diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c index 757ffe9d827c..683a5201b211 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -1207,6 +1207,15 @@ lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx, populate_dot11f_ht_info(mac_ctx, &frm.HTInfo, pe_session); } + lim_log(mac_ctx, LOG1, + FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x"), + frm.HTCaps.supportedChannelWidthSet, + frm.HTCaps.mimoPowerSave, + frm.HTCaps.greenField, frm.HTCaps.shortGI20MHz, + frm.HTCaps.shortGI40MHz, + frm.HTCaps.dsssCckMode40MHz, + frm.HTCaps.maxRxAMPDUFactor); + if (sta->mlmStaContext.vhtCapability && pe_session->vhtCapability) { lim_log(mac_ctx, LOG1, @@ -1761,6 +1770,15 @@ lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx, lim_log(mac_ctx, LOG1, FL("Populate HT Caps in Assoc Request")); populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps); } + lim_log(mac_ctx, LOG1, + FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x"), + frm->HTCaps.supportedChannelWidthSet, + frm->HTCaps.mimoPowerSave, + frm->HTCaps.greenField, frm->HTCaps.shortGI20MHz, + frm->HTCaps.shortGI40MHz, + frm->HTCaps.dsssCckMode40MHz, + frm->HTCaps.maxRxAMPDUFactor); + if (pe_session->vhtCapability && pe_session->vhtCapabilityPresentInBeacon) { lim_log(mac_ctx, LOG1, FL("Populate VHT IEs in Assoc Request")); diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c index 0f87a6dc6874..d61aeb308648 100644 --- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c @@ -700,9 +700,6 @@ lim_send_sme_scan_rsp(tpAniSirGlobal pMac, tSirResultCodes resultCode, uint8_t smesessionId, uint16_t smetranscationId, uint32_t scan_id) { - lim_log(pMac, LOG1, - FL("Sending message SME_SCAN_RSP reasonCode %s scanId %d"), - lim_result_code_str(resultCode), scan_id); lim_post_sme_scan_rsp_message(pMac, resultCode, smesessionId, smetranscationId, scan_id); } diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 550443955588..517ab64d249d 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -747,13 +747,6 @@ populate_dot11f_ht_caps(tpAniSirGlobal pMac, pDot11f->shortGI40MHz = 0; } - dot11f_log(pMac, LOG2, - FL - ("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d\n"), - pDot11f->supportedChannelWidthSet, pDot11f->mimoPowerSave, - pDot11f->greenField, pDot11f->shortGI20MHz, - pDot11f->shortGI40MHz, pDot11f->dsssCckMode40MHz); - CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_AMPDU_PARAMS, nCfgValue); nCfgValue8 = (uint8_t) nCfgValue; @@ -763,8 +756,6 @@ populate_dot11f_ht_caps(tpAniSirGlobal pMac, pDot11f->mpduDensity = pHTParametersInfo->mpduDensity; pDot11f->reserved1 = pHTParametersInfo->reserved; - dot11f_log(pMac, LOG2, FL("AMPDU Param: %x\n"), nCfgValue); - CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SUPPORTED_MCS_SET, pDot11f->supportedMCSSet, nCfgLen, SIZE_OF_SUPPORTED_MCS_SET); -- cgit v1.2.3 From 02460a80c695c91d01c55df44ac94cd6c3d7ccd2 Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Wed, 16 Sep 2015 17:20:30 +0530 Subject: qcacld-3.0: Add INFO logs in mcast/bcast filtering code qcacld-2.0 to qcacld-3.0 propagation Add info level logs for ARP, NS offload. Change-Id: I65943d4428f724c39142d1371c04541fcaba7d83 CRs-Fixed: 880526 --- core/hdd/src/wlan_hdd_power.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 117413611818..7346aa087605 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -860,6 +860,7 @@ static void hdd_mcbc_filter_modification(hdd_context_t *pHddCtx, * of Broadcast BIT */ *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST); + hdd_info("ARP offload is enabled"); } #ifdef WLAN_NS_OFFLOAD if (pHddCtx->config->fhostNSOffload) { @@ -868,6 +869,7 @@ static void hdd_mcbc_filter_modification(hdd_context_t *pHddCtx, * disable Multicast filtering, Anding with the negation * of Multicast BIT */ + hdd_info("NS offload is enabled"); *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST); } #endif -- cgit v1.2.3 From 0f94b570ed90716a7573dbcba3e1654ed0ea8322 Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Mon, 22 Feb 2016 13:27:06 +0530 Subject: qcacld-3.0: Dont include ext caps in Assoc request if AP doesn't support qcacld-2.0 to qcacld-3.0 propagation Some AP doesn't announce Extended Capabilities IE in Probe Response. Device should not send extended Capabilities if AP doesn't support. Change-Id: I53215b866cb90f4addf45e3b6ed8af435eb57842 CRs-Fixed: 930199 --- core/mac/src/include/parser_api.h | 1 + core/mac/src/pe/include/lim_session.h | 1 + core/mac/src/pe/lim/lim_prop_exts_utils.c | 3 +++ core/mac/src/pe/lim/lim_send_management_frames.c | 9 ++++++--- core/mac/src/sys/legacy/src/utils/src/parser_api.c | 5 +++++ 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/core/mac/src/include/parser_api.h b/core/mac/src/include/parser_api.h index f48aac5c416f..4a99241f7304 100644 --- a/core/mac/src/include/parser_api.h +++ b/core/mac/src/include/parser_api.h @@ -148,6 +148,7 @@ typedef struct sSirProbeRespBeacon { tDot11fIEVHTCaps VHTCaps; tDot11fIEVHTOperation VHTOperation; tDot11fIEVHTExtBssLoad VHTExtBssLoad; + tDot11fIEExtCap ext_cap; tDot11fIEOperatingMode OperatingMode; uint8_t WiderBWChanSwitchAnnPresent; tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn; diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index 483c9bd77768..779070b6ed12 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -475,6 +475,7 @@ typedef struct sPESession /* Added to Support BT-AMP */ struct obss_scanparam obss_ht40_scanparam; /* Supported NSS is intersection of self and peer NSS */ bool supported_nss_1x1; + bool is_ext_caps_present; } tPESession, *tpPESession; /*------------------------------------------------------------------------- diff --git a/core/mac/src/pe/lim/lim_prop_exts_utils.c b/core/mac/src/pe/lim/lim_prop_exts_utils.c index 8961a2c9b411..869706e327f1 100644 --- a/core/mac/src/pe/lim/lim_prop_exts_utils.c +++ b/core/mac/src/pe/lim/lim_prop_exts_utils.c @@ -215,6 +215,9 @@ lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie, if (beacon_struct->countryInfoPresent) session->country_info_present = true; } + /* Check if Extended caps are present in probe resp or not */ + if (beacon_struct->ext_cap.present) + session->is_ext_caps_present = true; qdf_mem_free(beacon_struct); return; } /****** end lim_extract_ap_capability() ******/ diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c index 683a5201b211..ef138b90b7d6 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -1623,7 +1623,7 @@ lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx, qdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0); - if (add_ie_len) { + if (add_ie_len && pe_session->is_ext_caps_present) { qdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap), 0); sir_status = lim_strip_extcap_update_struct(mac_ctx, @@ -1651,7 +1651,8 @@ lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx, } } } else { - lim_log(mac_ctx, LOG1, FL("No additional IE for Assoc Req")); + lim_log(mac_ctx, LOG1, + FL("No addn IE or peer dosen't support addnIE for Assoc Req")); extr_ext_flag = false; } @@ -1800,7 +1801,9 @@ lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx, &frm->vendor2_ie.VHTCaps); vht_enabled = true; } - populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm->ExtCap, pe_session); + if (pe_session->is_ext_caps_present) + populate_dot11f_ext_cap(mac_ctx, vht_enabled, + &frm->ExtCap, pe_session); if (pe_session->pLimJoinReq->is11Rconnection) { tSirBssDescription *bssdescr; diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 517ab64d249d..8063d79d0c31 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -3647,6 +3647,11 @@ sir_parse_beacon_ie(tpAniSirGlobal pMac, &pBies->vendor2_ie.VHTOperation, sizeof(tDot11fIEVHTOperation)); } + if (pBies->ExtCap.present) { + pBeaconStruct->ext_cap.present = 1; + qdf_mem_copy(&pBeaconStruct->ext_cap, &pBies->ExtCap, + sizeof(tDot11fIEExtCap)); + } qdf_mem_free(pBies); return eSIR_SUCCESS; } /* End sir_parse_beacon_ie. */ -- cgit v1.2.3 From 6b01576aa836b17dec0c545102ab695378f74f24 Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Thu, 5 May 2016 11:22:18 +0530 Subject: qcacld-3.0: Change conn_state to connecting before sme_roam_connect qcacld-2.0 to qcacld-3.0 propagation sme_roam_connect() has a direct path to call hdd_sme_roam_callback(), which will change the conn_state. If direct path, conn_state will be accordingly changed to NotConnected or Associated. Driver is not changing connection state to eConnectionState_Connecting when connecting with iwconfig. If connection state is not changed, connection state will remain in eConnectionState_NotConnected state. In hdd_association_completion_handler, "hddDisconInProgress" is set to true if conn state is eConnectionState_NotConnected. If "hddDisconInProgress" is set to true then cfg80211 layer is not informed of connect result indication which is an issue. Change-Id: Ieeaef582a04aa90ddcdcc373b00b68442c795337 CRs-Fixed: 900008 --- core/hdd/src/wlan_hdd_assoc.c | 33 +++++++++++++++++++++++++++++++++ core/hdd/src/wlan_hdd_cfg80211.c | 40 ++++++++++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 6bd256cd88e8..d1464e4d5eb6 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -5001,8 +5001,41 @@ static int __iw_set_essid(struct net_device *dev, (WLAN_HDD_GET_CTX(pAdapter))->config-> AdHocChannel5G); } + /* + * Change conn_state to connecting before sme_roam_connect(), + * because sme_roam_connect() has a direct path to call + * hdd_sme_roam_callback(), which will change the conn_state + * If direct path, conn_state will be accordingly changed to + * NotConnected or Associated by either + * hdd_association_completion_handler() or hdd_dis_connect_handler() + * in sme_RoamCallback()if sme_RomConnect is to be queued, + * Connecting state will remain until it is completed. + * + * If connection state is not changed, + * connection state will remain in eConnectionState_NotConnected state. + * In hdd_association_completion_handler, "hddDisconInProgress" is + * set to true if conn state is eConnectionState_NotConnected. + * If "hddDisconInProgress" is set to true then cfg80211 layer is not + * informed of connect result indication which is an issue. + */ + if (QDF_STA_MODE == pAdapter->device_mode || + QDF_P2P_CLIENT_MODE == pAdapter->device_mode) { + hdd_info("Set HDD connState to eConnectionState_Connecting"); + hdd_conn_set_connection_state(pAdapter, + eConnectionState_Connecting); + } + status = sme_roam_connect(hHal, pAdapter->sessionId, &(pWextState->roamProfile), &roamId); + if ((QDF_STATUS_SUCCESS != status) && + (QDF_STA_MODE == pAdapter->device_mode || + QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) { + hdd_err("sme_roam_connect (session %d) failed with status %d. -> NotConnected", + pAdapter->sessionId, status); + /* change back to NotAssociated */ + hdd_conn_set_connection_state(pAdapter, + eConnectionState_NotConnected); + } pRoamProfile->ChannelInfo.ChannelList = NULL; pRoamProfile->ChannelInfo.numOfChannels = 0; diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 19b32c755594..1a21f97ae2f9 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -8583,20 +8583,6 @@ int wlan_hdd_cfg80211_connect_start(hdd_adapter_t *pAdapter, return -EINVAL; } - /* change conn_state to connecting before sme_roam_connect(), because sme_roam_connect() - * has a direct path to call hdd_sme_roam_callback(), which will change the conn_state - * If direct path, conn_state will be accordingly changed to NotConnected or Associated - * by either hdd_association_completion_handler() or hdd_dis_connect_handler() in sme_RoamCallback() - * if sme_RomConnect is to be queued, Connecting state will remain until it is completed. - */ - if (QDF_STA_MODE == pAdapter->device_mode || - QDF_P2P_CLIENT_MODE == pAdapter->device_mode) { - hddLog(LOG1, - FL("Set HDD connState to eConnectionState_Connecting")); - hdd_conn_set_connection_state(pAdapter, - eConnectionState_Connecting); - } - /* After 8-way handshake supplicant should give the scan command * in that it update the additional IEs, But because of scan * enhancements, the supplicant is not issuing the scan command now. @@ -8652,6 +8638,32 @@ int wlan_hdd_cfg80211_connect_start(hdd_adapter_t *pAdapter, pHddCtx->config->nChannelBondingMode24GHz; sme_update_config(pHddCtx->hHal, sme_config); qdf_mem_free(sme_config); + /* + * Change conn_state to connecting before sme_roam_connect(), + * because sme_roam_connect() has a direct path to call + * hdd_sme_roam_callback(), which will change the conn_state + * If direct path, conn_state will be accordingly changed to + * NotConnected or Associated by either + * hdd_association_completion_handler() or + * hdd_dis_connect_handler() in sme_RoamCallback()if + * sme_RomConnect is to be queued, + * Connecting state will remain until it is completed. + * + * If connection state is not changed, connection state will + * remain in eConnectionState_NotConnected state. + * In hdd_association_completion_handler, "hddDisconInProgress" + * is set to true if conn state is + * eConnectionState_NotConnected. + * If "hddDisconInProgress" is set to true then cfg80211 layer + * is not informed of connect result indication which + * is an issue. + */ + if (QDF_STA_MODE == pAdapter->device_mode || + QDF_P2P_CLIENT_MODE == pAdapter->device_mode) { + hdd_info("Set HDD connState to eConnectionState_Connecting"); + hdd_conn_set_connection_state(pAdapter, + eConnectionState_Connecting); + } status = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, pRoamProfile, -- cgit v1.2.3 From 17bb3908dae2310d6cd822fd2e2802fe18df1016 Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Thu, 5 May 2016 13:29:40 +0530 Subject: qcacld-3.0: Ini change for dyanmic min_rest_time and idle_time qcacld-2.0 to qcacld-3.0 propagation Currently default min_rest_time, max_rest_time and idle_time are 50, 100 and 25 respectively. When STA is connected in default behavior, DUT will stay on home channel for 50 ms, then check traffic at every 25 ms increments. If no traffic, then it will move to the next channel. It will stay on home channel for max 100 ms. So 75 and 100 are the possible max_rest_time values. If idle_time is reduced to lower value, better throughput is possible as DUT need not to wait on same channel for data inactivity. Introduced ini params to configure min_rest_time & idle_time. Change-Id: If28b7a30147fc11c67817314021fa502d2d8f5ad CRs-Fixed: 952151 --- core/hdd/inc/wlan_hdd_cfg.h | 23 +++++++++++++++++++++ core/hdd/src/wlan_hdd_cfg.c | 23 +++++++++++++++++++++ core/mac/inc/sir_api.h | 8 ++++++++ core/mac/src/pe/lim/lim_process_sme_req_messages.c | 2 ++ core/sme/inc/csr_api.h | 12 ++++++++++- core/sme/inc/csr_internal.h | 12 ++++++++++- core/sme/src/csr/csr_api_roam.c | 13 ++++++++---- core/sme/src/csr/csr_api_scan.c | 24 +++++++++++++++++++--- core/sme/src/csr/csr_inside_api.h | 2 ++ core/wma/src/wma_scan_roam.c | 14 +++++++------ 10 files changed, 118 insertions(+), 15 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 39f0f2d014bd..10b6c72a8331 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -463,6 +463,25 @@ typedef enum { #define CFG_REST_TIME_CONC_MAX (10000) #define CFG_REST_TIME_CONC_DEFAULT (100) +/* Mininum time spent on home channel before moving to a new channel to scan */ +#define CFG_MIN_REST_TIME_NAME "gMinRestTimeConc" +#define CFG_MIN_REST_TIME_MIN (0) +#define CFG_MIN_REST_TIME_MAX (50) +#define CFG_MIN_REST_TIME_DEFAULT (50) + +/* Data inactivity time in msec on bss channel that will be used + * by scan engine in firmware. + * for example if this value is 25ms then firmware will check for + * data inactivity every 25ms till gRestTimeConc is reached. + * If inactive then scan engine will move from home channel to + * scan the next frequency. + */ +#define CFG_IDLE_TIME_NAME "gIdleTimeConc" +#define CFG_IDLE_TIME_MIN (0) +#define CFG_IDLE_TIME_MAX (25) +#define CFG_IDLE_TIME_DEFAULT (25) + + #define CFG_NUM_STA_CHAN_COMBINED_CONC_NAME "gNumStaChanCombinedConc" #define CFG_NUM_STA_CHAN_COMBINED_CONC_MIN (1) #define CFG_NUM_STA_CHAN_COMBINED_CONC_MAX (255) @@ -3111,6 +3130,10 @@ struct hdd_config { uint32_t nActiveMinChnTimeConc; /* in units of milliseconds */ uint32_t nActiveMaxChnTimeConc; /* in units of milliseconds */ uint32_t nRestTimeConc; /* in units of milliseconds */ + /* In units of milliseconds */ + uint32_t min_rest_time_conc; + /* In units of milliseconds */ + uint32_t idle_time_conc; uint8_t nNumStaChanCombinedConc; /* number of channels combined for */ /* STA in each split scan operation */ uint8_t nNumP2PChanCombinedConc; /* number of channels combined for */ diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 6cf3949a18dc..e5a3164a9443 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -803,6 +803,20 @@ REG_TABLE_ENTRY g_registry_table[] = { CFG_REST_TIME_CONC_MIN, CFG_REST_TIME_CONC_MAX), + REG_VARIABLE(CFG_MIN_REST_TIME_NAME, WLAN_PARAM_Integer, + struct hdd_config, min_rest_time_conc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MIN_REST_TIME_DEFAULT, + CFG_MIN_REST_TIME_MIN, + CFG_MIN_REST_TIME_MAX), + + REG_VARIABLE(CFG_IDLE_TIME_NAME , WLAN_PARAM_Integer, + struct hdd_config, idle_time_conc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IDLE_TIME_DEFAULT, + CFG_IDLE_TIME_MIN, + CFG_IDLE_TIME_MAX) , + REG_VARIABLE(CFG_NUM_STA_CHAN_COMBINED_CONC_NAME, WLAN_PARAM_Integer, struct hdd_config, nNumStaChanCombinedConc, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -5378,6 +5392,13 @@ void hdd_cfg_print(hdd_context_t *pHddCtx) hdd_info("Name = [%s] Value = [%u]", CFG_ROAM_DENSE_MIN_APS, pHddCtx->config->roam_dense_min_aps); + hdd_info("Name = [%s] Value = [%u]", + CFG_MIN_REST_TIME_NAME, + pHddCtx->config->min_rest_time_conc); + hdd_info("Name = [%s] Value = [%u]", + CFG_IDLE_TIME_NAME, + pHddCtx->config->idle_time_conc); + } @@ -6649,6 +6670,8 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx) smeConfig->csrConfig.nPassiveMinChnTimeConc = pConfig->nPassiveMinChnTimeConc; smeConfig->csrConfig.nRestTimeConc = pConfig->nRestTimeConc; + smeConfig->csrConfig.min_rest_time_conc = pConfig->min_rest_time_conc; + smeConfig->csrConfig.idle_time_conc = pConfig->idle_time_conc; smeConfig->csrConfig.nNumStaChanCombinedConc = pConfig->nNumStaChanCombinedConc; smeConfig->csrConfig.nNumP2PChanCombinedConc = diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 0a58715270b2..7cb2188783c3 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -778,6 +778,10 @@ typedef struct sSirSmeScanReq { */ /* in units of milliseconds, ignored when not connected */ uint32_t restTime; + /*in units of milliseconds, ignored when not connected*/ + uint32_t min_rest_time; + /*in units of milliseconds, ignored when not connected*/ + uint32_t idle_time; uint8_t returnAfterFirstMatch; /** @@ -3583,6 +3587,10 @@ typedef struct sSirScanOffloadReq { uint32_t scan_requestor_id; /* in units of milliseconds, ignored when not connected */ uint32_t restTime; + /*in units of milliseconds, ignored when not connected*/ + uint32_t min_rest_time; + /*in units of milliseconds, ignored when not connected*/ + uint32_t idle_time; tSirP2pScanType p2pScanType; uint16_t uIEFieldLen; uint16_t uIEFieldOffset; diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index be7feaeb14da..7e34ab80affe 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -1298,6 +1298,8 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac, pScanOffloadReq->minChannelTime = pScanReq->minChannelTime; pScanOffloadReq->maxChannelTime = pScanReq->maxChannelTime; pScanOffloadReq->restTime = pScanReq->restTime; + pScanOffloadReq->min_rest_time = pScanReq->min_rest_time; + pScanOffloadReq->idle_time = pScanReq->idle_time; /* for normal scan, the value for p2pScanType should be 0 always */ diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 3b74d5ef9a08..802afc321f1d 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -270,7 +270,12 @@ typedef struct tagCsrScanRequest { tCsrChannelInfo ChannelInfo; uint32_t minChnTime; /* in units of milliseconds */ uint32_t maxChnTime; /* in units of milliseconds */ - uint32_t restTime; /* in units of milliseconds */ + /* In units of milliseconds, ignored when not connected */ + uint32_t restTime; + /* In units of milliseconds, ignored when not connected */ + uint32_t min_rest_time; + /* In units of milliseconds, ignored when not connected */ + uint32_t idle_time; uint32_t uIEFieldLen; uint8_t *pIEField; eCsrRequestType requestType; /* 11d scan or full scan */ @@ -1094,6 +1099,11 @@ typedef struct tagCsrConfigParam { /* number of channels combined for P2P in each split scan operation */ uint8_t nNumP2PChanCombinedConc; #endif + /*In units of milliseconds*/ + uint32_t min_rest_time_conc; + /*In units of milliseconds*/ + uint32_t idle_time_conc; + /* * in dBm, the maximum TX power The actual TX power is the lesser of * this value and 11d. If 11d is disable, the lesser of this and diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index 4ed2c5597b42..17c806f2c585 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -283,7 +283,12 @@ typedef struct tagCsrChannel { typedef struct tagScanProfile { uint32_t minChnTime; uint32_t maxChnTime; - uint32_t restTime; /* This is ignored if not associated */ + /* In units of milliseconds, ignored when not connected */ + uint32_t restTime; + /* In units of milliseconds, ignored when not connected */ + uint32_t min_rest_time; + /* In units of milliseconds, ignored when not connected */ + uint32_t idle_time; uint32_t numOfChannels; uint8_t *pChannelList; tSirScanType scanType; @@ -545,6 +550,11 @@ typedef struct tagCsrConfig { uint32_t nActiveMinChnTimeConc; /* in units of milliseconds */ uint32_t nActiveMaxChnTimeConc; /* in units of milliseconds */ uint32_t nRestTimeConc; /* in units of milliseconds */ + /* In units of milliseconds */ + uint32_t min_rest_time_conc; + /* In units of milliseconds */ + uint32_t idle_time_conc; + /* number of channels combined for Sta in each split scan operation */ uint8_t nNumStaChanCombinedConc; /* number of channels combined for P2P in each split scan operation */ diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 4e921b45b316..0326f313a30c 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -1292,6 +1292,8 @@ static void init_config_param(tpAniSirGlobal pMac) pMac->roam.configParam.nPassiveMinChnTimeConc = CSR_PASSIVE_MIN_CHANNEL_TIME_CONC; pMac->roam.configParam.nRestTimeConc = CSR_REST_TIME_CONC; + pMac->roam.configParam.min_rest_time_conc = CSR_MIN_REST_TIME_CONC; + pMac->roam.configParam.idle_time_conc = CSR_IDLE_TIME_CONC; pMac->roam.configParam.nNumStaChanCombinedConc = CSR_NUM_STA_CHAN_COMBINED_CONC; pMac->roam.configParam.nNumP2PChanCombinedConc = @@ -2057,10 +2059,11 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac, pMac->roam.configParam.nPassiveMinChnTimeConc = pParam->nPassiveMinChnTimeConc; } - if (pParam->nRestTimeConc) { - pMac->roam.configParam.nRestTimeConc = - pParam->nRestTimeConc; - } + pMac->roam.configParam.nRestTimeConc = pParam->nRestTimeConc; + pMac->roam.configParam.min_rest_time_conc = + pParam->min_rest_time_conc; + pMac->roam.configParam.idle_time_conc = pParam->idle_time_conc; + if (pParam->nNumStaChanCombinedConc) { pMac->roam.configParam.nNumStaChanCombinedConc = pParam->nNumStaChanCombinedConc; @@ -2400,6 +2403,8 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam) pParam->nPassiveMaxChnTimeConc = cfg_params->nPassiveMaxChnTimeConc; pParam->nPassiveMinChnTimeConc = cfg_params->nPassiveMinChnTimeConc; pParam->nRestTimeConc = cfg_params->nRestTimeConc; + pParam->min_rest_time_conc = cfg_params->min_rest_time_conc; + pParam->idle_time_conc = cfg_params->idle_time_conc; pParam->nNumStaChanCombinedConc = cfg_params->nNumStaChanCombinedConc; pParam->nNumP2PChanCombinedConc = cfg_params->nNumP2PChanCombinedConc; #endif diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index dd76c63f3ebc..299fb641d367 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -256,6 +256,11 @@ static void csr_set_default_scan_timing(tpAniSirGlobal pMac, tSirScanType scanTy } pScanRequest->restTime = pMac->roam.configParam.nRestTimeConc; + pScanRequest->min_rest_time = + pMac->roam.configParam.min_rest_time_conc; + pScanRequest->idle_time = + pMac->roam.configParam.idle_time_conc; + /* Return so that fields set above will not be overwritten. */ return; } @@ -278,8 +283,12 @@ static void csr_set_default_scan_timing(tpAniSirGlobal pMac, tSirScanType scanTy pMac->roam.configParam.nPassiveMinChnTime; } #ifdef WLAN_AP_STA_CONCURRENCY - /* No rest time if no sessions are connected. */ + + /* No rest time/Idle time if no sessions are connected. */ pScanRequest->restTime = 0; + pScanRequest->min_rest_time = 0; + pScanRequest->idle_time = 0; + #endif } @@ -546,9 +555,14 @@ QDF_STATUS csr_scan_request(tpAniSirGlobal pMac, uint16_t sessionId, scan_req->minChnTime, scan_req->maxChnTime); } #ifdef WLAN_AP_STA_CONCURRENCY - /* Need to set restTime only if at least one session is connected */ + /* + * Need to set restTime/min_Ret_time/idle_time + * only if at least one session is connected + */ if (scan_req->restTime == 0 && csr_is_any_session_connected(pMac)) { scan_req->restTime = cfg_prm->nRestTimeConc; + scan_req->min_rest_time = cfg_prm->min_rest_time_conc; + scan_req->idle_time = cfg_prm->idle_time_conc; if (scan_req->scanType == eSIR_ACTIVE_SCAN) { scan_req->maxChnTime = cfg_prm->nActiveMaxChnTimeConc; scan_req->minChnTime = cfg_prm->nActiveMinChnTimeConc; @@ -4984,8 +4998,12 @@ QDF_STATUS csr_send_mb_scan_req(tpAniSirGlobal pMac, uint16_t sessionId, pMsg->maxChannelTime = maxChnTime; /* hidden SSID option */ pMsg->hiddenSsid = pScanReqParam->hiddenSsid; - /* rest time */ + /* maximum rest time */ pMsg->restTime = pScanReq->restTime; + /* Minimum rest time */ + pMsg->min_rest_time = pScanReq->min_rest_time; + /* Idle time */ + pMsg->idle_time = pScanReq->idle_time; pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch; /* All the scan results caching will be done by Roaming */ /* We do not want LIM to do any caching of scan results, */ diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 829c4f604b64..5537bf317f39 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -53,6 +53,8 @@ #define CSR_ACTIVE_MIN_CHANNEL_TIME_CONC 20 #define CSR_REST_TIME_CONC 100 +#define CSR_MIN_REST_TIME_CONC 50 +#define CSR_IDLE_TIME_CONC 25 #define CSR_NUM_STA_CHAN_COMBINED_CONC 3 #define CSR_NUM_P2P_CHAN_COMBINED_CONC 1 diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 49523a706044..841b04e8acb8 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -239,19 +239,21 @@ QDF_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle, cmd->repeat_probe_time = cmd->dwell_time_active / WMA_SCAN_NPROBES_DEFAULT; - /* CSR sends only one value restTime for staying on home channel - * to continue data traffic. Rome fw has facility to monitor the traffic - * and move to next channel. Stay on the channel for at least half - * of the requested time and then leave if there is no traffic. + /* CSR sends min_rest_Time, max_rest_time and idle_time + * for staying on home channel to continue data traffic. + * Rome fw has facility to monitor the traffic + * and move to next channel. Stay on the channel for min_rest_time + * and then leave if there is no traffic. */ - cmd->min_rest_time = scan_req->restTime / 2; + cmd->min_rest_time = scan_req->min_rest_time; cmd->max_rest_time = scan_req->restTime; /* Check for traffic at idle_time interval after min_rest_time. * Default value is 25 ms to allow full use of max_rest_time * when voice packets are running at 20 ms interval. */ - cmd->idle_time = WMA_SCAN_IDLE_TIME_DEFAULT; + cmd->idle_time = scan_req->idle_time; + /* Large timeout value for full scan cycle, 30 seconds */ cmd->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION; -- cgit v1.2.3 From 807e539334dc7bf29e1e932f191795f8aac7766f Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Thu, 5 May 2016 16:14:00 +0530 Subject: qcacld-3.0: Remove wlan_hdd_band_p2p_2_4_GHZ qcacld-2.0 to qcacld-3.0 propagation. Remove wlan_hdd_band_p2p_2_4_GHZ as it's not being used any more. Change-Id: I69d6e1b0c8298cab1776264f3e61445c95538729 CRs-Fixed: 944663 --- core/hdd/src/wlan_hdd_cfg80211.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 1a21f97ae2f9..79cc8b41943a 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -174,12 +174,6 @@ static struct ieee80211_channel hdd_channels_2_4_ghz[] = { HDD2GHZCHAN(2484, 14, 0), }; -static struct ieee80211_channel hdd_social_channels_2_4_ghz[] = { - HDD2GHZCHAN(2412, 1, 0), - HDD2GHZCHAN(2437, 6, 0), - HDD2GHZCHAN(2462, 11, 0), -}; - static struct ieee80211_channel hdd_channels_5_ghz[] = { HDD5GHZCHAN(5180, 36, 0), HDD5GHZCHAN(5200, 40, 0), @@ -268,23 +262,6 @@ static struct ieee80211_supported_band wlan_hdd_band_2_4_ghz = { .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED, }; -static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_ghz = { - .channels = hdd_social_channels_2_4_ghz, - .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_ghz), - .band = IEEE80211_BAND_2GHZ, - .bitrates = g_mode_rates, - .n_bitrates = g_mode_rates_size, - .ht_cap.ht_supported = 1, - .ht_cap.cap = IEEE80211_HT_CAP_SGI_20 - | IEEE80211_HT_CAP_GRN_FLD - | IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_LSIG_TXOP_PROT, - .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, - .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, - .ht_cap.mcs.rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - .ht_cap.mcs.rx_highest = cpu_to_le16(72), - .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED, -}; - static struct ieee80211_supported_band wlan_hdd_band_5_ghz = { .channels = hdd_channels_5_ghz, .n_channels = ARRAY_SIZE(hdd_channels_5_ghz), @@ -5954,8 +5931,6 @@ int wlan_hdd_cfg80211_init(struct device *dev, if (!pCfg->ShortGI20MhzEnable) { wlan_hdd_band_2_4_ghz.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20; wlan_hdd_band_5_ghz.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20; - wlan_hdd_band_p2p_2_4_ghz.ht_cap.cap &= - ~IEEE80211_HT_CAP_SGI_20; } if (!pCfg->ShortGI40MhzEnable) { -- cgit v1.2.3 From fdcb2d0b1fb22c63c4f6e49dd3d89c157e19e467 Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Thu, 5 May 2016 16:24:11 +0530 Subject: qcacld-3.0: Flush Scan results in DRIVER command SET_FCC_CHANNEL qcacld-2.0 to qcacld-3.0 propagation When framework sends SET_FCC_CHANNEL command to driver, driver removes channel 12 and 13 from valid channel list. Even after removing channels from valid channel list, BSS entries are not flushed from scan cache table. BSS entries get removed when age out timer expires. Scan results shows stale entries before age out timer expires. As 12 and 13 are not in valid channel list, driver should remove BSS scanned on channel 12 and 13. Change-Id: I63ca0bea23da1430ca0e6f323555c3ac6b2d07cd CRs-Fixed: 949293 --- core/sme/src/csr/csr_api_scan.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index 299fb641d367..0cf923b6b2e3 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -4176,6 +4176,11 @@ bool csr_scan_complete(tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp) pCommand->u.scanCmd.abortScanDueToBandChange = false; } csr_save_scan_results(pMac, pCommand->u.scanCmd.reason, sessionId); + /* filter scan result based on valid channel list number */ + if (pMac->scan.fcc_constraint) { + sms_log(pMac, LOG1, FL("Clear BSS from invalid channels")); + csr_scan_filter_results(pMac); + } #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR csr_diag_scan_complete(pMac, pCommand, pScanRsp); #endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */ -- cgit v1.2.3 From fb87b16193b5d7ab9a2dc05c2519e36a3a5de929 Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Thu, 5 May 2016 16:31:20 +0530 Subject: qcacld-3.0: Don't Update default country code when no country code is selected qcacld-2.0 to qcacld-3.0 propagation At the time of driver load, countryCodeElected will be saved as default country code. If Driver changes country code through userspace, driver won't update countryCodeElected as countryCodeElected is updated only for 11d scan. In next scan if there are no scan results with 11d country code, the driver will try to update country code on the basis of countryCodeElected. Fix this by not updating country code through 11d if number of country code count is zero in scan results. Change-Id: I0e5620a834dd3fef61d8a5f86ce753b9233bf56e CRs-Fixed: 1004031 --- core/sme/src/csr/csr_api_scan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index 0cf923b6b2e3..c337db354395 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -2930,8 +2930,8 @@ static void csr_move_temp_scan_results_to_main_list(tpAniSirGlobal pMac, return; } } - csr_elected_country_info(pMac); - csr_learn_11dcountry_information(pMac, NULL, NULL, true); + if (csr_elected_country_info(pMac)) + csr_learn_11dcountry_information(pMac, NULL, NULL, true); } static tCsrScanResult *csr_scan_save_bss_description(tpAniSirGlobal pMac, @@ -3327,6 +3327,8 @@ bool csr_elected_country_info(tpAniSirGlobal pMac) uint8_t i, j = 0; if (!pMac->scan.countryCodeCount) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN, + "No AP with 11d Country code is present in scan list"); return fRet; } maxVotes = pMac->scan.votes11d[0].votes; -- cgit v1.2.3 From b2a0b76c83623855856cd5b235a367809972fb4e Mon Sep 17 00:00:00 2001 From: Agrawal Ashish Date: Thu, 5 May 2016 17:15:16 +0530 Subject: qcacld-3.0: Print mac address in Hex qcacld-2.0 to qcacld-3.0 propagation dphPrintMacAddr is printing mac address in decimal. Print mac address in Hex format for readability. Change-Id: I7a68d4d94745cee2274970196642d5041f09d184 CRs-Fixed: 940324 --- core/mac/src/dph/dph_hash_table.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/mac/src/dph/dph_hash_table.c b/core/mac/src/dph/dph_hash_table.c index 0e592d18a774..af64bd5899a8 100644 --- a/core/mac/src/dph/dph_hash_table.c +++ b/core/mac/src/dph/dph_hash_table.c @@ -450,7 +450,8 @@ tSirRetStatus dph_delete_hash_entry(tpAniSirGlobal pMac, tSirMacAddr staAddr, void dph_print_mac_addr(tpAniSirGlobal pMac, uint8_t addr[], uint32_t level) { - lim_log(pMac, (uint16_t) level, FL("MAC ADDR = %d:%d:%d:%d:%d:%d"), + lim_log(pMac, (uint16_t) level, + FL("MAC ADDR = %02x:%02x:%02x:%02x:%02x:%02x"), addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); } -- cgit v1.2.3 From e6409f54925d2ac5b9dd82074a62e793c489ffe1 Mon Sep 17 00:00:00 2001 From: Akash Patel Date: Fri, 6 May 2016 12:49:00 -0700 Subject: Release 5.1.0.7 Release 5.1.0.7 Change-Id: I853be50c2af89206383602430b904bb587aedc84 CRs-Fixed: 688141 --- core/mac/inc/qwlan_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h index a253ce6cb2b0..d390a25d64ca 100644 --- a/core/mac/inc/qwlan_version.h +++ b/core/mac/inc/qwlan_version.h @@ -42,8 +42,8 @@ #define QWLAN_VERSION_MINOR 1 #define QWLAN_VERSION_PATCH 0 #define QWLAN_VERSION_EXTRA "" -#define QWLAN_VERSION_BUILD 6 +#define QWLAN_VERSION_BUILD 7 -#define QWLAN_VERSIONSTR "5.1.0.6" +#define QWLAN_VERSIONSTR "5.1.0.7" #endif /* QWLAN_VERSION_H */ -- cgit v1.2.3 From c332b35416aebedd1623c8b22f3564397665e326 Mon Sep 17 00:00:00 2001 From: Vishwajith Upendra Date: Wed, 11 May 2016 14:41:04 -0700 Subject: Release 5.1.0.7A Release 5.1.0.7A Change-Id: I544f83bd429bd6d4f0fb645db6d08c84d4435dc0 CRs-Fixed: 688141 --- core/mac/inc/qwlan_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h index d390a25d64ca..b225c7fecf54 100644 --- a/core/mac/inc/qwlan_version.h +++ b/core/mac/inc/qwlan_version.h @@ -41,9 +41,9 @@ #define QWLAN_VERSION_MAJOR 5 #define QWLAN_VERSION_MINOR 1 #define QWLAN_VERSION_PATCH 0 -#define QWLAN_VERSION_EXTRA "" +#define QWLAN_VERSION_EXTRA "A" #define QWLAN_VERSION_BUILD 7 -#define QWLAN_VERSIONSTR "5.1.0.7" +#define QWLAN_VERSIONSTR "5.1.0.7A" #endif /* QWLAN_VERSION_H */ -- cgit v1.2.3