diff options
35 files changed, 707 insertions, 209 deletions
diff --git a/Android.mk b/Android.mk index 1454e42d94fa..4602cf9b787c 100644 --- a/Android.mk +++ b/Android.mk @@ -5,37 +5,43 @@ WLAN_CHIPSET := ifeq ($(BOARD_HAS_QCOM_WLAN), true) -# Build/Package options for 8084/8092/8960/8992/8994 target -ifeq ($(call is-board-platform-in-list, msm8994 msm8996 msm8998 msmcobalt),true) +# Check if this driver needs be built for current target +ifneq ($(findstring qca_cld3,$(WIFI_DRIVER_BUILT)),) WLAN_CHIPSET := qca_cld3 WLAN_SELECT := CONFIG_QCA_CLD_WLAN=m -endif # platform +endif # Build/Package only in case of supported target ifneq ($(WLAN_CHIPSET),) -# If TARGET_KERNEL_VERSION is not defined, using default kernel path, -# otherwise kernel path should come from top level Android makefiles. +# If kernel version is not defined, using default kernel path, otherwise +# kernel path offset should come from top level Android makefiles. ifeq ($(TARGET_KERNEL_VERSION),) -$(info "WLAN: TARGET_KERNEL_VERSION not defined, assuming default") +$(info "$(WLAN_CHIPSET): TARGET_KERNEL_VERSION not defined, assuming default") TARGET_KERNEL_SOURCE := kernel KERNEL_TO_BUILD_ROOT_OFFSET := ../ endif +# If kernel path offset is not defined, assume old kernel structure +ifeq ($(KERNEL_TO_BUILD_ROOT_OFFSET),) +$(info "$(WLAN_CHIPSET): KERNEL_TO_BUILD_ROOT_OFFSET not defined, assuming default") +KERNEL_TO_BUILD_ROOT_OFFSET := ../ +endif + LOCAL_PATH := $(call my-dir) # This makefile is only for DLKM ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - WLAN_BLD_DIR := vendor/qcom/opensource/wlan + WLAN_BLD_DIR := vendor/qcom/opensource/wlan endif # opensource # DLKM_DIR was moved for JELLY_BEAN (PLATFORM_SDK 16) ifeq ($(call is-platform-sdk-version-at-least,16),true) - DLKM_DIR := $(TOP)/device/qcom/common/dlkm + DLKM_DIR := $(TOP)/device/qcom/common/dlkm else - DLKM_DIR := build/dlkm + DLKM_DIR := build/dlkm endif # platform-sdk-version # Build wlan.ko as $(WLAN_CHIPSET)_wlan.ko @@ -63,9 +69,12 @@ include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### # Create Symbolic link +ifneq ($(findstring $(WLAN_CHIPSET),$(WIFI_DRIVER_DEFAULT)),) +$(shell mkdir -p $(TARGET_OUT)/lib/modules; \ + ln -sf /system/lib/modules/$(WLAN_CHIPSET)/$(LOCAL_MODULE) $(TARGET_OUT)/lib/modules/wlan.ko) +endif $(shell ln -sf /persist/wlan_mac.bin $(TARGET_OUT_ETC)/firmware/wlan/qca_cld/wlan_mac.bin) endif # DLKM check - endif # supported target check endif # WLAN enabled check @@ -22,8 +22,8 @@ ifeq ($(KERNEL_BUILD),1) # Need to explicitly define for Kernel-based builds MODNAME := wlan WLAN_ROOT := drivers/staging/qcacld-3.0 - WLAN_COMMON_ROOT := drivers/staging/qca-wifi-host-cmn - WLAN_COMMON_INC := $(WLAN_COMMON_ROOT) + WLAN_COMMON_ROOT := ../qca-wifi-host-cmn + WLAN_COMMON_INC := $(WLAN_ROOT)/$(WLAN_COMMON_ROOT) endif # Make WLAN as open-source driver by default @@ -41,6 +41,31 @@ ifeq ($(KERNEL_BUILD), 0) CONFIG_MOBILE_ROUTER := y endif + # As per target team, build is done as follows: + # Defconfig : build with default flags + # Slub : defconfig + CONFIG_SLUB_DEBUG=y + + # CONFIG_SLUB_DEBUG_ON=y + CONFIG_PAGE_POISONING=y + # Perf : Using appropriate msmXXXX-perf_defconfig + # + # Shipment builds (user variants) should not have any debug feature + # enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds + # are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since + # there is no other way to identify defconfig builds, QCOMs internal + # representation of perf builds (identified using the string 'perf'), + # is used to identify if the build is a slub or defconfig one. This + # way no critical debug feature will be enabled for perf and shipment + # builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT + # config. + ifneq ($(TARGET_BUILD_VARIANT),user) + ifeq ($(CONFIG_SLUB_DEBUG_ON),y) + CONFIG_PKT_PROTO_TRACE := y + else + ifeq ($(findstring perf,$(KERNEL_DEFCONFIG)),) + CONFIG_PKT_PROTO_TRACE := y + endif + endif + endif + #Flag to enable Legacy Fast Roaming2(LFR2) CONFIG_QCACLD_WLAN_LFR2 := y #Flag to enable Legacy Fast Roaming3(LFR3) @@ -73,7 +98,7 @@ ifeq ($(KERNEL_BUILD), 0) CONFIG_QCOM_VOWIFI_11R := y ifneq ($(CONFIG_QCA_CLD_WLAN),) - ifeq (y,$(filter y,$(CONFIG_CNSS) $(CONFIG_ICNSS))) + ifeq (y,$(findstring y,$(CONFIG_CNSS) $(CONFIG_ICNSS))) #Flag to enable Protected Managment Frames (11w) feature CONFIG_WLAN_FEATURE_11W := y #Flag to enable LTE CoEx feature @@ -139,6 +164,10 @@ ifeq ($(KERNEL_BUILD), 0) endif endif +ifeq ($(CONFIG_ROME_IF), snoc) + CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y +endif + # Flag to enable LFR Subnet Detection CONFIG_LFR_SUBNET_DETECTION := y @@ -198,6 +227,11 @@ endif ifeq ($(CONFIG_ROME_IF),pci) CONFIG_ATH_PCI := 1 endif + +ifeq ($(CONFIG_ROME_IF),snoc) + CONFIG_HIF_SNOC:= 1 +endif + ifeq ($(CONFIG_ROME_IF),usb) #CONFIG_ATH_PCI := 1 endif @@ -755,6 +789,7 @@ HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_SNOC_DIR) endif HIF_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/ath_procfs.o \ + $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_bmi.o \ $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_diag.o \ $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_main.o \ $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_service.o \ @@ -772,7 +807,6 @@ HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_napi.o endif HIF_PCIE_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_PCIE_DIR)/if_pci.o -HIF_PCIE_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_bmi.o HIF_SNOC_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_SNOC_DIR)/if_snoc.o HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus.o @@ -960,11 +994,7 @@ ifeq ($(CONFIG_FEATURE_BMI_2), y) CDEFINES += -DFEATURE_BMI_2 endif -ifeq ($(CONFIG_ARCH_MSM), y) -CDEFINES += -DMSM_PLATFORM -endif - -ifeq ($(CONFIG_ARCH_MSMCOBALT), y) +ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM))) CDEFINES += -DMSM_PLATFORM endif @@ -979,7 +1009,7 @@ CDEFINES += -DQCA_LL_LEGACY_TX_FLOW_CONTROL endif endif -ifeq ($(CONFIG_DEBUG_LL),y) +ifeq ($(CONFIG_PKT_PROTO_TRACE), y) CDEFINES += -DQCA_PKT_PROTO_TRACE endif @@ -119,4 +119,8 @@ config QCACLD_WLAN_LFR2 bool "Enable the WLAN Legacy Fast Roaming feature Version 2" default n +config PKT_PROTO_TRACE + bool "Enable packet trace feature" + default n + endif # QCA_CLD_WLAN diff --git a/core/bmi/src/bmi.c b/core/bmi/src/bmi.c index 0a15dd41267e..5752ccc0d6e9 100644 --- a/core/bmi/src/bmi.c +++ b/core/bmi/src/bmi.c @@ -37,6 +37,12 @@ /* 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) @@ -220,11 +226,33 @@ static inline uint32_t bmi_get_test_addr(void) } #endif -QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx) +/** + * 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; if (NO_BMI || !hif_needs_bmi(scn)) @@ -235,23 +263,9 @@ QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx) bmi_assert(0); return QDF_STATUS_NOT_INITIALIZED; } -#ifdef CONFIG_CNSS - if (BMI_TEST_ENABLE == cnss_get_bmi_setup()) { - 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!"); - goto end; - } - 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); - } -#endif -end: + + if (SHOULD_RUN_BMI_TEST_COMMANDS) + run_bmi_test(ol_ctx); return bmi_firmware_download(ol_ctx); } diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c index 79bc5625f106..e47ff72fa311 100644 --- a/core/bmi/src/ol_fw.c +++ b/core/bmi/src/ol_fw.c @@ -59,8 +59,11 @@ static uint32_t refclk_speed_to_hz[] = { 52000000, /* SOC_REFCLK_52_MHZ */ }; +#if defined(CONFIG_CNSS) static int ol_target_coredump(void *inst, void *memory_block, uint32_t block_len); +#endif + #ifdef FEATURE_SECURE_FIRMWARE static int ol_check_fw_hash(const u8 *data, u32 fw_size, ATH_BIN_FILE file) { @@ -150,7 +153,9 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, #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) struct bmi_info *bmi_ctx = GET_BMI_CONTEXT(ol_ctx); +#endif qdf_device_t qdf_dev = ol_ctx->qdf_dev; switch (file) { @@ -612,8 +617,10 @@ void ol_target_failure(void *instance, QDF_STATUS status) struct ol_context *ol_ctx = instance; struct hif_opaque_softc *scn = ol_ctx->scn; tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); +#ifdef CONFIG_CNSS 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); @@ -1218,9 +1225,9 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx) struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx); uint32_t target_type = tgt_info->target_type; uint32_t target_version = tgt_info->target_version; +#ifdef CONFIG_CNSS struct bmi_info *bmi_ctx = GET_BMI_CONTEXT(ol_ctx); -#ifdef CONFIG_CNSS if (0 != cnss_get_fw_files_for_target(&bmi_ctx->fw_files, target_type, target_version)) { @@ -1328,7 +1335,7 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx) if (ini_cfg->enable_uart_print || (WLAN_IS_EPPING_ENABLED(cds_get_conparam()) && WLAN_IS_EPPING_FW_UART(cds_get_conparam()))) { - switch (tgt_info->target_version) { + switch (target_version) { case AR6004_VERSION_REV1_3: param = 11; break; @@ -1427,6 +1434,7 @@ int ol_diag_read(struct hif_opaque_softc *scn, uint8_t *buffer, return -EIO; } +#if defined(CONFIG_CNSS) static int ol_ath_get_reg_table(uint32_t target_version, tgt_reg_table *reg_table) { @@ -1461,7 +1469,10 @@ static int ol_ath_get_reg_table(uint32_t target_version, return section_len; } +#endif + +#if defined(CONFIG_CNSS) static int ol_diag_read_reg_loc(struct hif_opaque_softc *scn, uint8_t *buffer, uint32_t buffer_len) { @@ -1527,6 +1538,7 @@ static int ol_diag_read_reg_loc(struct hif_opaque_softc *scn, uint8_t *buffer, out: return result; } +#endif void ol_dump_target_memory(struct hif_opaque_softc *scn, void *memory_block) { @@ -1552,6 +1564,8 @@ void ol_dump_target_memory(struct hif_opaque_softc *scn, void *memory_block) } } + +#if defined(CONFIG_CNSS) /** * ol_target_coredump() - API to collect target ramdump * @inst - private context @@ -1638,6 +1652,7 @@ static int ol_target_coredump(void *inst, void *memory_block, } return ret; } +#endif /** * ol_get_ini_handle() - API to get Ol INI configuration diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h index 14a5f860d63e..45e37f8b0f94 100644 --- a/core/cds/inc/cds_concurrency.h +++ b/core/cds/inc/cds_concurrency.h @@ -47,6 +47,51 @@ #define CONNECTION_UPDATE_TIMEOUT 1000 #endif +/* Some max value greater than the max length of the channel list */ +#define MAX_WEIGHT_OF_PCL_CHANNELS 255 +/* Some fixed weight difference between the groups */ +#define PCL_GROUPS_WEIGHT_DIFFERENCE 20 + +/* Currently max, only 3 groups are possible as per 'enum cds_pcl_type'. + * i.e., in a PCL only 3 groups of channels can be present + * e.g., SCC channel on 2.4 Ghz, SCC channel on 5 Ghz & 5 Ghz channels. + * Group 1 has highest priority, group 2 has the next higher priority + * and so on. + */ +#define WEIGHT_OF_GROUP1_PCL_CHANNELS MAX_WEIGHT_OF_PCL_CHANNELS +#define WEIGHT_OF_GROUP2_PCL_CHANNELS \ + (WEIGHT_OF_GROUP1_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE) +#define WEIGHT_OF_GROUP3_PCL_CHANNELS \ + (WEIGHT_OF_GROUP2_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE) + +#define WEIGHT_OF_NON_PCL_CHANNELS 1 + +/** + * enum cds_pcl_group_id - Identifies the pcl groups to be used + * @CDS_PCL_GROUP_ID1_ID2: Use weights of group1 and group2 + * @CDS_PCL_GROUP_ID2_ID2: Use weights of group2 and group3 + * + * Since maximum of three groups are possible, this will indicate which + * PCL group needs to be used. + */ +enum cds_pcl_group_id { + CDS_PCL_GROUP_ID1_ID2, + CDS_PCL_GROUP_ID2_ID3, +}; + +/** + * cds_pcl_channel_order - Order in which the PCL is requested + * @CDS_PCL_ORDER_NONE: no order + * @CDS_PCL_ORDER_24G_THEN_5G: 2.4 Ghz channel followed by 5 Ghz channel + * @CDS_PCL_ORDER_5G_THEN_2G: 5 Ghz channel followed by 2.4 Ghz channel + * + * Order in which the PCL is requested + */ +enum cds_pcl_channel_order { + CDS_PCL_ORDER_NONE, + CDS_PCL_ORDER_24G_THEN_5G, + CDS_PCL_ORDER_5G_THEN_2G, +}; /** * enum cds_max_rx_ss - Maximum number of receive spatial streams @@ -588,7 +633,8 @@ void cds_decr_session_set_pcl(enum tQDF_ADAPTER_MODE mode, QDF_STATUS cds_init_policy_mgr(void); QDF_STATUS cds_deinit_policy_mgr(void); QDF_STATUS cds_get_pcl(enum cds_con_mode mode, - uint8_t *pcl_Channels, uint32_t *len); + uint8_t *pcl_channels, uint32_t *len, + uint8_t *pcl_weight, uint32_t weight_len); uint8_t cds_get_nondfs_preferred_channel(enum cds_con_mode mode, bool for_existing_conn); bool cds_is_any_nondfs_chnl_present(uint8_t *channel); @@ -697,5 +743,7 @@ QDF_STATUS cds_register_sap_restart_channel_switch_cb( void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t)); #endif QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode, - uint8_t *pcl_ch, uint32_t *len); + 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); #endif /* __CDS_CONCURRENCY_H */ diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h index 7325b6155e26..46908e6701f6 100644 --- a/core/cds/inc/cds_sched.h +++ b/core/cds/inc/cds_sched.h @@ -296,7 +296,6 @@ typedef struct _cds_context_type { /*--------------------------------------------------------------------------- Function declarations and documenation ---------------------------------------------------------------------------*/ - #ifdef QCA_CONFIG_SMP /*--------------------------------------------------------------------------- \brief cds_drop_rxpkt_by_staid() - API to drop pending Rx packets for a sta @@ -357,6 +356,70 @@ void cds_free_ol_rx_pkt(p_cds_sched_context pSchedContext, \sa cds_free_ol_rx_pkt_freeq() -------------------------------------------------------------------------*/ void cds_free_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext); +#else +/** + * cds_drop_rxpkt_by_staid() - api to drop pending rx packets for a sta + * @pSchedContext: Pointer to the global CDS Sched Context + * @staId: Station Id + * + * This api drops queued packets for a station, to drop all the pending + * packets the caller has to send WLAN_MAX_STA_COUNT as staId. + * + * Return: none + */ +static inline +void cds_drop_rxpkt_by_staid(p_cds_sched_context pSchedContext, uint16_t staId) +{ +} + +/** + * cds_indicate_rxpkt() - API to Indicate rx data packet + * @pSchedContext: pointer to CDS Sched Context + * @pkt: CDS OL RX pkt pointer containing to RX data message buffer + * + * Return: none + */ +static inline +void cds_indicate_rxpkt(p_cds_sched_context pSchedContext, + struct cds_ol_rx_pkt *pkt) +{ +} + +/** + * cds_alloc_ol_rx_pkt() - API to return next available cds message + * @pSchedContext: pointer to CDS Sched Context + * + * Return: none + */ +static inline +struct cds_ol_rx_pkt *cds_alloc_ol_rx_pkt(p_cds_sched_context pSchedContext) +{ +} + +/** + * cds_free_ol_rx_pkt() - API to release cds message to the freeq + * @pSchedContext: pointer to CDS Sched Context + * @pkt: CDS message buffer to be returned to free queue + * + * Return: none + */ +static inline +void cds_free_ol_rx_pkt(p_cds_sched_context pSchedContext, + struct cds_ol_rx_pkt *pkt) +{ +} + +/** + * cds_free_ol_rx_pkt_freeq() - Free cds buffer free queue + * @pSchedContext: pointer to CDS Sched Context + * @pkt: CDS message buffer to be returned to free queue + * + * Return: none + */ +static inline +void cds_free_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext) +{ +} #endif /*--------------------------------------------------------------------------- diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index 2e8d9002b8ed..f211ace0dfc5 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -3438,16 +3438,16 @@ void cds_clear_concurrency_mode(enum tQDF_ADAPTER_MODE mode) } /** - * cds_soc_set_pcl() - Sets PCL to FW + * cds_pdev_set_pcl() - Sets PCL to FW * @mode: adapter mode * * Fetches the PCL and sends the PCL to SME * module which in turn will send the WMI - * command WMI_SOC_SET_PCL_CMDID to the fw + * command WMI_PDEV_SET_PCL_CMDID to the fw * * Return: None */ -static void cds_soc_set_pcl(enum tQDF_ADAPTER_MODE mode) +static void cds_pdev_set_pcl(enum tQDF_ADAPTER_MODE mode) { QDF_STATUS status; enum cds_con_mode con_mode; @@ -3485,13 +3485,14 @@ static void cds_soc_set_pcl(enum tQDF_ADAPTER_MODE mode) cds_debug("get pcl to set it to the FW"); status = cds_get_pcl(con_mode, - pcl.pcl_list, &pcl.pcl_len); + pcl.pcl_list, &pcl.pcl_len, + pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); if (status != QDF_STATUS_SUCCESS) { cds_err("Unable to set PCL to FW, Get PCL failed"); return; } - status = sme_soc_set_pcl(hdd_ctx->hHal, pcl); + status = sme_pdev_set_pcl(hdd_ctx->hHal, pcl); if (status != QDF_STATUS_SUCCESS) cds_err("Send soc set PCL to SME failed"); else @@ -3552,7 +3553,7 @@ void cds_incr_active_session(enum tQDF_ADAPTER_MODE mode, */ if (mode == QDF_STA_MODE) { /* Set PCL of STA to the FW */ - cds_soc_set_pcl(mode); + cds_pdev_set_pcl(mode); cds_info("Set PCL of STA to FW"); } cds_incr_connection_count(session_id); @@ -3671,7 +3672,7 @@ static void cds_set_pcl_for_existing_combo(enum cds_con_mode mode) /* Check, store and temp delete the mode's parameter */ cds_store_and_del_conn_info(mode, &info); /* Set the PCL to the FW since connection got updated */ - cds_soc_set_pcl(pcl_mode); + cds_pdev_set_pcl(pcl_mode); cds_info("Set PCL to FW for mode:%d", mode); /* Restore the connection info */ cds_restore_deleted_conn_info(&info); @@ -3681,13 +3682,18 @@ static void cds_set_pcl_for_existing_combo(enum cds_con_mode mode) /** * cds_get_pcl_for_existing_conn() - Get PCL for existing connection * @mode: Connection mode of type 'cds_con_mode' + * @pcl_ch: Pointer to the PCL + * @len: Pointer to the length of the PCL + * @pcl_weight: Pointer to the weights of the PCL + * @weight_len: Max length of the weights list * * Get the PCL for an existing connection * * Return: None */ QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode, - uint8_t *pcl_ch, uint32_t *len) + uint8_t *pcl_ch, uint32_t *len, + uint8_t *pcl_weight, uint32_t weight_len) { struct cds_conc_connection_info info; @@ -3703,7 +3709,7 @@ QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode, /* Check, store and temp delete the mode's parameter */ cds_store_and_del_conn_info(mode, &info); /* Set the PCL to the FW since connection got updated */ - status = cds_get_pcl(mode, pcl_ch, len); + status = cds_get_pcl(mode, pcl_ch, len, pcl_weight, weight_len); cds_info("Get PCL to FW for mode:%d", mode); /* Restore the connection info */ cds_restore_deleted_conn_info(&info); @@ -4289,6 +4295,10 @@ QDF_STATUS cds_decr_connection_count(uint32_t vdev_id) * @order: no order OR 2.4 Ghz channel followed by 5 Ghz * channel OR 5 Ghz channel followed by 2.4 Ghz channel * @skip_dfs_channel: if this flag is true then skip the dfs channel + * @pcl_weight: Pointer to the weights of PCL + * @weight_len: Max length of the weight list + * @index: Index from which the weight list needs to be populated + * @group_id: Next available groups for weight assignment * * * This function provides the channel(s) on which current @@ -4297,11 +4307,14 @@ QDF_STATUS cds_decr_connection_count(uint32_t vdev_id) * Return: QDF_STATUS */ QDF_STATUS cds_get_connection_channels(uint8_t *channels, - uint32_t *len, uint8_t order, - bool skip_dfs_channel) + uint32_t *len, enum cds_pcl_channel_order order, + bool skip_dfs_channel, + uint8_t *pcl_weight, uint32_t weight_len, + uint32_t *index, enum cds_pcl_group_id group_id) { QDF_STATUS status = QDF_STATUS_SUCCESS; uint32_t conn_index = 0, num_channels = 0; + uint32_t weight1, weight2; if ((NULL == channels) || (NULL == len)) { cds_err("channels or len is NULL"); @@ -4309,58 +4322,99 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels, return status; } - if (0 == order) { + /* CDS_PCL_GROUP_ID1_ID2 indicates that all three weights are + * available for assignment. i.e., WEIGHT_OF_GROUP1_PCL_CHANNELS, + * WEIGHT_OF_GROUP2_PCL_CHANNELS and WEIGHT_OF_GROUP3_PCL_CHANNELS + * are all available. Since in this function only two weights are + * assigned at max, only group1 and group2 weights are considered. + * + * The other possible group id CDS_PCL_GROUP_ID2_ID3 indicates that + * group1 was assigned the weight WEIGHT_OF_GROUP1_PCL_CHANNELS and + * only weights WEIGHT_OF_GROUP2_PCL_CHANNELS and + * WEIGHT_OF_GROUP3_PCL_CHANNELS are available for further weight + * assignments. + * + * e.g., when order is CDS_PCL_ORDER_24G_THEN_5G and group id is + * CDS_PCL_GROUP_ID2_ID3, WEIGHT_OF_GROUP2_PCL_CHANNELS is assigned to + * 2.4GHz channels and the weight WEIGHT_OF_GROUP3_PCL_CHANNELS is + * assigned to the 5GHz channels. + */ + if (group_id == CDS_PCL_GROUP_ID1_ID2) { + weight1 = WEIGHT_OF_GROUP1_PCL_CHANNELS; + weight2 = WEIGHT_OF_GROUP2_PCL_CHANNELS; + } else { + weight1 = WEIGHT_OF_GROUP2_PCL_CHANNELS; + weight2 = WEIGHT_OF_GROUP3_PCL_CHANNELS; + } + + if (CDS_PCL_ORDER_NONE == order) { while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (skip_dfs_channel && CDS_IS_DFS_CH( - conc_connection_list[conn_index].chan)) + conc_connection_list[conn_index].chan)) { conn_index++; - else + } else { channels[num_channels++] = conc_connection_list[conn_index++].chan; + if (*index < weight_len) + pcl_weight[(*index)++] = weight1; + } } *len = num_channels; - } else if (1 == order) { + } else if (CDS_PCL_ORDER_24G_THEN_5G == order) { while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (CDS_IS_CHANNEL_24GHZ( - conc_connection_list[conn_index].chan)) + conc_connection_list[conn_index].chan)) { channels[num_channels++] = conc_connection_list[conn_index++].chan; - else + if (*index < weight_len) + pcl_weight[(*index)++] = weight1; + } else { conn_index++; + } } conn_index = 0; while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (skip_dfs_channel && CDS_IS_DFS_CH( - conc_connection_list[conn_index].chan)) + conc_connection_list[conn_index].chan)) { conn_index++; - else if (CDS_IS_CHANNEL_5GHZ( - conc_connection_list[conn_index].chan)) + } else if (CDS_IS_CHANNEL_5GHZ( + conc_connection_list[conn_index].chan)) { channels[num_channels++] = conc_connection_list[conn_index++].chan; - else + if (*index < weight_len) + pcl_weight[(*index)++] = weight2; + } else { conn_index++; + } } *len = num_channels; - } else if (2 == order) { + } else if (CDS_PCL_ORDER_5G_THEN_2G == order) { while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (skip_dfs_channel && CDS_IS_DFS_CH( - conc_connection_list[conn_index].chan)) + conc_connection_list[conn_index].chan)) { conn_index++; - else if (CDS_IS_CHANNEL_5GHZ( - conc_connection_list[conn_index].chan)) + } else if (CDS_IS_CHANNEL_5GHZ( + conc_connection_list[conn_index].chan)) { channels[num_channels++] = conc_connection_list[conn_index++].chan; - else + if (*index < weight_len) + pcl_weight[(*index)++] = weight1; + } else { conn_index++; + } } conn_index = 0; while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (CDS_IS_CHANNEL_24GHZ( - conc_connection_list[conn_index].chan)) + conc_connection_list[conn_index].chan)) { channels[num_channels++] = conc_connection_list[conn_index++].chan; - else + if (*index < weight_len) + pcl_weight[(*index)++] = weight2; + + } else { conn_index++; + } } *len = num_channels; } else { @@ -4376,6 +4430,8 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels, * channel list * @pcl_channels: channel list * @len: length of the list + * @weight_list: Weights of the PCL + * @weight_len: Max length of the weights list * * This function provides the safe channel list from the list * provided after consulting the channel avoidance list @@ -4383,10 +4439,12 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels, * Return: None */ #ifdef CONFIG_CNSS -void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) +void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len, + uint8_t *weight_list, uint32_t weight_len) { uint16_t unsafe_channel_list[MAX_NUM_CHAN]; uint8_t current_channel_list[MAX_NUM_CHAN]; + uint8_t org_weight_list[MAX_NUM_CHAN]; uint16_t unsafe_channel_count = 0; uint8_t is_unsafe = 1; uint8_t i, j; @@ -4409,6 +4467,9 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) qdf_mem_zero(pcl_channels, sizeof(*pcl_channels)*current_channel_count); + qdf_mem_copy(org_weight_list, weight_list, MAX_NUM_CHAN); + qdf_mem_zero(weight_list, weight_len); + for (i = 0; i < current_channel_count; i++) { is_unsafe = 0; for (j = 0; j < unsafe_channel_count; j++) { @@ -4424,6 +4485,9 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) if (!is_unsafe) { pcl_channels[safe_channel_count++] = current_channel_list[i]; + if (safe_channel_count < weight_len) + weight_list[safe_channel_count++] = + org_weight_list[i]; } } *len = safe_channel_count; @@ -4431,7 +4495,8 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) return; } #else -void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) +void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len, + uint8_t *weight_list, uint32_t weight_len) { return; } @@ -4439,11 +4504,12 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) /** * cds_get_channel_list() - provides the channel list * suggestion for new connection - * @hdd_ctx: HDD Context * @pcl: The preferred channel list enum * @pcl_channels: PCL channels * @len: length of the PCL * @mode: concurrency mode for which channel list is requested + * @pcl_weights: Weights of the PCL + * @weight_len: Max length of the weight list * * This function provides the actual channel list based on the * current regulatory domain derived using preferred channel @@ -4452,7 +4518,9 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) * Return: Channel List */ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, - uint8_t *pcl_channels, uint32_t *len, enum cds_con_mode mode) + uint8_t *pcl_channels, uint32_t *len, + enum cds_con_mode mode, + uint8_t *pcl_weights, uint32_t weight_len) { QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t num_channels = WNI_CFG_VALID_CHANNEL_LIST_LEN; @@ -4462,6 +4530,7 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, uint8_t channel_list_5[MAX_NUM_CHAN] = {0}; bool skip_dfs_channel = false; hdd_context_t *hdd_ctx; + uint32_t i = 0, j = 0; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -4529,23 +4598,61 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, } num_channels = 0; + /* In the below switch case, the channel list is populated based on the + * pcl. e.g., if the pcl is CDS_SCC_CH_24G, the SCC channel group is + * populated first followed by the 2.4GHz channel group. Along with + * this, the weights are also populated in the same order for each of + * these groups. There are three weight groups: + * WEIGHT_OF_GROUP1_PCL_CHANNELS, WEIGHT_OF_GROUP2_PCL_CHANNELS and + * WEIGHT_OF_GROUP3_PCL_CHANNELS. + * + * e.g., if pcl is CDS_SCC_ON_5_SCC_ON_24_24G: scc on 5GHz (group1) + * channels take the weight WEIGHT_OF_GROUP1_PCL_CHANNELS, scc on 2.4GHz + * (group2) channels take the weight WEIGHT_OF_GROUP2_PCL_CHANNELS and + * 2.4GHz (group3) channels take the weight + * WEIGHT_OF_GROUP3_PCL_CHANNELS. + * + * When the weight to be assigned to the group is known along with the + * number of channels, the weights are directly assigned to the + * pcl_weights list. But, the channel list is populated using + * cds_get_connection_channels(), the order of weights to be used is + * passed as an argument to the function cds_get_connection_channels() + * using 'enum cds_pcl_group_id' which indicates the next available + * weights to be used and cds_get_connection_channels() will take care + * of the weight assignments. + * + * e.g., 'enum cds_pcl_group_id' value of CDS_PCL_GROUP_ID2_ID3 + * indicates that the next available groups for weight assignment are + * WEIGHT_OF_GROUP2_PCL_CHANNELS and WEIGHT_OF_GROUP3_PCL_CHANNELS and + * that the weight WEIGHT_OF_GROUP1_PCL_CHANNELS was already allocated. + * So, in the same example, when order is CDS_PCL_ORDER_24G_THEN_5G, + * cds_get_connection_channels() will assign the weight + * WEIGHT_OF_GROUP2_PCL_CHANNELS to 2.4GHz channels and assign the + * weight WEIGHT_OF_GROUP3_PCL_CHANNELS to 5GHz channels. + */ switch (pcl) { case CDS_24G: qdf_mem_copy(pcl_channels, channel_list_24, chan_index_24); *len = chan_index_24; + for (i = 0; ((i < *len) && (i < weight_len)); i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case CDS_5G: qdf_mem_copy(pcl_channels, channel_list_5, chan_index_5); *len = chan_index_5; + for (i = 0; ((i < *len) && (i < weight_len)); i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case CDS_SCC_CH: case CDS_MCC_CH: cds_get_connection_channels( - channel_list, &num_channels, 0, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *len = num_channels; status = QDF_STATUS_SUCCESS; @@ -4553,24 +4660,33 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, case CDS_SCC_CH_24G: case CDS_MCC_CH_24G: cds_get_connection_channels( - channel_list, &num_channels, 0, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *len = num_channels; qdf_mem_copy(&pcl_channels[num_channels], channel_list_24, chan_index_24); *len += chan_index_24; + for (j = 0; ((j < chan_index_24) && (i < weight_len)); i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS; + status = QDF_STATUS_SUCCESS; break; case CDS_SCC_CH_5G: case CDS_MCC_CH_5G: cds_get_connection_channels( - channel_list, &num_channels, 0, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *len = num_channels; qdf_mem_copy(&pcl_channels[num_channels], channel_list_5, chan_index_5); *len += chan_index_5; + for (j = 0; ((j < chan_index_5) && (i < weight_len)); i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case CDS_24G_SCC_CH: @@ -4578,8 +4694,12 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, qdf_mem_copy(pcl_channels, channel_list_24, chan_index_24); *len = chan_index_24; + for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; cds_get_connection_channels( - channel_list, &num_channels, 0, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID2_ID3); qdf_mem_copy(&pcl_channels[chan_index_24], channel_list, num_channels); *len += num_channels; @@ -4590,8 +4710,12 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, qdf_mem_copy(pcl_channels, channel_list_5, chan_index_5); *len = chan_index_5; + for (i = 0; ((i < chan_index_5) && (i < weight_len)); i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; cds_get_connection_channels( - channel_list, &num_channels, 0, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID2_ID3); qdf_mem_copy(&pcl_channels[chan_index_5], channel_list, num_channels); *len += num_channels; @@ -4599,7 +4723,9 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, break; case CDS_SCC_ON_24_SCC_ON_5: cds_get_connection_channels( - channel_list, &num_channels, 1, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_24G_THEN_5G, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *len = num_channels; @@ -4607,49 +4733,67 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, break; case CDS_SCC_ON_5_SCC_ON_24: cds_get_connection_channels( - channel_list, &num_channels, 2, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_5G_THEN_2G, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *len = num_channels; status = QDF_STATUS_SUCCESS; break; case CDS_SCC_ON_24_SCC_ON_5_24G: cds_get_connection_channels( - channel_list, &num_channels, 1, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_24G_THEN_5G, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *len = num_channels; qdf_mem_copy(&pcl_channels[num_channels], channel_list_24, chan_index_24); *len += chan_index_24; + for (j = 0; ((j < chan_index_24) && (i < weight_len)); i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case CDS_SCC_ON_24_SCC_ON_5_5G: cds_get_connection_channels( - channel_list, &num_channels, 1, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_24G_THEN_5G, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *len = num_channels; qdf_mem_copy(&pcl_channels[num_channels], channel_list_5, chan_index_5); *len += chan_index_5; + for (j = 0; ((j < chan_index_5) && (i < weight_len)); i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case CDS_SCC_ON_5_SCC_ON_24_24G: cds_get_connection_channels( - channel_list, &num_channels, 2, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_5G_THEN_2G, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *len = num_channels; qdf_mem_copy(&pcl_channels[num_channels], channel_list_24, chan_index_24); *len += chan_index_24; + for (j = 0; ((j < chan_index_24) && (i < weight_len)); i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case CDS_SCC_ON_5_SCC_ON_24_5G: cds_get_connection_channels( - channel_list, &num_channels, 2, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_5G_THEN_2G, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *len = num_channels; qdf_mem_copy(&pcl_channels[num_channels], channel_list_5, chan_index_5); *len += chan_index_5; + for (j = 0; ((j < chan_index_5) && (i < weight_len)); i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; default: @@ -4657,8 +4801,13 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, break; } + if ((*len != 0) && (*len != i)) + cds_info("pcl len (%d) and weight list len mismatch (%d)", + *len, i); + /* check the channel avoidance list */ - cds_update_with_safe_channel_list(pcl_channels, len); + cds_update_with_safe_channel_list(pcl_channels, len, + pcl_weights, weight_len); return status; } @@ -4708,6 +4857,8 @@ bool cds_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode, * @mode: Device mode * @pcl_channels: PCL channels * @len: lenght of the PCL + * @pcl_weight: Weights of the PCL + * @weight_len: Max length of the weights list * * This function provides the preferred channel list on which * policy manager wants the new connection to come up. Various @@ -4717,7 +4868,8 @@ bool cds_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode, * Return: QDF_STATUS */ QDF_STATUS cds_get_pcl(enum cds_con_mode mode, - uint8_t *pcl_channels, uint32_t *len) + uint8_t *pcl_channels, uint32_t *len, + uint8_t *pcl_weight, uint32_t weight_len) { QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t num_connections = 0; @@ -4805,12 +4957,14 @@ QDF_STATUS cds_get_pcl(enum cds_con_mode mode, /* once the PCL enum is obtained find out the exact channel list with * help from sme_get_cfg_valid_channels */ - status = cds_get_channel_list(pcl, pcl_channels, len, mode); + status = cds_get_channel_list(pcl, pcl_channels, len, mode, + pcl_weight, weight_len); if (status == QDF_STATUS_SUCCESS) { uint32_t i; cds_debug("pcl len:%d", *len); for (i = 0; i < *len; i++) - cds_debug("chan:%d", pcl_channels[i]); + cds_debug("chan:%d weight:%d", + pcl_channels[i], pcl_weight[i]); } return status; @@ -8217,6 +8371,8 @@ cds_get_nondfs_preferred_channel(enum cds_con_mode mode, bool for_existing_conn) { uint8_t pcl_channels[NUM_CHANNELS]; + uint8_t pcl_weight[NUM_CHANNELS]; + /* * in worst case if we can't find any channel at all * then return 2.4G channel, so atleast we won't fall @@ -8235,11 +8391,13 @@ cds_get_nondfs_preferred_channel(enum cds_con_mode mode, return channel; if (QDF_STATUS_SUCCESS != cds_get_pcl_for_existing_conn(mode, - &pcl_channels[0], &pcl_len)) + &pcl_channels[0], &pcl_len, + pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) return channel; } else { if (QDF_STATUS_SUCCESS != cds_get_pcl(mode, - &pcl_channels[0], &pcl_len)) + &pcl_channels[0], &pcl_len, + pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) return channel; } @@ -8263,6 +8421,8 @@ cds_get_nondfs_preferred_channel(enum cds_con_mode mode, } return channel; } + + /** * cds_is_any_nondfs_chnl_present() - Find any non-dfs channel from conc table * @channel: pointer to channel which needs to be filled @@ -8296,3 +8456,47 @@ bool cds_is_any_nondfs_chnl_present(uint8_t *channel) return status; } +/** + * cds_get_valid_chan_weights() - Get the weightage for all valid channels + * @weight: Pointer to the structure containing pcl, saved channel list and + * weighed channel list + * + * Provides the weightage for all valid channels. This compares the PCL list + * with the valid channel list. The channels present in the PCL get their + * corresponding weightage and the non-PCL channels get the default weightage + * of WEIGHT_OF_NON_PCL_CHANNELS. + * + * Return: QDF_STATUS + */ +QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight) +{ + uint32_t i, j; + + if (!weight->pcl_list) { + cds_err("Invalid pcl"); + return QDF_STATUS_E_FAILURE; + } + + if (!weight->saved_chan_list) { + cds_err("Invalid valid channel list"); + return QDF_STATUS_E_FAILURE; + } + + if (!weight->weighed_valid_list) { + cds_err("Invalid weighed valid channel list"); + return QDF_STATUS_E_FAILURE; + } + + for (i = 0; i < weight->saved_num_chan; i++) { + weight->weighed_valid_list[i] = WEIGHT_OF_NON_PCL_CHANNELS; + for (j = 0; j < weight->pcl_len; j++) { + if (weight->saved_chan_list[i] == weight->pcl_list[j]) { + weight->weighed_valid_list[i] = + weight->weight_list[j]; + break; + } + } + } + + return QDF_STATUS_SUCCESS; +} diff --git a/core/dp/htt/htt.c b/core/dp/htt/htt.c index 58860948dd5e..1672a39c2ea5 100644 --- a/core/dp/htt/htt.c +++ b/core/dp/htt/htt.c @@ -434,9 +434,10 @@ int htt_update_endpoint(struct htt_pdev_t *pdev, QDF_BUG(service_id == HTT_DATA_MSG_SVC); pdev->htc_tx_endpoint = ep; + hif_save_htc_htt_config_endpoint(hif_ctx, ep); rc = 1; } - return rc; + return rc; } int htt_htc_attach(struct htt_pdev_t *pdev, uint16_t service_id) diff --git a/core/dp/htt/htt_h2t.c b/core/dp/htt/htt_h2t.c index a1c020279d4c..9662eb4d6980 100644 --- a/core/dp/htt/htt_h2t.c +++ b/core/dp/htt/htt_h2t.c @@ -178,6 +178,10 @@ A_STATUS htt_h2t_frag_desc_bank_cfg_msg(struct htt_pdev_t *pdev) SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); rc = htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt); +#ifdef ATH_11AC_TXCOMPACT + if (rc == A_OK) + htt_htc_misc_pkt_list_add(pdev, pkt); +#endif return rc; } diff --git a/core/dp/ol/inc/ol_txrx_ctrl_api.h b/core/dp/ol/inc/ol_txrx_ctrl_api.h index 203eb6983526..cb937ba6f75f 100644 --- a/core/dp/ol/inc/ol_txrx_ctrl_api.h +++ b/core/dp/ol/inc/ol_txrx_ctrl_api.h @@ -517,7 +517,7 @@ void ol_tx_flow_pool_unmap_handler(uint8_t flow_id, uint8_t flow_type, uint8_t flow_pool_id); struct ol_tx_flow_pool_t *ol_tx_create_flow_pool(uint8_t flow_pool_id, uint16_t flow_pool_size); -int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool); +int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool, bool force); #else static inline void ol_tx_register_flow_control(struct ol_txrx_pdev_t *pdev) @@ -551,7 +551,8 @@ static inline struct ol_tx_flow_pool_t *ol_tx_create_flow_pool( { return NULL; } -static inline int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool) +static inline int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool, + bool force) { return 0; } diff --git a/core/dp/txrx/ol_tx_queue.c b/core/dp/txrx/ol_tx_queue.c index 17030f1772bb..5490bff84ee0 100644 --- a/core/dp/txrx/ol_tx_queue.c +++ b/core/dp/txrx/ol_tx_queue.c @@ -182,6 +182,7 @@ ol_txrx_map_to_netif_reason_type(uint32_t reason) } } +#ifndef CONFIG_ICNSS /** * ol_txrx_vdev_pause() - pause vdev network queues * @vdev: vdev handle @@ -233,6 +234,7 @@ void ol_txrx_vdev_unpause(ol_txrx_vdev_handle vdev, uint32_t reason) netif_reason); } +#endif /** * ol_txrx_pdev_pause() - pause network queues for each vdev diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 2316b1e5cd4f..ad2dc54b6c48 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -1025,7 +1025,6 @@ void ol_txrx_pdev_detach(ol_txrx_pdev_handle pdev, int force) #endif #endif ol_tso_seg_list_deinit(pdev); - ol_tx_deregister_flow_control(pdev); if (force) { /* @@ -1045,6 +1044,7 @@ void ol_txrx_pdev_detach(ol_txrx_pdev_handle pdev, int force) ol_txrx_peer_find_hash_erase(pdev); } + ol_tx_deregister_flow_control(pdev); /* Stop the communication between HTT and target at first */ htt_detach_target(pdev->htt_pdev); @@ -2227,6 +2227,62 @@ void ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer) } /** + * ol_txrx_clear_peer_internal() - ol internal function to clear peer + * @peer: pointer to ol txrx peer structure + * + * Return: QDF Status + */ +static QDF_STATUS +ol_txrx_clear_peer_internal(struct ol_txrx_peer_t *peer) +{ + p_cds_sched_context sched_ctx = get_cds_sched_ctxt(); + /* Drop pending Rx frames in CDS */ + if (sched_ctx) + cds_drop_rxpkt_by_staid(sched_ctx, peer->local_id); + + /* Purge the cached rx frame queue */ + ol_txrx_flush_rx_frames(peer, 1); + + qdf_spin_lock_bh(&peer->peer_info_lock); + peer->vdev->rx = NULL; + peer->state = OL_TXRX_PEER_STATE_DISC; + qdf_spin_unlock_bh(&peer->peer_info_lock); + + return QDF_STATUS_SUCCESS; +} + +/** + * ol_txrx_clear_peer() - clear peer + * @sta_id: sta id + * + * Return: QDF Status + */ +QDF_STATUS ol_txrx_clear_peer(uint8_t sta_id) +{ + struct ol_txrx_peer_t *peer; + struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + + if (!pdev) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "%s: Unable to find pdev!", + __func__); + return QDF_STATUS_E_FAILURE; + } + + if (sta_id >= WLAN_MAX_STA_COUNT) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Invalid sta id %d", sta_id); + return QDF_STATUS_E_INVAL; + } + + + peer = ol_txrx_peer_find_by_local_id(pdev, sta_id); + if (!peer) + return QDF_STATUS_E_FAULT; + + return ol_txrx_clear_peer_internal(peer); + +} + +/** * ol_txrx_peer_detach - Delete a peer's data object. * @data_peer - the object to delete * @@ -2245,6 +2301,8 @@ void ol_txrx_peer_detach(ol_txrx_peer_handle peer) peer->valid = 0; + /* flush all rx packets before clearing up the peer local_id */ + ol_txrx_clear_peer_internal(peer); ol_txrx_local_peer_id_free(peer->vdev->pdev, peer); /* debug print to dump rx reorder state */ @@ -2256,7 +2314,6 @@ void ol_txrx_peer_detach(ol_txrx_peer_handle peer) peer->mac_addr.raw[0], peer->mac_addr.raw[1], peer->mac_addr.raw[2], peer->mac_addr.raw[3], peer->mac_addr.raw[4], peer->mac_addr.raw[5]); - ol_txrx_flush_rx_frames(peer, 1); if (peer->vdev->last_real_peer == peer) peer->vdev->last_real_peer = NULL; @@ -3455,6 +3512,7 @@ static void ol_rx_data_cb(struct ol_txrx_pdev_t *pdev, qdf_nbuf_t buf_list, uint16_t staid) { void *cds_ctx = cds_get_global_context(); + void *osif_dev; qdf_nbuf_t buf, next_buf; QDF_STATUS ret; ol_txrx_rx_fp data_rx = NULL; @@ -3478,6 +3536,7 @@ static void ol_rx_data_cb(struct ol_txrx_pdev_t *pdev, } data_rx = peer->vdev->rx; + osif_dev = peer->vdev->osif_dev; qdf_spin_unlock_bh(&peer->peer_info_lock); qdf_spin_lock_bh(&peer->bufq_lock); @@ -3492,7 +3551,7 @@ static void ol_rx_data_cb(struct ol_txrx_pdev_t *pdev, while (buf) { next_buf = qdf_nbuf_queue_next(buf); qdf_nbuf_set_next(buf, NULL); /* Add NULL terminator */ - ret = data_rx(peer->vdev->osif_dev, buf); + ret = data_rx(osif_dev, buf); if (ret != QDF_STATUS_SUCCESS) { TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Frame Rx to HDD failed"); qdf_nbuf_free(buf); @@ -3661,52 +3720,6 @@ QDF_STATUS ol_txrx_register_peer(struct ol_txrx_desc_type *sta_desc) } /** - * ol_txrx_clear_peer() - clear peer - * @sta_id: sta id - * - * Return: QDF Status - */ -QDF_STATUS ol_txrx_clear_peer(uint8_t sta_id) -{ - struct ol_txrx_peer_t *peer; - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "%s: Unable to find pdev!", - __func__); - return QDF_STATUS_E_FAILURE; - } - - if (sta_id >= WLAN_MAX_STA_COUNT) { - TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Invalid sta id %d", sta_id); - return QDF_STATUS_E_INVAL; - } - -#ifdef QCA_CONFIG_SMP - { - p_cds_sched_context sched_ctx = get_cds_sched_ctxt(); - /* Drop pending Rx frames in CDS */ - if (sched_ctx) - cds_drop_rxpkt_by_staid(sched_ctx, sta_id); - } -#endif - - peer = ol_txrx_peer_find_by_local_id(pdev, sta_id); - if (!peer) - return QDF_STATUS_E_FAULT; - - /* Purge the cached rx frame queue */ - ol_txrx_flush_rx_frames(peer, 1); - - qdf_spin_lock_bh(&peer->peer_info_lock); - peer->vdev->rx = NULL; - peer->state = OL_TXRX_PEER_STATE_DISC; - qdf_spin_unlock_bh(&peer->peer_info_lock); - - return QDF_STATUS_SUCCESS; -} - -/** * ol_txrx_register_ocb_peer - Function to register the OCB peer * @cds_ctx: Pointer to the global OS context * @mac_addr: MAC address of the self peer diff --git a/core/dp/txrx/ol_txrx_flow_control.c b/core/dp/txrx/ol_txrx_flow_control.c index a0d4404cb0d4..920f825f1ef5 100644 --- a/core/dp/txrx/ol_txrx_flow_control.c +++ b/core/dp/txrx/ol_txrx_flow_control.c @@ -82,7 +82,7 @@ ol_tx_register_global_mgmt_pool(struct ol_txrx_pdev_t *pdev) static void ol_tx_deregister_global_mgmt_pool(struct ol_txrx_pdev_t *pdev) { - ol_tx_delete_flow_pool(pdev->mgmt_pool); + ol_tx_delete_flow_pool(pdev->mgmt_pool, false); return; } #else @@ -121,14 +121,27 @@ void ol_tx_register_flow_control(struct ol_txrx_pdev_t *pdev) */ void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev) { + int i = 0; + struct ol_tx_flow_pool_t *pool = NULL; + if (!ol_tx_get_is_mgmt_over_wmi_enabled()) ol_tx_deregister_global_mgmt_pool(pdev); - qdf_spinlock_destroy(&pdev->tx_desc.flow_pool_list_lock); - if (!TAILQ_EMPTY(&pdev->tx_desc.flow_pool_list)) { + qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock); + while (!TAILQ_EMPTY(&pdev->tx_desc.flow_pool_list)) { + pool = TAILQ_FIRST(&pdev->tx_desc.flow_pool_list); + if (!pool) + break; + qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock); TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, - "flow pool list is not empty!!!\n"); + "flow pool list is not empty %d!!!\n", i++); + if (i == 1) + ol_tx_dump_flow_pool_info(); + ol_tx_delete_flow_pool(pool, true); + qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock); } + qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock); + qdf_spinlock_destroy(&pdev->tx_desc.flow_pool_list_lock); } /** @@ -381,13 +394,16 @@ struct ol_tx_flow_pool_t *ol_tx_create_flow_pool(uint8_t flow_pool_id, /** * ol_tx_delete_flow_pool() - delete flow pool * @pool: flow pool pointer + * @force: free pool forcefully * * Delete flow_pool if all tx descriptors are available. * Otherwise put it in FLOW_POOL_INVALID state. + * If force is set then pull all available descriptors to + * global pool. * * Return: 0 for success or error */ -int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool) +int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool, bool force) { struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); uint16_t i, size; @@ -405,7 +421,7 @@ int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool) qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock); qdf_spin_lock_bh(&pool->flow_pool_lock); - if (pool->avail_desc == pool->flow_pool_size) + if (pool->avail_desc == pool->flow_pool_size || force == true) pool->status = FLOW_POOL_INACTIVE; else pool->status = FLOW_POOL_INVALID; @@ -481,7 +497,7 @@ int ol_tx_free_invalid_flow_pool(struct ol_tx_flow_pool_t *pool) "%s: invalid pool deleted %d\n", __func__, pdev->tx_desc.num_invalid_bin); - return ol_tx_delete_flow_pool(pool); + return ol_tx_delete_flow_pool(pool, false); } /** @@ -624,7 +640,7 @@ void ol_tx_flow_pool_map_handler(uint8_t flow_id, uint8_t flow_type, break; default: if (pool_create) - ol_tx_delete_flow_pool(pool); + ol_tx_delete_flow_pool(pool, false); TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "%s: flow type %d not supported !!!\n", __func__, type); @@ -684,7 +700,7 @@ void ol_tx_flow_pool_unmap_handler(uint8_t flow_id, uint8_t flow_type, } /* only delete if all descriptors are available */ - ol_tx_delete_flow_pool(pool); + ol_tx_delete_flow_pool(pool, false); return; } diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 2d7795fa264c..98c9f9a35855 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -2121,15 +2121,18 @@ typedef enum { /* * Connection related log Enable/Disable. - * 0x1 - Enable mgmt pkt logs (no probe req/rsp). + * 0x1 - Enable mgmt pkt logs (excpet probe req/rsp, beacons). * 0x2 - Enable EAPOL pkt logs. * 0x4 - Enable DHCP pkt logs. + * 0x8 - Enable mgmt action frames logs. * 0x0 - Disable all the above connection related logs. + * + * The default value of 0x0F will enable all the above logs. */ #define CFG_ENABLE_DEBUG_CONNECT_ISSUE "gEnableDebugLog" #define CFG_ENABLE_DEBUG_CONNECT_ISSUE_MIN (0) #define CFG_ENABLE_DEBUG_CONNECT_ISSUE_MAX (0xFF) -#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_DEFAULT (0) +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_DEFAULT (0x0F) /* This will be used only for debugging purpose, will be removed after sometime */ #define CFG_ENABLE_RX_THREAD "gEnableRxThread" diff --git a/core/hdd/inc/wlan_hdd_napi.h b/core/hdd/inc/wlan_hdd_napi.h index 3c1683ded84c..f4bfa75f169a 100644 --- a/core/hdd/inc/wlan_hdd_napi.h +++ b/core/hdd/inc/wlan_hdd_napi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -68,7 +68,7 @@ struct qca_napi_data *hdd_napi_get_all(void); #define HDD_NAPI_ANY (-1) static inline int hdd_napi_enabled(int id) { return 0; } -static inline int hdd_napi_create(void) { return -EPERM; } +static inline int hdd_napi_create(void) { return 0; } static inline int hdd_napi_destroy(int force) { return 0; } static inline int hdd_napi_stats(char *buf, int max, char *indp, struct qca_napi_data *napid) diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index cad7ae03bc89..67066ebc1733 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -1259,7 +1259,6 @@ QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter, QDF_STATUS err; uint8_t *peer_mac_addr; struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - ol_txrx_vdev_handle vdev; ol_txrx_peer_handle peer; if (!pdev) { @@ -1309,6 +1308,7 @@ QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter, if (pAdapter->device_mode == QDF_STA_MODE || pAdapter->device_mode == QDF_P2P_CLIENT_MODE) { #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2) + ol_txrx_vdev_handle vdev; unsigned long rc; /* wait for event from firmware to set the event */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 7db20291e808..c8af93844f02 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -1396,6 +1396,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1]; bool ht_enabled, ht40_enabled, vht_enabled; uint8_t ch_width; + uint8_t weight_list[MAX_NUM_CHAN]; /* ***Note*** Donot set SME config related to ACS operation here because * ACS operation is not synchronouse and ACS for Second AP may come when @@ -1532,8 +1533,9 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, /* consult policy manager to get PCL */ status = cds_get_pcl(CDS_SAP_MODE, - sap_config->acs_cfg.pcl_channels, - &sap_config->acs_cfg.pcl_ch_count); + sap_config->acs_cfg.pcl_channels, + &sap_config->acs_cfg.pcl_ch_count, + weight_list, QDF_ARRAY_SIZE(weight_list)); if (QDF_STATUS_SUCCESS != status) hddLog(LOGE, FL("Get PCL failed")); @@ -4215,7 +4217,7 @@ static int __wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy, hdd_context_t *hdd_ctx = wiphy_priv(wiphy); int i, ret = 0; QDF_STATUS status; - uint8_t pcl[MAX_NUM_CHAN]; + uint8_t pcl[MAX_NUM_CHAN], weight_list[MAX_NUM_CHAN]; uint32_t pcl_len = 0; uint32_t freq_list[MAX_NUM_CHAN]; enum cds_con_mode intf_mode; @@ -4249,7 +4251,8 @@ static int __wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy, hdd_debug("Userspace requested pref freq list"); - status = cds_get_pcl(intf_mode, pcl, &pcl_len); + status = cds_get_pcl(intf_mode, pcl, &pcl_len, + weight_list, QDF_ARRAY_SIZE(weight_list)); if (status != QDF_STATUS_SUCCESS) { hdd_err("Get pcl failed"); return -EINVAL; diff --git a/core/hdd/src/wlan_hdd_conc_ut.c b/core/hdd/src/wlan_hdd_conc_ut.c index 8b7882e3990d..d42391602485 100644 --- a/core/hdd/src/wlan_hdd_conc_ut.c +++ b/core/hdd/src/wlan_hdd_conc_ut.c @@ -625,7 +625,7 @@ void wlan_hdd_one_connection_scenario(hdd_context_t *hdd_ctx) enum cds_con_mode sub_type; enum cds_conc_priority_mode system_pref = hdd_ctx->config->conc_system_pref; - uint8_t pcl[MAX_NUM_CHAN] = {0}; + uint8_t pcl[MAX_NUM_CHAN] = {0}, weight_list[MAX_NUM_CHAN] = {0}; uint32_t pcl_len = 0; bool status = false; enum cds_pcl_type pcl_type; @@ -651,7 +651,8 @@ void wlan_hdd_one_connection_scenario(hdd_context_t *hdd_ctx) pcl_type = get_pcl_from_first_conn_table(sub_type, system_pref); /* check PCL value for second connection is correct or no */ - cds_get_pcl(sub_type, pcl, &pcl_len); + cds_get_pcl(sub_type, pcl, &pcl_len, + weight_list, QDF_ARRAY_SIZE(weight_list)); status = wlan_hdd_validate_pcl(hdd_ctx, pcl_type, pcl, pcl_len, 0, 0, reason, sizeof(reason)); @@ -671,7 +672,7 @@ void wlan_hdd_two_connections_scenario(hdd_context_t *hdd_ctx, { uint8_t vdevid = 0, tx_stream = 2, rx_stream = 2; uint8_t type = WMI_VDEV_TYPE_STA, channel_id = first_chnl, mac_id = 1; - uint8_t pcl[MAX_NUM_CHAN] = {0}; + uint8_t pcl[MAX_NUM_CHAN] = {0}, weight_list[MAX_NUM_CHAN] = {0}; uint32_t pcl_len = 0; enum cds_chain_mode chain_mask = first_chain_mask; enum cds_con_mode sub_type, next_sub_type, dummy_type; @@ -723,7 +724,8 @@ void wlan_hdd_two_connections_scenario(hdd_context_t *hdd_ctx, next_sub_type, system_pref, wma_is_hw_dbs_capable()); /* check PCL for second connection is correct or no */ - cds_get_pcl(next_sub_type, pcl, &pcl_len); + cds_get_pcl(next_sub_type, pcl, &pcl_len, + weight_list, QDF_ARRAY_SIZE(weight_list)); status = wlan_hdd_validate_pcl(hdd_ctx, pcl_type, pcl, pcl_len, channel_id, 0, reason, sizeof(reason)); @@ -749,7 +751,7 @@ void wlan_hdd_three_connections_scenario(hdd_context_t *hdd_ctx, uint8_t channel_id_1 = first_chnl, channel_id_2 = second_chnl; uint8_t mac_id_1, mac_id_2; uint8_t type_1 = WMI_VDEV_TYPE_STA, type_2 = WMI_VDEV_TYPE_STA; - uint8_t pcl[MAX_NUM_CHAN] = {0}; + uint8_t pcl[MAX_NUM_CHAN] = {0}, weight_list[MAX_NUM_CHAN] = {0}; uint32_t pcl_len = 0; enum cds_chain_mode chain_mask_1; enum cds_chain_mode chain_mask_2; @@ -838,7 +840,9 @@ void wlan_hdd_three_connections_scenario(hdd_context_t *hdd_ctx, system_pref, wma_is_hw_dbs_capable()); cds_get_pcl(next_sub_type, - pcl, &pcl_len); + pcl, &pcl_len, + weight_list, + QDF_ARRAY_SIZE(weight_list)); status = wlan_hdd_validate_pcl(hdd_ctx, pcl_type, pcl, pcl_len, channel_id_1, channel_id_2, diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index 3d72466d9608..1649840e98ae 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -256,7 +256,9 @@ static int hdd_hif_open(struct device *dev, void *bdev, const hif_bus_id *bid, } else { ret = hdd_napi_create(); hdd_info("hdd_napi_create returned: %d", ret); - if (ret <= 0) { + if (ret == 0) + hdd_warn("NAPI: no instances are created"); + else if (ret < 0) { hdd_err("NAPI creation error, rc: 0x%x, reinit = %d", ret, reinit); ret = -EFAULT; diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 124d601a2cdb..f8f4137c4e6c 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -7927,13 +7927,15 @@ static int __iw_set_var_ints_getnone(struct net_device *dev, case WE_POLICY_MANAGER_PCL_CMD: { uint8_t pcl[MAX_NUM_CHAN] = {0}; + uint8_t weight_list[MAX_NUM_CHAN] = {0}; uint32_t pcl_len = 0, i = 0; hddLog(LOGE, FL("<iwpriv wlan0 pm_pcl> is called\n")); cds_get_pcl(apps_args[0], - pcl, &pcl_len); + pcl, &pcl_len, + weight_list, QDF_ARRAY_SIZE(weight_list)); pr_info("PCL list for role[%d] is {", apps_args[0]); for (i = 0 ; i < pcl_len; i++) pr_info(" %d, ", pcl[i]); diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h index 494519e7cc59..e2bc89c4297a 100644 --- a/core/mac/inc/qwlan_version.h +++ b/core/mac/inc/qwlan_version.h @@ -41,10 +41,10 @@ #define QWLAN_VERSION_MAJOR 5 #define QWLAN_VERSION_MINOR 1 #define QWLAN_VERSION_PATCH 0 -#define QWLAN_VERSION_EXTRA "A" -#define QWLAN_VERSION_BUILD 3 +#define QWLAN_VERSION_EXTRA "" +#define QWLAN_VERSION_BUILD 4 -#define QWLAN_VERSIONSTR "5.1.0.3A" +#define QWLAN_VERSIONSTR "5.1.0.4" /* 172 */ #endif /* QWLAN_VERSION_H */ diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index cf0870c5f891..5c5ff30e87f9 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -3205,14 +3205,37 @@ enum set_hw_mode_status { /** * struct sir_pcl_list - Format of PCL * @pcl_list: List of preferred channels + * @weight_list: Weights of the PCL * @pcl_len: Number of channels in the PCL */ struct sir_pcl_list { uint8_t pcl_list[128]; + uint8_t weight_list[128]; uint32_t pcl_len; }; /** + * struct sir_pcl_chan_weights - Params to get the valid weighed list + * @pcl_list: Preferred channel list already sorted in the order of preference + * @pcl_len: Length of the PCL + * @saved_chan_list: Valid channel list updated as part of + * WMA_UPDATE_CHAN_LIST_REQ + * @saved_num_chan: Length of the valid channel list + * @weighed_valid_list: Weights of the valid channel list. This will have one + * to one mapping with valid_chan_list. FW expects channel order and size to be + * as per the list provided in WMI_SCAN_CHAN_LIST_CMDID. + * @weight_list: Weights assigned by policy manager + */ +struct sir_pcl_chan_weights { + uint8_t pcl_list[128]; + uint32_t pcl_len; + uint8_t saved_chan_list[128]; + uint32_t saved_num_chan; + uint8_t weighed_valid_list[128]; + uint8_t weight_list[128]; +}; + +/** * struct sir_hw_mode_params - HW mode params * @mac0_tx_ss: MAC0 Tx spatial stream * @mac0_rx_ss: MAC0 Rx spatial stream diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index b1e08297c0ed..6287638b2b8f 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -421,7 +421,7 @@ typedef struct sSirMbMsgP2p { #define SIR_HAL_FLUSH_LOG_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 160) -#define SIR_HAL_SOC_SET_PCL_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161) +#define SIR_HAL_PDEV_SET_PCL_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161) /* 162 unused */ 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 75b4b5a06be0..db836f05c46f 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 @@ -526,7 +526,7 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg) CASE_RETURN_STRING(SIR_HAL_CONFIG_GUARD_TIME); CASE_RETURN_STRING(SIR_HAL_START_STOP_LOGGING); CASE_RETURN_STRING(SIR_HAL_FLUSH_LOG_TO_FW); - CASE_RETURN_STRING(SIR_HAL_SOC_SET_PCL_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_SOC_DUAL_MAC_CFG_REQ); CASE_RETURN_STRING(WMA_RADAR_DETECTED_IND); diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index fbb94a8b3394..9be884d40020 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -4488,7 +4488,8 @@ static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext) } status = cds_get_pcl_for_existing_conn(CDS_SAP_MODE, - pcl.pcl_list, &pcl.pcl_len); + pcl.pcl_list, &pcl.pcl_len, + pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); if (status != QDF_STATUS_SUCCESS) { cds_err("Get PCL failed"); return status; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index a41f85b5a9bf..d836a36a0389 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -986,7 +986,7 @@ QDF_STATUS sme_update_nss(tHalHandle h_hal, uint8_t nss); bool sme_is_any_session_in_connected_state(tHalHandle h_hal); -QDF_STATUS sme_soc_set_pcl(tHalHandle hal, +QDF_STATUS sme_pdev_set_pcl(tHalHandle hal, struct sir_pcl_list msg); QDF_STATUS sme_soc_set_hw_mode(tHalHandle hal, struct sir_hw_mode msg); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 52439872e079..c12aef820c50 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -14797,20 +14797,20 @@ QDF_STATUS sme_fw_mem_dump(tHalHandle hHal, void *recvd_req) #endif /* WLAN_FEATURE_MEMDUMP */ /* - * sme_soc_set_pcl() - Send WMI_SOC_SET_PCL_CMDID to the WMA + * sme_pdev_set_pcl() - Send WMI_PDEV_SET_PCL_CMDID to the WMA * @hal: Handle returned by macOpen * @msg: PCL channel list and length structure * - * Sends the command to WMA to send WMI_SOC_SET_PCL_CMDID to FW + * Sends the command to WMA to send WMI_PDEV_SET_PCL_CMDID to FW * Return: QDF_STATUS_SUCCESS on successful posting */ -QDF_STATUS sme_soc_set_pcl(tHalHandle hal, +QDF_STATUS sme_pdev_set_pcl(tHalHandle hal, struct sir_pcl_list msg) { QDF_STATUS status = QDF_STATUS_SUCCESS; tpAniSirGlobal mac = PMAC_STRUCT(hal); cds_msg_t cds_message; - struct sir_pcl_list *req_msg; + struct wmi_pcl_chan_weights *req_msg; uint32_t len, i; len = sizeof(*req_msg); @@ -14823,8 +14823,10 @@ QDF_STATUS sme_soc_set_pcl(tHalHandle hal, qdf_mem_zero(req_msg, len); - for (i = 0; i < msg.pcl_len; i++) + for (i = 0; i < msg.pcl_len; i++) { req_msg->pcl_list[i] = msg.pcl_list[i]; + req_msg->weight_list[i] = msg.weight_list[i]; + } req_msg->pcl_len = msg.pcl_len; @@ -14839,7 +14841,7 @@ QDF_STATUS sme_soc_set_pcl(tHalHandle hal, /* Serialize the req through MC thread */ cds_message.bodyptr = req_msg; - cds_message.type = SIR_HAL_SOC_SET_PCL_TO_FW; + cds_message.type = SIR_HAL_PDEV_SET_PCL_TO_FW; status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); if (!QDF_IS_STATUS_SUCCESS(status)) { sms_log(mac, LOGE, diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index a7cd0987b30c..87ceec5baa58 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -1991,6 +1991,7 @@ csr_parse_scan_results(tpAniSirGlobal pMac, eCsrAuthType auth = eCSR_AUTH_TYPE_OPEN_SYSTEM; uint32_t len = 0; enum cds_con_mode new_mode; + uint8_t weight_list[MAX_NUM_CHAN]; csr_ll_lock(&pMac->scan.scanResultList); @@ -1999,7 +2000,8 @@ csr_parse_scan_results(tpAniSirGlobal pMac, if (cds_map_concurrency_mode( &pFilter->csrPersona, &new_mode)) { status = cds_get_pcl(new_mode, - &pFilter->pcl_channels.channelList[0], &len); + &pFilter->pcl_channels.channelList[0], &len, + weight_list, QDF_ARRAY_SIZE(weight_list)); pFilter->pcl_channels.numChannels = (uint8_t)len; } } diff --git a/core/utils/epping/src/epping_txrx.c b/core/utils/epping/src/epping_txrx.c index 4586b1033fe8..8196bf908056 100644 --- a/core/utils/epping/src/epping_txrx.c +++ b/core/utils/epping/src/epping_txrx.c @@ -390,7 +390,6 @@ epping_adapter_t *epping_add_adapter(epping_context_t *pEpping_ctx, int epping_connect_service(epping_context_t *pEpping_ctx) { int status, i; - int ret = -1; HTC_SERVICE_CONNECT_REQ connect; HTC_SERVICE_CONNECT_RESP response; @@ -421,9 +420,9 @@ int epping_connect_service(epping_context_t *pEpping_ctx) status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response); if (status != EOK) { EPPING_LOG(QDF_TRACE_LEVEL_FATAL, - "Failed to connect to Endpoint Ping BE service status:%d \n", + "Failed to connect to Endpoint Ping BE service status:%d\n", status); - return -1;; + return status; } else { EPPING_LOG(QDF_TRACE_LEVEL_FATAL, "eppingtest BE endpoint:%d\n", response.Endpoint); @@ -435,9 +434,9 @@ int epping_connect_service(epping_context_t *pEpping_ctx) status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response); if (status != EOK) { EPPING_LOG(QDF_TRACE_LEVEL_FATAL, - "Failed to connect to Endpoint Ping BK service status:%d \n", + "Failed to connect to Endpoint Ping BK service status:%d\n", status); - return ret; + return status; } else { EPPING_LOG(QDF_TRACE_LEVEL_FATAL, "eppingtest BK endpoint:%d\n", response.Endpoint); diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index e9553ffe94f6..ff9dca2f5a70 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1042,6 +1042,17 @@ struct wma_ini_config { }; /** + * struct wmi_valid_channels - Channel details part of WMI_SCAN_CHAN_LIST_CMDID + * @num_channels: Number of channels + * @channel_list: Channel list + */ +struct wma_valid_channels { + uint8_t num_channels; + uint8_t channel_list[MAX_NUM_CHAN]; +}; + + +/** * struct t_wma_handle - wma context * @wmi_handle: wmi handle * @htc_handle: htc handle @@ -1165,6 +1176,7 @@ struct wma_ini_config { * @service_ready_ext_evt: Wait event for service ready ext * @wmi_cmd_rsp_wake_lock: wmi command response wake lock * @wmi_cmd_rsp_runtime_lock: wmi command response bus lock + * @saved_chan: saved channel list sent as part of WMI_SCAN_CHAN_LIST_CMDID */ typedef struct { void *wmi_handle; @@ -1350,6 +1362,7 @@ typedef struct { qdf_runtime_lock_t wma_runtime_resume_lock; uint32_t fine_time_measurement_cap; struct wma_ini_config ini_config; + struct wma_valid_channels saved_chan; } t_wma_handle, *tp_wma_handle; /** @@ -1956,8 +1969,8 @@ void wma_log_completion_timeout(void *data); QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma, struct rssi_monitor_req *req); -QDF_STATUS wma_send_soc_set_pcl_cmd(tp_wma_handle wma_handle, - struct sir_pcl_list *msg); +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, struct sir_hw_mode *msg); diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 42ca332a8646..572b7d91a1d8 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -2633,8 +2633,8 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, if (pFc->subType == SIR_MAC_MGMT_ACTION) proto_type = cds_pkt_get_proto_type(tx_frame, pMac->fEnableDebugLog, - NBUF_PKT_TRAC_TYPE_MGMT_ACTION); - if (proto_type & NBUF_PKT_TRAC_TYPE_MGMT_ACTION) + CDS_PKT_TRAC_TYPE_MGMT_ACTION); + if (proto_type & CDS_PKT_TRAC_TYPE_MGMT_ACTION) cds_pkt_trace_buf_update("WM:T:MACT"); qdf_nbuf_trace_set_proto_type(tx_frame, proto_type); #endif /* QCA_PKT_PROTO_TRACE */ diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index fe9d40f56b34..23312de758f2 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -5695,21 +5695,18 @@ QDF_STATUS wma_suspend_target(WMA_HANDLE handle, int disable_target_intr) QDF_STATUS status; struct suspend_params param = {0}; -#ifdef CONFIG_CNSS tpAniSirGlobal pmac = cds_get_context(QDF_MODULE_ID_PE); -#endif if (!wma_handle || !wma_handle->wmi_handle) { WMA_LOGE("WMA is closed. can not issue suspend cmd"); return QDF_STATUS_E_INVAL; } -#ifdef CONFIG_CNSS if (NULL == pmac) { WMA_LOGE("%s: Unable to get PE context", __func__); return QDF_STATUS_E_INVAL; } -#endif + qdf_event_reset(&wma_handle->target_suspend); param.disable_target_intr = disable_target_intr; status = wmi_unified_suspend_send(wma_handle->wmi_handle, @@ -5772,7 +5769,6 @@ void wma_target_suspend_acknowledge(void *context) */ QDF_STATUS wma_resume_target(WMA_HANDLE handle) { - int ret; tp_wma_handle wma = (tp_wma_handle) handle; QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; #ifdef CONFIG_CNSS @@ -5818,7 +5814,7 @@ QDF_STATUS wma_resume_target(WMA_HANDLE handle) if (QDF_STATUS_SUCCESS == qdf_status) wmi_set_target_suspend(wma->wmi_handle, false); - return ret; + return qdf_status; } #ifdef FEATURE_WLAN_TDLS diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 06e5da0b548a..723ff4921eb8 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -1798,6 +1798,7 @@ QDF_STATUS wma_open(void *cds_context, wma_handle->dfs_radar_indication_cb = radar_ind_cb; wma_handle->old_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX; wma_handle->new_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX; + wma_handle->saved_chan.num_channels = 0; qdf_status = qdf_event_create(&wma_handle->wma_ready_event); if (qdf_status != QDF_STATUS_SUCCESS) { @@ -5165,9 +5166,9 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg) (struct fw_dump_req *)msg->bodyptr); qdf_mem_free(msg->bodyptr); break; - case SIR_HAL_SOC_SET_PCL_TO_FW: - wma_send_soc_set_pcl_cmd(wma_handle, - (struct sir_pcl_list *)msg->bodyptr); + case SIR_HAL_PDEV_SET_PCL_TO_FW: + wma_send_pdev_set_pcl_cmd(wma_handle, + (struct wmi_pcl_chan_weights *)msg->bodyptr); qdf_mem_free(msg->bodyptr); break; case SIR_HAL_SOC_SET_HW_MODE: @@ -5297,30 +5298,49 @@ void wma_log_completion_timeout(void *data) } /** - * wma_send_soc_set_pcl_cmd() - Send WMI_SOC_SET_PCL_CMDID to FW + * wma_send_pdev_set_pcl_cmd() - Send WMI_SOC_SET_PCL_CMDID to FW * @wma_handle: WMA handle * @msg: PCL structure containing the PCL and the number of channels * - * WMI_SOC_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN + * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN * firmware. The DBS Manager is the consumer of this information in the WLAN * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs * to migrate to a new channel without host driver involvement. An example of * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will * manage the channel selection without firmware involvement. * + * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual + * channel list. The weights corresponds to the channels sent in + * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher + * weightage compared to the non PCL channels. + * * Return: Success if the cmd is sent successfully to the firmware */ -QDF_STATUS wma_send_soc_set_pcl_cmd(tp_wma_handle wma_handle, - struct sir_pcl_list *msg) +QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle, + struct wmi_pcl_chan_weights *msg) { + uint32_t i; + QDF_STATUS status; + if (!wma_handle) { WMA_LOGE("%s: WMA handle is NULL. Cannot issue command", __func__); return QDF_STATUS_E_NULL_VALUE; } - if (wmi_unified_soc_set_pcl_cmd(wma_handle->wmi_handle, - (struct wmi_pcl_list *) msg)) + for (i = 0; i < wma_handle->saved_chan.num_channels; i++) { + msg->saved_chan_list[i] = + wma_handle->saved_chan.channel_list[i]; + } + + msg->saved_num_chan = wma_handle->saved_chan.num_channels; + status = cds_get_valid_chan_weights((struct sir_pcl_chan_weights *)msg); + if (!QDF_IS_STATUS_SUCCESS(status)) { + WMA_LOGE("%s: Error in creating weighed pcl", __func__); + return status; + } + + if (wmi_unified_pdev_set_pcl_cmd(wma_handle->wmi_handle, msg)) return QDF_STATUS_E_FAILURE; return QDF_STATUS_SUCCESS; diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 78d57ac32921..295cde659da1 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -642,6 +642,7 @@ QDF_STATUS wma_update_channel_list(WMA_HANDLE handle, WMA_LOGD("no of channels = %d", chan_list->numChan); tchan_info = scan_ch_param.chan_info; scan_ch_param.num_scan_chans = chan_list->numChan; + wma_handle->saved_chan.num_channels = chan_list->numChan; for (i = 0; i < chan_list->numChan; ++i) { tchan_info->mhz = @@ -649,8 +650,11 @@ QDF_STATUS wma_update_channel_list(WMA_HANDLE handle, tchan_info->band_center_freq1 = tchan_info->mhz; tchan_info->band_center_freq2 = 0; + wma_handle->saved_chan.channel_list[i] = + chan_list->chanParam[i].chanId; - WMA_LOGD("chan[%d] = %u", i, tchan_info->mhz); + WMA_LOGD("chan[%d] = freq:%u chan:%d", i, tchan_info->mhz, + chan_list->chanParam[i].chanId); if (chan_list->chanParam[i].dfsSet) { WMI_SET_CHANNEL_FLAG(tchan_info, WMI_CHAN_FLAG_PASSIVE); WMA_LOGI("chan[%d] DFS[%d]\n", |
