From 4a37fc74a2aef6e9f07b51da59c578c029661808 Mon Sep 17 00:00:00 2001 From: Ivan Priest Date: Mon, 17 Sep 2018 14:02:14 +0100 Subject: [PATCH] [RAMEN9610-10521][9610] wlbt: fix for kernel panic and changes for function improvement 1) generate sable tar on wifi disconnect 2) disable log collection for default 3) Memleaks and unexpected break fall through is fixed 4) Fix compile errors when various optional features disabled 5) Protect hip dereferencing 6) zero out BT/A-BOX ringbuffer on BT crash 7) Improve scsc_mx Makefile modules compatibility 8) CONTROL_ROAMING feature in FW 9) Improve collection speed 10)vif cleanup changes 11) Initialize g_spinlock lock bugdb : REL-1633 Change-Id: Iad9b3c652a91cd4a9164801e96cd145367f08778 --- arch/arm64/configs/erd9610_defconfig | 1 + drivers/hid/hid-input.c | 7 + drivers/hid/uhid.c | 46 +- drivers/misc/samsung/kic/Makefile | 2 +- drivers/misc/samsung/scsc/Kconfig | 22 +- drivers/misc/samsung/scsc/Makefile | 124 +- drivers/misc/samsung/scsc/miframman.c | 16 + drivers/misc/samsung/scsc/miframman.h | 9 + drivers/misc/samsung/scsc/mx140_file.c | 15 +- drivers/misc/samsung/scsc/mx250_fm.c | 10 +- drivers/misc/samsung/scsc/mx250_fm_test.c | 2 +- drivers/misc/samsung/scsc/mxconf.h | 21 +- drivers/misc/samsung/scsc/mxlog.c | 4 +- drivers/misc/samsung/scsc/mxlogger.c | 68 +- drivers/misc/samsung/scsc/mxman.c | 92 +- drivers/misc/samsung/scsc/mxman.h | 6 +- drivers/misc/samsung/scsc/pcie_mif.c | 22 + drivers/misc/samsung/scsc/platform_mif.c | 15 +- .../misc/samsung/scsc/scsc_log_collector.c | 37 +- drivers/misc/samsung/scsc/scsc_logring_main.c | 29 +- drivers/misc/samsung/scsc/scsc_logring_ring.c | 2 +- drivers/misc/samsung/scsc/scsc_mif_abs.h | 6 + drivers/misc/samsung/scsc/scsc_mx_impl.c | 16 + drivers/misc/samsung/scsc/scsc_mx_impl.h | 3 + drivers/misc/samsung/scsc/scsc_mx_module.c | 3 - drivers/misc/samsung/scsc/scsc_service.c | 78 +- drivers/misc/samsung/scsc/scsc_wlbtd.c | 28 +- drivers/misc/samsung/scsc/scsc_wlbtd.h | 2 +- drivers/misc/samsung/scsc/srvman.h | 4 + drivers/misc/samsung/scsc_bt/Makefile | 4 +- drivers/misc/samsung/scsc_bt/scsc_bt_module.c | 87 +- drivers/misc/samsung/scsc_bt/scsc_bt_priv.h | 7 +- drivers/misc/samsung/scsc_bt/scsc_shm.c | 7 + drivers/net/wireless/scsc/Kconfig | 12 + drivers/net/wireless/scsc/Makefile | 87 +- drivers/net/wireless/scsc/acm_api.c | 74 + drivers/net/wireless/scsc/ba.c | 25 +- drivers/net/wireless/scsc/cfg80211_ops.c | 159 +- drivers/net/wireless/scsc/cm_if.c | 3 +- drivers/net/wireless/scsc/debug.h | 17 +- drivers/net/wireless/scsc/dev.c | 24 +- drivers/net/wireless/scsc/dev.h | 100 +- drivers/net/wireless/scsc/fapi.h | 4 +- drivers/net/wireless/scsc/hip4.c | 813 ++++++- drivers/net/wireless/scsc/hip4.h | 45 +- drivers/net/wireless/scsc/hip4_sampler.c | 19 +- drivers/net/wireless/scsc/hip4_smapper.c | 16 +- drivers/net/wireless/scsc/ioctl.c | 18 +- drivers/net/wireless/scsc/mgt.c | 513 ++++- drivers/net/wireless/scsc/mgt.h | 19 +- drivers/net/wireless/scsc/mib.c | 48 +- drivers/net/wireless/scsc/mib.h | 2036 ++++++++++++----- drivers/net/wireless/scsc/mlme.c | 341 ++- drivers/net/wireless/scsc/mlme.h | 10 +- drivers/net/wireless/scsc/netif.c | 108 +- drivers/net/wireless/scsc/nl80211_vendor.c | 680 +++++- drivers/net/wireless/scsc/nl80211_vendor.h | 211 +- drivers/net/wireless/scsc/procfs.c | 60 +- drivers/net/wireless/scsc/rx.c | 46 +- drivers/net/wireless/scsc/sap_ma.c | 462 ++-- drivers/net/wireless/scsc/sap_mlme.c | 26 +- drivers/net/wireless/scsc/sap_test.c | 3 + drivers/net/wireless/scsc/scsc_wifi_fcq.c | 20 +- drivers/net/wireless/scsc/src_sink.c | 1 + drivers/net/wireless/scsc/test/Makefile | 2 +- drivers/net/wireless/scsc/traffic_monitor.c | 14 +- drivers/net/wireless/scsc/tx.c | 6 + drivers/net/wireless/scsc/utils.h | 2 +- include/scsc/api/bsmhcp.h | 2 +- include/scsc/scsc_logring.h | 112 +- include/scsc/scsc_mx.h | 11 +- include/scsc/scsc_release.h | 2 +- 72 files changed, 5394 insertions(+), 1552 deletions(-) mode change 100644 => 100755 arch/arm64/configs/erd9610_defconfig create mode 100755 drivers/net/wireless/scsc/acm_api.c mode change 100755 => 100644 drivers/net/wireless/scsc/mib.h diff --git a/arch/arm64/configs/erd9610_defconfig b/arch/arm64/configs/erd9610_defconfig old mode 100644 new mode 100755 index 1e27d7532f02..e07269593137 --- a/arch/arm64/configs/erd9610_defconfig +++ b/arch/arm64/configs/erd9610_defconfig @@ -577,3 +577,4 @@ CONFIG_EXYNOS_FMP=y CONFIG_LTO_CLANG=y CONFIG_CFI_CLANG=y #CONFIG_CFI_PERMISSIVE=y +CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION=y diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index bb984cc9753b..b39369987792 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -94,6 +94,8 @@ static bool match_index(struct hid_usage *usage, typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage, unsigned int cur_idx, unsigned int val); +extern bool lcd_is_on; + static struct hid_usage *hidinput_find_key(struct hid_device *hid, hid_usage_cmp_t match, unsigned int value, @@ -1402,6 +1404,11 @@ static void hidinput_led_worker(struct work_struct *work) if (!buf) return; + if (!lcd_is_on) { + kfree(buf); + return; + } + hid_output_report(report, buf); /* synchronous output report */ ret = hid_hw_output_report(hid, buf, len); diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 6f819f144cb4..e3ec968cdf41 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -24,6 +24,7 @@ #include #include #include +#include #define UHID_NAME "uhid" #define UHID_BUFSIZE 32 @@ -55,6 +56,7 @@ struct uhid_device { }; static struct miscdevice uhid_misc; +bool lcd_is_on = true; static void uhid_device_add_worker(struct work_struct *work) { @@ -780,8 +782,50 @@ static struct miscdevice uhid_misc = { .minor = UHID_MINOR, .name = UHID_NAME, }; -module_misc_device(uhid_misc); +static int fb_state_change(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct fb_event *evdata = data; + unsigned int blank; + + dbg_hid("fb_state_change"); + if (val != FB_EVENT_BLANK) + return 0; + + blank = *(int *)evdata->data; + + switch (blank) { + case FB_BLANK_POWERDOWN: + lcd_is_on = false; + break; + case FB_BLANK_UNBLANK: + lcd_is_on = true; + break; + default: + break; + } + + return NOTIFY_OK; +} +static struct notifier_block fb_block = { + .notifier_call = fb_state_change, +}; + +static int __init uhid_init(void) +{ + fb_register_client(&fb_block); + return misc_register(&uhid_misc); +} + +static void __exit uhid_exit(void) +{ + fb_unregister_client(&fb_block); + misc_deregister(&uhid_misc); +} + +module_init(uhid_init); +module_exit(uhid_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Herrmann "); MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem"); diff --git a/drivers/misc/samsung/kic/Makefile b/drivers/misc/samsung/kic/Makefile index ef9f6f833f8b..f865ef35c939 100644 --- a/drivers/misc/samsung/kic/Makefile +++ b/drivers/misc/samsung/kic/Makefile @@ -15,4 +15,4 @@ ccflags-y += $(CONFIG_SAMSUNG_KIC_EXTRA) ccflags-$(CONFIG_SLSI_KIC_API_ENABLED) += -DCONFIG_SLSI_KIC_API_ENABLED -ccflags-$(CONFIG_SCSC_DEBUG) += -DCONFIG_SCSC_PRINTK +ccflags-$(CONFIG_SCSC_LOGRING) += -DCONFIG_SCSC_PRINTK diff --git a/drivers/misc/samsung/scsc/Kconfig b/drivers/misc/samsung/scsc/Kconfig index 23856cfa7d57..cdb660bbfec5 100644 --- a/drivers/misc/samsung/scsc/Kconfig +++ b/drivers/misc/samsung/scsc/Kconfig @@ -56,6 +56,13 @@ config SCSC_WLBTD ---help--- Uses generic netlink messages to communicate events to userspace daemon which takes necessary actions e.g. taking moredump +config SCSC_QOS + bool "Samsung SCSC kernel PM QoS support" + default y + depends on SCSC_CORE + ---help--- + SCSC_QOS provides support to configure kernel PM QoS to register configuration as per performance expectations + config SCSC_PLATFORM tristate "Samsung SCSC MIF Platform driver implementation" depends on SCSC_CORE @@ -73,7 +80,7 @@ config SCSC_CLK20MHZ depends on SCSC_CORE config SCSC_CLK20MHZ_TEST - tristate "Samsung SCSC USB 20MHz Clock Test" + bool "Samsung SCSC USB 20MHz Clock Test" depends on SCSC_CLK20MHZ config SCSC_FM @@ -81,7 +88,7 @@ config SCSC_FM depends on SCSC_CORE config SCSC_FM_TEST - tristate "Samsung SCSC MX250 Test for enabling LDOs used for FM" + bool "Samsung SCSC MX250 Test for enabling LDOs used for FM" depends on SCSC_FM config SCSC_MMAP @@ -99,13 +106,18 @@ config SCSC_DEBUG config SCSC_DEBUG_COMPATIBILITY bool "Samsung SCSC Logging mode" - depends on SCSC_DEBUG default y +config SCSC_LOGRING + tristate "Samsung SCSC Kernel Logging" + default y + ---help--- + SCSC Drivers logging mechanism + config SCSC_STATIC_RING tristate "Samsung SCSC Logging use static ring" - depends on SCSC_DEBUG - default n + depends on SCSC_LOGRING + default y config SCSC_STATIC_RING_SIZE int "Size of the static ring" diff --git a/drivers/misc/samsung/scsc/Makefile b/drivers/misc/samsung/scsc/Makefile index 759e8a4d1efc..8f3335003afd 100644 --- a/drivers/misc/samsung/scsc/Makefile +++ b/drivers/misc/samsung/scsc/Makefile @@ -1,66 +1,72 @@ -############################################################################# -# -# Copyright (c) 2014 - 2016 Samsung Electronics Co., Ltd. All rights reserved -# -############################################################################# +######################################################################## +# Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved # +######################################################################## # Needed since this subdir is symlinked in the main Kernel tree # without this our samsung subdir is NOT cleaned. clean-files := *.o *.ko -ifneq ($(CONFIG_SCSC_CORE),n) - -ccflags-y += -Iinclude/scsc ccflags-y += $(CONFIG_SAMSUNG_MAXWELL_EXTRA) -obj-$(CONFIG_SCSC_DEBUG) += scsc_logring.o -scsc_logring-y += scsc_logring_main.o scsc_logring_ring.o scsc_logring_debugfs.o - -obj-$(CONFIG_SCSC_LOG_COLLECTION) += scsc_log_collection.o -scsc_log_collection-y += scsc_log_collector.o scsc_log_collector_proc.o scsc_log_collector_mmap.o -## -## The following cumbersome ifeq/else is the only way to make -## this CONFIG_SCSC_PRINTK propagate correctly in any scenario (y,m,n) -## Otherwise using ONLY the else branch when CONFIG_SCSC_DEBUG evaluates -## to m ==>> ccflags-m does NOT work correctly in every build scenario: -## - kernel debug modules : builtin with scsc_logring support -## - kernel nodebug modules : builtins without scsc_logring support -## - kernel debug|nodebug nomodules : no builtin / no scsclogring -## +# No such thing as ccflags-m, so ifeq(..., m)/else +# to correctly handle all options (y,m,n) ifeq ($(CONFIG_SCSC_DEBUG), m) ccflags-y += -DCONFIG_SCSC_PRINTK else -ccflags-$(CONFIG_SCSC_DEBUG) += -DCONFIG_SCSC_PRINTK +ccflags-$(CONFIG_SCSC_LOGRING) += -DCONFIG_SCSC_PRINTK endif -ifneq ($(CONFIG_SCSC_DEBUG),n) -ccflags-$(CONFIG_SCSC_STATIC_RING) += -DCONFIG_SCSC_STATIC_RING_SIZE=$(CONFIG_SCSC_STATIC_RING_SIZE) +ifneq ($(CONFIG_SCSC_STATIC_RING), n) +ccflags-y += -DCONFIG_SCSC_STATIC_RING_SIZE=$(CONFIG_SCSC_STATIC_RING_SIZE) endif -obj-$(CONFIG_SCSC_WIFILOGGER) += scsc_wifilogger.o -scsc_wifilogger-y += scsc_wifilogger_api.o \ - scsc_wifilogger_internal.o \ - scsc_wifilogger_core.o \ - scsc_wifilogger_module.o \ - scsc_wifilogger_ring_connectivity.o \ - scsc_wifilogger_ring_wakelock.o \ - scsc_wifilogger_ring_pktfate.o +# Debug +obj-$(CONFIG_SCSC_LOGRING) += scsc_logring.o +scsc_logring-$(CONFIG_SCSC_LOGRING) += \ + scsc_logring_main.o \ + scsc_logring_ring.o \ + scsc_logring_debugfs.o + +# Log collection +obj-$(CONFIG_SCSC_LOG_COLLECTION) += scsc_log_collection.o +scsc_log_collection-$(CONFIG_SCSC_LOG_COLLECTION) += \ + scsc_log_collector.o \ + scsc_log_collector_proc.o \ + scsc_log_collector_mmap.o \ + +# WiFi logger +obj-$(CONFIG_SCSC_WIFILOGGER) += scsc_wifilogger.o +scsc_wifilogger-$(CONFIG_SCSC_WIFILOGGER) += \ + scsc_wifilogger_api.o \ + scsc_wifilogger_internal.o \ + scsc_wifilogger_core.o \ + scsc_wifilogger_module.o \ + scsc_wifilogger_ring_connectivity.o \ + scsc_wifilogger_ring_wakelock.o \ + scsc_wifilogger_ring_pktfate.o scsc_wifilogger-$(CONFIG_SCSC_WIFILOGGER_DEBUGFS) += scsc_wifilogger_debugfs.o + scsc_wifilogger-$(CONFIG_SCSC_WIFILOGGER_TEST) += scsc_wifilogger_ring_test.o -#pcie_module for static functions and registration of client modules (only core) -#pcie_mif for instance +# PCI-E MIF obj-$(CONFIG_SCSC_PCIE) += scsc_pcie_mif.o -scsc_pcie_mif-y += pcie_mif_module.o pcie_mif.o pcie_proc.o pcie_mbox.o pcie_mbox_intgen.o - +scsc_pcie_mif-$(CONFIG_SCSC_PCIE) += \ + pcie_mif_module.o \ + pcie_mif.o \ + pcie_proc.o \ + pcie_mbox.o \ + pcie_mbox_intgen.o + +# Platform MIF obj-$(CONFIG_SCSC_PLATFORM) += scsc_platform_mif.o -scsc_platform_mif-y += platform_mif_module.o platform_mif.o +scsc_platform_mif-$(CONFIG_SCSC_PLATFORM) += \ + platform_mif_module.o \ + platform_mif.o -#core_module for static functions and registration client module (all the service driver modules -wlan, bt,...-) -#core for instance +# Maxwell manager obj-$(CONFIG_SCSC_CORE_CM) += scsc_mx.o -scsc_mx-y += \ +scsc_mx-$(CONFIG_SCSC_CORE_CM) += \ mxlog_transport.o \ fw_panic_record.o \ panicmon.o \ @@ -81,45 +87,45 @@ scsc_mx-y += \ mifstream.o \ mxmgmt_transport.o \ gdb_transport.o \ - mifqos.o \ mx140_file.o +# Maxwell logger scsc_mx-$(CONFIG_SCSC_MXLOGGER) += mxlogger.o +# SMAPPER scsc_mx-$(CONFIG_SCSC_SMAPPER) += mifsmapper.o +# WLBT daemon scsc_mx-$(CONFIG_SCSC_WLBTD) += scsc_wlbtd.o -ifneq ($(CONFIG_SCSC_CM_MX_CLIENT_TEST),n) +# QOS +scsc_mx-$(CONFIG_SCSC_QOS) += mifqos.o + +# Null service (test) obj-$(CONFIG_SCSC_CM_MX_CLIENT_TEST) += mx_client_test.o -mx_client_test-y += client_test.o -endif +mx_client_test-$(CONFIG_SCSC_CM_MX_CLIENT_TEST) += client_test.o -ifneq ($(CONFIG_SCSC_MMAP),n) +# Memory map obj-$(CONFIG_SCSC_MMAP) += scsc_mmap.o -scsc_mmap-y += mx_mmap.o -endif +scsc_mmap-$(CONFIG_SCSC_MMAP) += mx_mmap.o -ifneq ($(CONFIG_SCSC_CLK20MHZ),n) +# 20 MHz clock test obj-$(CONFIG_SCSC_CLK20MHZ) += scsc_mx140_clk.o -scsc_mx140_clk-y += mx140_clk.o +scsc_mx140_clk-$(CONFIG_SCSC_CLK20MHZ) += mx140_clk.o ifeq ($(CONFIG_SCSC_CLK20MHZ_TEST),y) -scsc_mx140_clk-y += mx140_clk_test.o -endif +scsc_mx140_clk-$(CONFIG_SCSC_CLK20MHZ) += mx140_clk_test.o endif -ifneq ($(CONFIG_SCSC_FM),n) +# FM LDO test obj-$(CONFIG_SCSC_FM) += scsc_mx250_fm.o -scsc_mx250_fm-y += mx250_fm.o +scsc_mx250_fm-$(CONFIG_SCSC_FM) += mx250_fm.o ifeq ($(CONFIG_SCSC_FM_TEST),y) -scsc_mx250_fm-y += mx250_fm_test.o -endif +scsc_mx250_fm-$(CONFIG_SCSC_FM) += mx250_fm_test.o endif +# Debug sampler obj-$(CONFIG_SCSC_DBG_SAMPLER) += scsc_dbg_sampler.o -scsc_dbg_sampler-y += mx_dbg_sampler.o - -endif +scsc_dbg_sampler-$(CONFIG_SCSC_DBG_SAMPLER) += mx_dbg_sampler.o # The below section is only for DTE purpose. It is controlled by the flag SCSC_DTE_BUILD which is set only by the # DTE top level Makefile. Hence, no risk. diff --git a/drivers/misc/samsung/scsc/miframman.c b/drivers/misc/samsung/scsc/miframman.c index 62f4293d8d0d..ba6253cec887 100644 --- a/drivers/misc/samsung/scsc/miframman.c +++ b/drivers/misc/samsung/scsc/miframman.c @@ -10,8 +10,10 @@ #include #include "scsc_mif_abs.h" +#include "scsc/api/bt_audio.h" #include "miframman.h" + /* Caller should provide locking */ void miframman_init(struct miframman *ram, void *start_dram, size_t size_pool) { @@ -37,6 +39,12 @@ void miframman_init(struct miframman *ram, void *start_dram, size_t size_pool) ram->free_mem = ram->num_blocks * MIFRAMMAN_BLOCK_SIZE; } +void miframabox_init(struct mifabox *mifabox, void *start_aboxram) +{ + /* No locking as not a shared resource */ + mifabox->aboxram = (struct scsc_bt_audio_abox *)start_aboxram; +} + void *__miframman_alloc(struct miframman *ram, size_t nbytes) { unsigned int index = 0; @@ -173,3 +181,11 @@ void miframman_deinit(struct miframman *ram) ram->size_pool = 0; ram->free_mem = 0; } + +void miframabox_deinit(struct mifabox *mifabox) +{ + /* not dynamic - so just mark as NULL */ + /* Maybe this function should be empty? */ + mifabox->aboxram = NULL; +} + diff --git a/drivers/misc/samsung/scsc/miframman.h b/drivers/misc/samsung/scsc/miframman.h index 19b0b1405b06..0c08c0adcd09 100644 --- a/drivers/misc/samsung/scsc/miframman.h +++ b/drivers/misc/samsung/scsc/miframman.h @@ -8,15 +8,20 @@ #define __MIFRAMMAN_H #include +#include "scsc/api/bt_audio.h" /* TODO: Needs to define the max mem */ struct miframman; +struct mifabox; + void miframman_init(struct miframman *ram, void *start_dram, size_t size_pool); +void miframabox_init(struct mifabox *mifabox, void *start_aboxram); void *miframman_alloc(struct miframman *ram, size_t nbytes, size_t align); void miframman_free(struct miframman *ram, void *mem); void miframman_deinit(struct miframman *ram); +void miframabox_deinit(struct mifabox *mifabox); #define MIFRAMMAN_MAXMEM (16 * 1024 * 1024) #define MIFRAMMAN_BLOCK_SIZE (64) @@ -36,4 +41,8 @@ struct miframman { u32 free_mem; struct mutex lock; }; + +struct mifabox { + struct scsc_bt_audio_abox *aboxram; +}; #endif diff --git a/drivers/misc/samsung/scsc/mx140_file.c b/drivers/misc/samsung/scsc/mx140_file.c index 75f9cac47e8f..40e918e6f88a 100644 --- a/drivers/misc/samsung/scsc/mx140_file.c +++ b/drivers/misc/samsung/scsc/mx140_file.c @@ -8,7 +8,11 @@ #include #include #include +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +#include +#else #include +#endif #include #include @@ -30,7 +34,12 @@ #endif /* Look for this file in /etc/wifi */ -#define MX140_FW_DETECT "mx" +#ifdef CONFIG_ANDROID +#define MX140_FW_DETECT "mx" +#else +/* Linux host vfs_stat() doesn't find mx* with "mx" */ +#define MX140_FW_DETECT "mx140.bin" +#endif /* Paths for vendor utilities, used when CONFIG_SCSC_CORE_FW_LOCATION_AUTO=n */ #define MX140_EXE_DIR_VENDOR "/vendor/bin" /* Oreo */ @@ -96,7 +105,11 @@ module_param(firmware_hw_ver, charp, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(firmware_hw_ver, "mx140 hw version detect, manual=disable"); /* FW base dir readable by usermode script */ +#ifdef CONFIG_SCSC_CORE_FW_LOCATION_AUTO +static char *fw_base_dir; +#else static char *fw_base_dir = CONFIG_SCSC_CORE_FW_LOCATION; +#endif module_param_named(base_dir, fw_base_dir, charp, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(base_dir, "WLBT FW base directory"); diff --git a/drivers/misc/samsung/scsc/mx250_fm.c b/drivers/misc/samsung/scsc/mx250_fm.c index b12d108ea9f6..cb21ab7b14df 100755 --- a/drivers/misc/samsung/scsc/mx250_fm.c +++ b/drivers/misc/samsung/scsc/mx250_fm.c @@ -131,7 +131,15 @@ static int open_start_close_service(void) r = open_start_service(); if (r) { SCSC_TAG_ERR(FM, "Error starting service: open_start_service(fm_service) failed %d\n", r); - return r; + + if (!fm_client->ldo_on) { + /* Do not return here. For the case where WLBT FW is crashed, and FM off request is + * rejected, it's safest to continue to let scsc_service_on_halt_ldos_off() reset + * the global flag to indicate that FM is no longer needed when WLBT next boots. + * Otherwise LDO could be stuck always-on. + */ + } else + return r; } if (fm_client->ldo_on) diff --git a/drivers/misc/samsung/scsc/mx250_fm_test.c b/drivers/misc/samsung/scsc/mx250_fm_test.c index 598301ce3de3..70706628ee07 100644 --- a/drivers/misc/samsung/scsc/mx250_fm_test.c +++ b/drivers/misc/samsung/scsc/mx250_fm_test.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/misc/samsung/scsc/mxconf.h b/drivers/misc/samsung/scsc/mxconf.h index 47951253430d..d263bb1b4a02 100644 --- a/drivers/misc/samsung/scsc/mxconf.h +++ b/drivers/misc/samsung/scsc/mxconf.h @@ -48,7 +48,7 @@ * mismatches. */ #define MXCONF_VERSION_MAJOR 0 -#define MXCONF_VERSION_MINOR 1 +#define MXCONF_VERSION_MINOR 3 /* For FM status */ /* Types */ @@ -139,10 +139,25 @@ struct mxconf { struct mxtransconf mx_trans_conf_gdb_m4; /** - * Mxlog Event Buffer Configuration. - */ + * Mxlog Event Buffer Configuration. + */ struct mxlogconf mxlogconf; + /* FROM MINOR_2 */ + + /** + * SOC HW revision override from host + */ + uint32_t soc_revision; + + /* FROM MINOR_3 */ + + /** + * Setup flags + */ +#define MXCONF_FLAGS_FM_ON (BIT(0)) /* FM already on */ + uint32_t flags; + } __MXPACKED; #endif /* MXCONF_H__ */ diff --git a/drivers/misc/samsung/scsc/mxlog.c b/drivers/misc/samsung/scsc/mxlog.c index 98c7f92d27dd..e15afba58cfa 100644 --- a/drivers/misc/samsung/scsc/mxlog.c +++ b/drivers/misc/samsung/scsc/mxlog.c @@ -21,7 +21,7 @@ static inline void mxlog_phase4_message_handler(const void *message, { unsigned char *buf = (unsigned char *)message; - SCSC_TAG_LVL(MX_FW, level, "%d: %s\n", (int)length, buf); + SCSC_TAG_LVL(MX_FW, level, SCSC_PREFIX"%d: %s\n", (int)length, buf); } /** @@ -162,7 +162,7 @@ static inline void mxlog_phase5_message_handler(const void *message, /* Add FW provided tstamp on front and proper \n at * the end when needed */ - snprintf(spare, MAX_SPARE_FMT + TSTAMP_LEN - 2, "%08X %s%c", + snprintf(spare, MAX_SPARE_FMT + TSTAMP_LEN - 2, SCSC_PREFIX"%08X %s%c", elogmsg->timestamp, fmt, (fmt[fmt_sz] != '\n') ? '\n' : '\0'); fmt = spare; diff --git a/drivers/misc/samsung/scsc/mxlogger.c b/drivers/misc/samsung/scsc/mxlogger.c index 8d0192c833e3..b49347ee28c5 100644 --- a/drivers/misc/samsung/scsc/mxlogger.c +++ b/drivers/misc/samsung/scsc/mxlogger.c @@ -228,33 +228,66 @@ static void mxlogger_message_handler(const void *message, void *data) static int __mxlogger_generate_sync_record(struct mxlogger *mxlogger, enum mxlogger_sync_event event) { - struct mxlogger_sync_record sync_r = {}; + struct mxlogger_sync_record *sync_r_mem; struct timeval t; struct log_msg_packet msg = {}; + unsigned long int jd; void *mem; + ktime_t t1, t2; msg.msg = MM_MXLOGGER_SYNC_RECORD; msg.arg = MM_MXLOGGER_SYNC_INDEX; memcpy(&msg.payload, &mxlogger->sync_buffer_index, sizeof(mxlogger->sync_buffer_index)); - do_gettimeofday(&t); - - sync_r.tv_sec = (u64)t.tv_sec; - sync_r.tv_usec = (u64)t.tv_usec; - sync_r.kernel_time = ktime_to_ns(ktime_get()); - sync_r.sync_event = event; - /* Get the pointer from the index of the sync array */ mem = mxlogger->mem_sync_buf + mxlogger->sync_buffer_index * sizeof(struct mxlogger_sync_record); - memcpy(mem, &sync_r, sizeof(struct mxlogger_sync_record)); - - mxlogger->sync_buffer_index++; - mxlogger->sync_buffer_index &= SYNC_MASK; - + sync_r_mem = (struct mxlogger_sync_record *)mem; + /* Write values in record as FW migth be doing sanity checks */ + sync_r_mem->tv_sec = 1; + sync_r_mem->tv_usec = 1; + sync_r_mem->kernel_time = 1; + sync_r_mem->sync_event = event; + sync_r_mem->fw_time = 0; + sync_r_mem->fw_wrap = 0; + + + SCSC_TAG_INFO(MXMAN, "Get FW time\n"); + preempt_disable(); + /* set the tight loop timeout - we do not require precission but something to not + * loop forever + */ + jd = jiffies + msecs_to_jiffies(20); /* Send the msg as fast as possible */ mxmgmt_transport_send(scsc_mx_get_mxmgmt_transport(mxlogger->mx), MMTRANS_CHAN_ID_MAXWELL_LOGGING, &msg, sizeof(msg)); + t1 = ktime_get(); + /* Tight loop to read memory */ + while (time_before(jiffies, jd) && sync_r_mem->fw_time == 0 && sync_r_mem->fw_wrap == 0) + ; + t2 = ktime_get(); + do_gettimeofday(&t); + preempt_enable(); + + /* Do the processing */ + if (sync_r_mem->fw_wrap == 0 && sync_r_mem->fw_time == 0) { + /* FW didn't update the record (FW panic?). Do not create a SYNC record */ + SCSC_TAG_INFO(MXMAN, "FW failure updating the FW time\n"); + SCSC_TAG_INFO(MXMAN, "Sync delta %lld\n", ktime_to_ns(ktime_sub(t2, t1))); + return 0; + } + + sync_r_mem->tv_sec = (u64)t.tv_sec; + sync_r_mem->tv_usec = (u64)t.tv_usec; + sync_r_mem->kernel_time = ktime_to_ns(t2); + sync_r_mem->sync_event = event; + + SCSC_TAG_INFO(MXMAN, "Sample, %lld, %u, %lld.%06lld\n", + ktime_to_ns(sync_r_mem->kernel_time), sync_r_mem->fw_time, sync_r_mem->tv_sec, sync_r_mem->tv_usec); + SCSC_TAG_INFO(MXMAN, "Sync delta %lld\n", ktime_to_ns(ktime_sub(t2, t1))); + + mxlogger->sync_buffer_index++; + mxlogger->sync_buffer_index &= SYNC_MASK; return 0; } @@ -513,6 +546,8 @@ int mxlogger_init(struct scsc_mx *mx, struct mxlogger *mxlogger, uint32_t mem_sz MEM_LAYOUT_CHECK(); + mxlogger->configured = false; + if (mem_sz <= (sizeof(struct mxlogger_config_area) + MXLOGGER_TOTAL_FIX_BUF)) { SCSC_TAG_ERR(MXMAN, "Insufficient memory allocation\n"); return -EIO; @@ -732,6 +767,12 @@ void mxlogger_deinit(struct scsc_mx *mx, struct mxlogger *mxlogger) struct mxlogger_node *mn, *next; bool match = false; + SCSC_TAG_INFO(MXMAN, "\n"); + + if (!mxlogger || !mxlogger->configured) { + SCSC_TAG_WARNING(MXMAN, "MXLOGGER is not valid or not configured.\n"); + return; + } /* Run deregistration before adquiring the mxlogger lock to avoid * deadlock with log_collector. */ @@ -768,6 +809,7 @@ void mxlogger_deinit(struct scsc_mx *mx, struct mxlogger *mxlogger) if (match == false) SCSC_TAG_ERR(MXMAN, "FATAL, no match for given scsc_mif_abs\n"); + SCSC_TAG_INFO(MXMAN, "End\n"); mutex_unlock(&mxlogger->lock); } diff --git a/drivers/misc/samsung/scsc/mxman.c b/drivers/misc/samsung/scsc/mxman.c index 8d26ddeec29c..3b1b33b32fab 100755 --- a/drivers/misc/samsung/scsc/mxman.c +++ b/drivers/misc/samsung/scsc/mxman.c @@ -31,10 +31,12 @@ #ifdef CONFIG_SCSC_SMAPPER #include "mifsmapper.h" #endif +#ifdef CONFIG_SCSC_QOS #include "mifqos.h" +#endif #include #include -#include "scsc_mx.h" +#include #include #ifdef CONFIG_SCSC_LOG_COLLECTION #include @@ -48,6 +50,9 @@ static struct work_struct wlbtd_work; #endif +#include +#include + #define STRING_BUFFER_MAX_LENGTH 512 #define NUMBER_OF_STRING_ARGS 5 #define MX_DRAM_SIZE (4 * 1024 * 1024) @@ -160,6 +165,13 @@ MODULE_PARM_DESC(disable_logger, "Disable launch of user space logger"); bool reset_failed; static u64 reset_failed_time; +/* Status of FM driver request, which persists beyond the lifecyle + * of the scsx_mx driver. + */ +#ifdef CONFIG_SCSC_FM +static u32 is_fm_on; +#endif + static int firmware_runtime_flags; /** * This mxman reference is initialized/nullified via mxman_init/deinit @@ -604,6 +616,15 @@ static int transports_init(struct mxman *mxman) mxconf->magic = MXCONF_MAGIC; mxconf->version.major = MXCONF_VERSION_MAJOR; mxconf->version.minor = MXCONF_VERSION_MINOR; + + /* Pass pre-existing FM status to FW */ +#if (MXCONF_VERSION_MINOR >= 3) + mxconf->flags = 0; +#ifdef CONFIG_SCSC_FM + mxconf->flags |= is_fm_on ? MXCONF_FLAGS_FM_ON : 0; +#endif + SCSC_TAG_INFO(MXMAN, "mxconf flags 0x%08x\n", mxconf->flags); +#endif /* serialise mxmgmt transport */ mxmgmt_transport_config_serialise(scsc_mx_get_mxmgmt_transport(mx), &mxconf->mx_trans_conf); /* serialise Cortex-R4 gdb transport */ @@ -854,11 +875,16 @@ static int mxman_start(struct mxman *mxman) start_mifram_heap = (char *)start_dram + fwhdr->fw_runtime_length; length_mifram_heap = MX_DRAM_SIZE_SECTION_1 - fwhdr->fw_runtime_length; + start_mifram_heap2 = (char *)start_dram + MX_DRAM_SIZE_SECTION_2; - length_mifram_heap2 = MX_DRAM_SIZE_SECTION_2; + + /* ABox reserved at end so adjust length - round to multiple of PAGE_SIZE */ + length_mifram_heap2 = MX_DRAM_SIZE_SECTION_2 - + ((sizeof(struct scsc_bt_audio_abox) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)); miframman_init(scsc_mx_get_ramman(mxman->mx), start_mifram_heap, length_mifram_heap); miframman_init(scsc_mx_get_ramman2(mxman->mx), start_mifram_heap2, length_mifram_heap2); + miframabox_init(scsc_mx_get_aboxram(mxman->mx), start_mifram_heap2 + length_mifram_heap2); mifmboxman_init(scsc_mx_get_mboxman(mxman->mx)); mifintrbit_init(scsc_mx_get_intrbit(mxman->mx), mif); @@ -870,11 +896,14 @@ static int mxman_start(struct mxman *mxman) mifintrbit_deinit(scsc_mx_get_intrbit(mxman->mx)); miframman_deinit(scsc_mx_get_ramman(mxman->mx)); miframman_deinit(scsc_mx_get_ramman2(mxman->mx)); + miframabox_deinit(scsc_mx_get_aboxram(mxman->mx)); mifmboxman_deinit(scsc_mx_get_mboxman(mxman->mx)); #ifdef CONFIG_SCSC_SMAPPER mifsmapper_deinit(scsc_mx_get_smapper(mxman->mx)); #endif +#ifdef CONFIG_SCSC_QOS mifqos_deinit(scsc_mx_get_qos(mxman->mx)); +#endif /* Release the MIF memory resources */ mif->unmap(mif, mxman->start_dram); return r; @@ -882,8 +911,9 @@ static int mxman_start(struct mxman *mxman) mbox_init(mxman, fwhdr->firmware_entry_point); init_completion(&mxman->mm_msg_start_ind_completion); init_completion(&mxman->mm_msg_halt_rsp_completion); - mxmgmt_transport_register_channel_handler(scsc_mx_get_mxmgmt_transport(mxman->mx), MMTRANS_CHAN_ID_MAXWELL_MANAGEMENT, - &mxman_message_handler, mxman); + mxmgmt_transport_register_channel_handler(scsc_mx_get_mxmgmt_transport(mxman->mx), + MMTRANS_CHAN_ID_MAXWELL_MANAGEMENT, + &mxman_message_handler, mxman); mxlog_init(scsc_mx_get_mxlog(mxman->mx), mxman->mx, mxman->fw_build_id); #ifdef CONFIG_SCSC_MXLOGGER @@ -893,7 +923,9 @@ static int mxman_start(struct mxman *mxman) /* Initialize SMAPPER */ mifsmapper_init(scsc_mx_get_smapper(mxman->mx), mif); #endif +#ifdef CONFIG_SCSC_QOS mifqos_init(scsc_mx_get_qos(mxman->mx), mif); +#endif #ifdef CONFIG_SCSC_CHV_SUPPORT if (chv_run) { @@ -1095,6 +1127,7 @@ void mxman_show_last_panic(struct mxman *mxman) print_panic_code(mxman->scsc_panic_code); SCSC_TAG_INFO(MXMAN, "Reason: '%s'\n", mxman->failure_reason[0] ? mxman->failure_reason : ""); + SCSC_TAG_INFO(MXMAN, "Auto-recovery: %s\n", disable_recovery_handling ? "off" : "on"); if (disable_recovery_handling) { /* Labour the point that a reboot is needed when autorecovery is disabled */ @@ -1200,8 +1233,11 @@ static void mxman_failure_work(struct work_struct *work) struct srvman *srvman; struct scsc_mx *mx = mxman->mx; struct scsc_mif_abs *mif = scsc_mx_get_mif_abs(mxman->mx); + int used = 0, r = 0; +#ifdef CONFIG_ANDROID wake_lock(&mxman->recovery_wake_lock); +#endif slsi_kic_system_event(slsi_kic_system_event_category_error, slsi_kic_system_events_subsystem_crashed, GFP_KERNEL); @@ -1215,7 +1251,9 @@ static void mxman_failure_work(struct work_struct *work) if (mxman->mxman_state != MXMAN_STATE_STARTED && mxman->mxman_state != MXMAN_STATE_STARTING) { SCSC_TAG_WARNING(MXMAN, "Not in started state: mxman->mxman_state=%d\n", mxman->mxman_state); +#ifdef CONFIG_ANDROID wake_unlock(&mxman->recovery_wake_lock); +#endif mutex_unlock(&mxman->mxman_mutex); return; } @@ -1241,7 +1279,9 @@ static void mxman_failure_work(struct work_struct *work) WARN_ON(mxman->mxman_state != MXMAN_STATE_FAILED && mxman->mxman_state != MXMAN_STATE_FREEZED); SCSC_TAG_ERR(MXMAN, "Bad state=%d\n", mxman->mxman_state); +#ifdef CONFIG_ANDROID wake_unlock(&mxman->recovery_wake_lock); +#endif mutex_unlock(&mxman->mxman_mutex); return; } @@ -1260,6 +1300,7 @@ static void mxman_failure_work(struct work_struct *work) SCSC_RELEASE_ITERATION, SCSC_RELEASE_CANDIDATE, SCSC_RELEASE_POINT); + SCSC_TAG_INFO(MXMAN, "Auto-recovery: %s\n", mxman_recovery_disabled() ? "off" : "on"); #ifdef CONFIG_SCSC_WLBTD scsc_wlbtd_get_and_print_build_type(); #endif @@ -1281,8 +1322,6 @@ static void mxman_failure_work(struct work_struct *work) MAX_UHELP_TMO_MS); /* Waits for the usermode_helper subsytem to be re-enabled. */ if (usermodehelper_read_lock_wait(msecs_to_jiffies(MAX_UHELP_TMO_MS))) { - int used, r; - /** * Release immediately the rwsem on usermode_helper * enabled since we anyway already hold a wakelock here @@ -1348,6 +1387,7 @@ static void mxman_failure_work(struct work_struct *work) if (mif->mif_cleanup && mxman_recovery_disabled()) mif->mif_cleanup(mif); } + SCSC_TAG_INFO(MXMAN, "Auto-recovery: %s\n", mxman_recovery_disabled() ? "off" : "on"); if (!mxman_recovery_disabled()) srvman_clear_error(srvman); @@ -1367,7 +1407,9 @@ static void mxman_failure_work(struct work_struct *work) if (mxman_recovery_disabled()) complete(&mxman->recovery_completion); +#ifdef CONFIG_ANDROID wake_unlock(&mxman->recovery_wake_lock); +#endif } static void failure_wq_init(struct mxman *mxman) @@ -1469,6 +1511,7 @@ static int __mxman_open(struct mxman *mxman) SCSC_TAG_INFO(MXMAN, "Reason: '%s'\n", mxman->failure_reason[0] ? mxman->failure_reason : ""); print_panic_code(mxman->scsc_panic_code); } + SCSC_TAG_INFO(MXMAN, "Auto-recovery: %s\n", mxman_recovery_disabled() ? "off" : "on"); srvman = scsc_mx_get_srvman(mxman->mx); if (srvman && srvman->error) { mutex_unlock(&mxman->mxman_mutex); @@ -1610,11 +1653,14 @@ static void mxman_stop(struct mxman *mxman) mifintrbit_deinit(scsc_mx_get_intrbit(mxman->mx)); miframman_deinit(scsc_mx_get_ramman(mxman->mx)); miframman_deinit(scsc_mx_get_ramman2(mxman->mx)); + miframabox_deinit(scsc_mx_get_aboxram(mxman->mx)); mifmboxman_deinit(scsc_mx_get_mboxman(mxman->mx)); #ifdef CONFIG_SCSC_SMAPPER mifsmapper_deinit(scsc_mx_get_smapper(mxman->mx)); #endif +#ifdef CONFIG_SCSC_QOS mifqos_deinit(scsc_mx_get_qos(mxman->mx)); +#endif /* Release the MIF memory resources */ mif->unmap(mif, mxman->start_dram); } @@ -1673,6 +1719,12 @@ void mxman_close(struct mxman *mxman) mutex_unlock(&mxman->mxman_mutex); return; } +#ifdef CONFIG_SCSC_MXLOGGER + /** + * Deinit mxlogger on last service stop...BUT before asking for HALT + */ + mxlogger_deinit(mxman->mx, scsc_mx_get_mxlogger(mxman->mx)); +#endif mxman_stop(mxman); mxman->mxman_state = MXMAN_STATE_STOPPED; @@ -1727,7 +1779,9 @@ void mxman_init(struct mxman *mxman, struct scsc_mx *mx) #endif mutex_init(&mxman->mxman_mutex); init_completion(&mxman->recovery_completion); +#ifdef CONFIG_ANDROID wake_lock_init(&mxman->recovery_wake_lock, WAKE_LOCK_SUSPEND, "mxman_recovery"); +#endif /* set the initial state */ mxman->mxman_state = MXMAN_STATE_STOPPED; @@ -1747,7 +1801,9 @@ void mxman_deinit(struct mxman *mxman) #ifdef CONFIG_SCSC_WLBTD wlbtd_wq_deinit(mxman); #endif +#ifdef CONFIG_ANDROID wake_lock_destroy(&mxman->recovery_wake_lock); +#endif mutex_destroy(&mxman->mxman_mutex); } @@ -1814,11 +1870,29 @@ int mxman_suspend(struct mxman *mxman) void mxman_on_halt_ldos_on(struct mxman *mxman) { mxman->on_halt_ldos_on = 1; + + /* FM status to pass into FW at next FW init, + * by which time driver context is lost. + * This is required, because now WLBT gates + * LDOs with TCXO instead of leaving them + * always on, to save power in deep sleep. + * FM, however, needs them always on. So + * we need to know when to leave the LDOs + * alone at WLBT boot. + */ + is_fm_on = 1; } void mxman_on_halt_ldos_off(struct mxman *mxman) { + /* Newer FW no longer need set shared LDOs + * always-off at WLBT halt, as TCXO gating + * has the same effect. But pass the "off" + * request for backwards compatibility + * with old FW. + */ mxman->on_halt_ldos_on = 0; + is_fm_on = 0; } #endif @@ -1988,8 +2062,6 @@ int mx140_log_dump(void) } # endif /* CONFIG_SCSC_WLBTD */ return r; - - #else return 0; #endif @@ -2012,7 +2084,7 @@ EXPORT_SYMBOL(mxman_recovery_disabled); void mxman_get_fw_version(char *version, size_t ver_sz) { /* unavailable only if chip not probed ! */ - snprintf(version, ver_sz - 1, "%s", saved_fw_build_id); + snprintf(version, ver_sz, "%s", saved_fw_build_id); } EXPORT_SYMBOL(mxman_get_fw_version); @@ -2020,7 +2092,7 @@ void mxman_get_driver_version(char *version, size_t ver_sz) { /* IMPORTANT - Do not change the formatting as User space tooling is parsing the string * to read SAP fapi versions. */ - snprintf(version, ver_sz - 1, "drv_ver: %u.%u.%u.%u", + snprintf(version, ver_sz, "drv_ver: %u.%u.%u.%u", SCSC_RELEASE_PRODUCT, SCSC_RELEASE_ITERATION, SCSC_RELEASE_CANDIDATE, SCSC_RELEASE_POINT); #ifdef CONFIG_SCSC_WLBTD scsc_wlbtd_get_and_print_build_type(); diff --git a/drivers/misc/samsung/scsc/mxman.h b/drivers/misc/samsung/scsc/mxman.h index 9b9ad5c0aa34..df4a18f3e237 100755 --- a/drivers/misc/samsung/scsc/mxman.h +++ b/drivers/misc/samsung/scsc/mxman.h @@ -10,8 +10,10 @@ #include "fwhdr.h" #include "mxmgmt_transport.h" #include "mxproc.h" -#include "scsc_mx.h" +#include +#ifdef CONFIG_ANDROID #include +#endif struct mxman; @@ -66,7 +68,9 @@ struct mxman { bool check_crc; char fw_build_id[FW_BUILD_ID_SZ]; /* Defined in SC-505846-SW */ struct completion recovery_completion; +#ifdef CONFIG_ANDROID struct wake_lock recovery_wake_lock; +#endif u32 rf_hw_ver; u16 scsc_panic_code; u64 last_panic_time; diff --git a/drivers/misc/samsung/scsc/pcie_mif.c b/drivers/misc/samsung/scsc/pcie_mif.c index 224b4120a3f5..3cf0925b8dcc 100644 --- a/drivers/misc/samsung/scsc/pcie_mif.c +++ b/drivers/misc/samsung/scsc/pcie_mif.c @@ -99,6 +99,23 @@ static void pcie_mif_emulate_reset_request_interrupt(struct pcie_mif *pcie) } } +#ifdef CONFIG_SCSC_QOS +static int pcie_mif_pm_qos_add_request(struct scsc_mif_abs *interface, struct scsc_mifqos_request *qos_req, enum scsc_qos_config config) +{ + return 0; +} + +static int pcie_mif_pm_qos_update_request(struct scsc_mif_abs *interface, struct scsc_mifqos_request *qos_req, enum scsc_qos_config config) +{ + return 0; +} + +static int pcie_mif_pm_qos_remove_request(struct scsc_mif_abs *interface, struct scsc_mifqos_request *qos_req) +{ + return 0; +} +#endif + irqreturn_t pcie_mif_isr(int irq, void *data) { struct pcie_mif *pcie = (struct pcie_mif *)data; @@ -464,6 +481,11 @@ struct scsc_mif_abs *pcie_mif_create(struct pci_dev *pdev, const struct pci_devi pcie_if->get_mif_device = pcie_mif_get_mif_device; pcie_if->irq_clear = pcie_mif_irq_clear; pcie_if->mif_dump_registers = pcie_mif_dump_register; +#ifdef CONFIG_SCSC_QOS + pcie_if->mif_pm_qos_add_request = pcie_mif_pm_qos_add_request; + pcie_if->mif_pm_qos_update_request = pcie_mif_pm_qos_update_request; + pcie_if->mif_pm_qos_remove_request = pcie_mif_pm_qos_remove_request; +#endif /* Suspend/resume not supported in PCIe MIF */ pcie_if->suspend_reg_handler = NULL; diff --git a/drivers/misc/samsung/scsc/platform_mif.c b/drivers/misc/samsung/scsc/platform_mif.c index 9793a816df17..2ea092387a92 100755 --- a/drivers/misc/samsung/scsc/platform_mif.c +++ b/drivers/misc/samsung/scsc/platform_mif.c @@ -49,7 +49,9 @@ #include #include "mif_reg_smapper.h" #endif +#ifdef CONFIG_SCSC_QOS #include +#endif #if !defined(CONFIG_SOC_EXYNOS7872) && !defined(CONFIG_SOC_EXYNOS7570) \ && !defined(CONFIG_SOC_EXYNOS7885) && !defined(CONFIG_SOC_EXYNOS9610) @@ -92,12 +94,14 @@ static bool enable_platform_mif_arm_reset = true; module_param(enable_platform_mif_arm_reset, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(enable_platform_mif_arm_reset, "Enables WIFIBT ARM cores reset"); +#ifdef CONFIG_SCSC_QOS struct qos_table { unsigned int freq_mif; unsigned int freq_int; unsigned int freq_cl0; unsigned int freq_cl1; }; +#endif struct platform_mif { struct scsc_mif_abs interface; @@ -181,10 +185,11 @@ struct platform_mif { void (*reset_request_handler)(int irq, void *data); void *irq_reset_request_dev; +#ifdef CONFIG_SCSC_QOS /* QoS table */ struct qos_table *qos; bool qos_enabled; - +#endif /* Suspend/resume handlers */ int (*suspend_handler)(struct scsc_mif_abs *abs, void *data); void (*resume_handler)(struct scsc_mif_abs *abs, void *data); @@ -434,7 +439,7 @@ static int platform_mif_parse_smapper(struct platform_mif *platform, struct devi return 0; } #endif - +#ifdef CONFIG_SCSC_QOS static int platform_mif_parse_qos(struct platform_mif *platform, struct device_node *np) { int len, i; @@ -575,6 +580,7 @@ static int platform_mif_pm_qos_remove_request(struct scsc_mif_abs *interface, st return 0; } +#endif static void platform_mif_irq_default_handler(int irq, void *data) { @@ -2130,10 +2136,11 @@ struct scsc_mif_abs *platform_mif_create(struct platform_device *pdev) platform_if->mif_smapper_configure = platform_mif_smapper_configure; platform_if->mif_smapper_get_bank_base_address = platform_mif_smapper_get_bank_base_address; #endif +#ifdef CONFIG_SCSC_QOS platform_if->mif_pm_qos_add_request = platform_mif_pm_qos_add_request; platform_if->mif_pm_qos_update_request = platform_mif_pm_qos_update_request; platform_if->mif_pm_qos_remove_request = platform_mif_pm_qos_remove_request; - +#endif /* Update state */ platform->pdev = pdev; platform->dev = &pdev->dev; @@ -2386,7 +2393,9 @@ cont: platform_mif_parse_smapper(platform, platform->dev->of_node, smapper_banks); #endif +#ifdef CONFIG_SCSC_QOS platform_mif_parse_qos(platform, platform->dev->of_node); +#endif #ifdef CONFIG_SCSC_CLK20MHZ /* Assign USBPLL ownership to WLBT f/w */ __platform_mif_usbpll_claim(platform, true); diff --git a/drivers/misc/samsung/scsc/scsc_log_collector.c b/drivers/misc/samsung/scsc/scsc_log_collector.c index 9eb031d1454e..f7df7e51dde1 100644 --- a/drivers/misc/samsung/scsc/scsc_log_collector.c +++ b/drivers/misc/samsung/scsc/scsc_log_collector.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include "scsc_log_collector_proc.h" @@ -48,6 +47,8 @@ static u8 chunk_supported_sbl[SCSC_NUM_CHUNKS_SUPPORTED] = { static int scsc_log_collector_collect(enum scsc_log_reason reason, u16 reason_code); +static atomic_t in_collection; + /* Collect logs in an intermediate buffer to be collected at later time (mmap or wq) */ static bool collect_to_ram = true; module_param(collect_to_ram, bool, S_IRUGO | S_IWUSR); @@ -111,7 +112,6 @@ struct scsc_log_status { struct work_struct collect_work; enum scsc_log_reason collect_reason; u16 reason_code; - struct completion complete; struct mutex collection_serial; } log_status; @@ -127,7 +127,7 @@ static void collection_worker(struct work_struct *work) pr_info("SCSC running scheduled Log Collection - collect reason:%d reason code:%d\n", ls->collect_reason, ls->reason_code); scsc_log_collector_collect(ls->collect_reason, ls->reason_code); - complete(&log_status.complete); + atomic_set(&in_collection, 0); } /* Module init */ @@ -151,7 +151,6 @@ int __init scsc_log_collector(void) log_status.buf = NULL; } - init_completion(&log_status.complete); mutex_init(&log_status.collection_serial); scsc_log_collect_proc_create(); @@ -166,7 +165,7 @@ void __exit scsc_log_collector_exit(void) scsc_log_collect_proc_remove(); if (log_status.collection_workq) { - cancel_work_sync(&log_status.collect_work); + flush_workqueue(log_status.collection_workq); destroy_workqueue(log_status.collection_workq); log_status.collection_workq = NULL; } @@ -455,12 +454,14 @@ exit: lc->collect_client->collect_end(lc->collect_client); } - pr_info("Log collection end. Took: %lld\n", ktime_to_ns(ktime_sub(ktime_get(), start))); + pr_info("Calling sable collection\n"); #ifdef CONFIG_SCSC_WLBTD if (sbl_is_valid) call_wlbtd_sable(scsc_loc_reason_str[reason], reason_code); #endif + pr_info("Log collection end. Took: %lld\n", ktime_to_ns(ktime_sub(ktime_get(), start))); + mutex_unlock(&log_mutex); return ret; @@ -486,20 +487,30 @@ static int scsc_log_collector_collect(enum scsc_log_reason reason, u16 reason_co void scsc_log_collector_schedule_collection(enum scsc_log_reason reason, u16 reason_code) { - int err; if (log_status.collection_workq) { mutex_lock(&log_status.collection_serial); pr_info("Log collection Schedule"); + + /* Serialize with previous work if the reason is a FW panic */ + if (reason == SCSC_LOG_FW_PANIC) + flush_work(&log_status.collect_work); + else if (atomic_read(&in_collection)) { + pr_info("Log collection %s reason_code 0x%x rejected. Collection already scheduled\n", + scsc_loc_reason_str[reason], reason_code); + mutex_unlock(&log_status.collection_serial); + return; + } log_status.collect_reason = reason; log_status.reason_code = reason_code; - if (!queue_work(log_status.collection_workq, &log_status.collect_work)) - pr_info("Log collection %s reason_code 0x%x rejected. Collection already scheduled\n", + if (!queue_work(log_status.collection_workq, &log_status.collect_work)) { + pr_info("Log collection %s reason_code 0x%x queue_work error\n", scsc_loc_reason_str[reason], reason_code); - err = wait_for_completion_timeout(&log_status.complete, 5*HZ); - if (!err) - pr_err("Log collection Timeout"); - pr_info("Log collection End"); + mutex_unlock(&log_status.collection_serial); + return; + } + atomic_set(&in_collection, 1); + pr_info("Log collection Scheduled"); mutex_unlock(&log_status.collection_serial); } else { diff --git a/drivers/misc/samsung/scsc/scsc_logring_main.c b/drivers/misc/samsung/scsc/scsc_logring_main.c index 7f5eda49d4c8..79767480fa4e 100644 --- a/drivers/misc/samsung/scsc/scsc_logring_main.c +++ b/drivers/misc/samsung/scsc/scsc_logring_main.c @@ -11,6 +11,7 @@ #endif /* Global module parameters */ +static int cached_enable; static int enable = DEFAULT_ENABLE_LOGRING; static bool initialized; #ifndef CONFIG_SCSC_STATIC_RING_SIZE @@ -467,7 +468,7 @@ void handle_klogbuf_out_binary(int level, int tag, const void *start, if (IS_PRINTK_REDIRECT_ALLOWED(force, level, tag)) { if (level < SCSC_MIN_DBG || level >= ARRAY_SIZE(map2kern)) level = ARRAY_SIZE(map2kern) - 1; - print_hex_dump(map2kern[level], "SCSC_HEX->|", + print_hex_dump(map2kern[level], SCSC_PREFIX"SCSC_HEX->|", DUMP_PREFIX_NONE, 16, 1, start, len, false); } } @@ -622,6 +623,32 @@ int scsc_printk_bin(int force, int tag, int dlev, const void *start, size_t len) } EXPORT_SYMBOL(scsc_printk_bin); +/* + * This is a very basic mechanism to have implement the dynamic switch + * for one user (currently WLAN). If multiple users are + * required to use the dynamic logring switch, a new registration + * mechanism based on requests and use_count should be implemented to avoid one service + * re-enabling logring when some other has requested not to do so. + */ +int scsc_logring_enable(bool logging_enable) +{ + scsc_printk_tag(FORCE_PRK, NO_TAG, "scsc_logring %s\n", logging_enable ? "enable" : "disable"); + /* User has requested to disable logring */ + if (!logging_enable && enable) { + cached_enable = true; + enable = 0; + scsc_printk_tag(FORCE_PRK, NO_TAG, "Logring disabled\n"); + } else if (logging_enable && cached_enable) { + cached_enable = false; + enable = 1; + scsc_printk_tag(FORCE_PRK, NO_TAG, "Logring re-enabled\n"); + } else { + scsc_printk_tag(FORCE_PRK, NO_TAG, "Ignored\n"); + } + return 0; +} +EXPORT_SYMBOL(scsc_logring_enable); + MODULE_DESCRIPTION("SCSC Event Logger"); MODULE_AUTHOR("SLSI"); diff --git a/drivers/misc/samsung/scsc/scsc_logring_ring.c b/drivers/misc/samsung/scsc/scsc_logring_ring.c index 74b61ad22a1d..432eb6e24ec9 100644 --- a/drivers/misc/samsung/scsc/scsc_logring_ring.c +++ b/drivers/misc/samsung/scsc/scsc_logring_ring.c @@ -364,7 +364,7 @@ int push_record_string(struct scsc_ring_buffer *rb, int tag, int lev, rec_len = tag_writer_string(rb->spare, tag, lev, prepend_header, msg_head, args); /* Line too long anyway drop */ - if (rec_len == BASE_SPARE_SZ) { + if (rec_len >= BASE_SPARE_SZ - SCSC_RINGREC_SZ) { raw_spin_unlock_irqrestore(&rb->lock, flags); return 0; } diff --git a/drivers/misc/samsung/scsc/scsc_mif_abs.h b/drivers/misc/samsung/scsc/scsc_mif_abs.h index 8ce8caa15b51..333d28a0403e 100644 --- a/drivers/misc/samsung/scsc/scsc_mif_abs.h +++ b/drivers/misc/samsung/scsc/scsc_mif_abs.h @@ -7,7 +7,9 @@ #ifndef __SCSC_MIF_ABS_H #define __SCSC_MIF_ABS_H +#ifdef CONFIG_SCSC_QOS #include +#endif #include #include #include @@ -35,12 +37,14 @@ enum scsc_mif_abs_bank_type { }; #endif +#ifdef CONFIG_SCSC_QOS struct scsc_mifqos_request { struct pm_qos_request pm_qos_req_mif; struct pm_qos_request pm_qos_req_int; struct pm_qos_request pm_qos_req_cl0; struct pm_qos_request pm_qos_req_cl1; }; +#endif /** * Abstraction of the Maxwell "Memory Interface" aka MIF. * @@ -193,9 +197,11 @@ struct scsc_mif_abs { void (*mif_smapper_configure)(struct scsc_mif_abs *interface, u32 granularity); u32 (*mif_smapper_get_bank_base_address)(struct scsc_mif_abs *interface, u8 bank); #endif +#ifdef CONFIG_SCSC_QOS int (*mif_pm_qos_add_request)(struct scsc_mif_abs *interface, struct scsc_mifqos_request *qos_req, enum scsc_qos_config config); int (*mif_pm_qos_update_request)(struct scsc_mif_abs *interface, struct scsc_mifqos_request *qos_req, enum scsc_qos_config config); int (*mif_pm_qos_remove_request)(struct scsc_mif_abs *interface, struct scsc_mifqos_request *qos_req); +#endif }; struct device; diff --git a/drivers/misc/samsung/scsc/scsc_mx_impl.c b/drivers/misc/samsung/scsc/scsc_mx_impl.c index 2c0323a11b9e..cfd339bdd556 100644 --- a/drivers/misc/samsung/scsc/scsc_mx_impl.c +++ b/drivers/misc/samsung/scsc/scsc_mx_impl.c @@ -11,8 +11,12 @@ #include "mifintrbit.h" #include "miframman.h" #include "mifmboxman.h" +#ifdef CONFIG_SCSC_SMAPPER #include "mifsmapper.h" +#endif +#ifdef CONFIG_SCSC_QOS #include "mifqos.h" +#endif #include "mifproc.h" #include "mxman.h" #include "mxproc.h" @@ -24,6 +28,8 @@ #include "panicmon.h" #include "mxlog_transport.h" #include "suspendmon.h" + +#include "scsc/api/bt_audio.h" #ifdef CONFIG_SCSC_WLBTD #include "scsc_wlbtd.h" #endif @@ -33,10 +39,13 @@ struct scsc_mx { struct miframman ram; struct miframman ram2; struct mifmboxman mbox; + struct mifabox mifabox; #ifdef CONFIG_SCSC_SMAPPER struct mifsmapper smapper; #endif +#ifdef CONFIG_SCSC_QOS struct mifqos qos; +#endif struct mifproc proc; struct mxman mxman; struct srvman srvman; @@ -116,6 +125,11 @@ struct miframman *scsc_mx_get_ramman2(struct scsc_mx *mx) return &mx->ram2; } +struct mifabox *scsc_mx_get_aboxram(struct scsc_mx *mx) +{ + return &mx->mifabox; +} + struct mifmboxman *scsc_mx_get_mboxman(struct scsc_mx *mx) { return &mx->mbox; @@ -128,10 +142,12 @@ struct mifsmapper *scsc_mx_get_smapper(struct scsc_mx *mx) } #endif +#ifdef CONFIG_SCSC_QOS struct mifqos *scsc_mx_get_qos(struct scsc_mx *mx) { return &mx->qos; } +#endif struct device *scsc_mx_get_device(struct scsc_mx *mx) { diff --git a/drivers/misc/samsung/scsc/scsc_mx_impl.h b/drivers/misc/samsung/scsc/scsc_mx_impl.h index 8446bac75f30..479e5743c8bd 100644 --- a/drivers/misc/samsung/scsc/scsc_mx_impl.h +++ b/drivers/misc/samsung/scsc/scsc_mx_impl.h @@ -27,11 +27,14 @@ struct mifintrbit *scsc_mx_get_intrbit(struct scsc_mx *mx); struct mifmuxman *scsc_mx_get_muxman(struct scsc_mx *mx); struct miframman *scsc_mx_get_ramman(struct scsc_mx *mx); struct miframman *scsc_mx_get_ramman2(struct scsc_mx *mx); +struct mifabox *scsc_mx_get_aboxram(struct scsc_mx *mx); struct mifmboxman *scsc_mx_get_mboxman(struct scsc_mx *mx); #ifdef CONFIG_SCSC_SMAPPER struct mifsmapper *scsc_mx_get_smapper(struct scsc_mx *mx); #endif +#ifdef CONFIG_SCSC_QOS struct mifqos *scsc_mx_get_qos(struct scsc_mx *mx); +#endif struct device *scsc_mx_get_device(struct scsc_mx *mx); struct mxman *scsc_mx_get_mxman(struct scsc_mx *mx); struct srvman *scsc_mx_get_srvman(struct scsc_mx *mx); diff --git a/drivers/misc/samsung/scsc/scsc_mx_module.c b/drivers/misc/samsung/scsc/scsc_mx_module.c index e11f4c29a1e3..0b4c01b24e78 100755 --- a/drivers/misc/samsung/scsc/scsc_mx_module.c +++ b/drivers/misc/samsung/scsc/scsc_mx_module.c @@ -107,9 +107,6 @@ static int __init scsc_mx_module_init(void) SCSC_RELEASE_ITERATION, SCSC_RELEASE_CANDIDATE, SCSC_RELEASE_POINT); -#ifdef CONFIG_SCSC_WLBTD - scsc_wlbtd_get_and_print_build_type(); -#endif scsc_mif_abs_register(&mx_module_mif_if); return 0; diff --git a/drivers/misc/samsung/scsc/scsc_service.c b/drivers/misc/samsung/scsc/scsc_service.c index 642ce8039f62..9f28ea9c52e0 100755 --- a/drivers/misc/samsung/scsc/scsc_service.c +++ b/drivers/misc/samsung/scsc/scsc_service.c @@ -8,7 +8,9 @@ #include #include #include +#ifdef CONFIG_ANDROID #include +#endif #include #include @@ -20,7 +22,9 @@ #ifdef CONFIG_SCSC_SMAPPER #include "mifsmapper.h" #endif +#ifdef CONFIG_SCSC_QOS #include "mifqos.h" +#endif #include "mxlogger.h" #include "srvman.h" #include "servman_messages.h" @@ -37,8 +41,6 @@ MODULE_PARM_DESC(sm_completion_timeout_ms, "Timeout Service Manager start/stop ( #define reinit_completion(completion) INIT_COMPLETION(*(completion)) #endif - - struct scsc_service { struct list_head list; struct scsc_mx *mx; @@ -56,7 +58,9 @@ void srvman_init(struct srvman *srvman, struct scsc_mx *mx) mutex_init(&srvman->service_list_mutex); mutex_init(&srvman->api_access_mutex); +#ifdef CONFIG_ANDROID wake_lock_init(&srvman->sm_wake_lock, WAKE_LOCK_SUSPEND, "srvman_wakelock"); +#endif } void srvman_deinit(struct srvman *srvman) @@ -71,7 +75,9 @@ void srvman_deinit(struct srvman *srvman) mutex_destroy(&srvman->api_access_mutex); mutex_destroy(&srvman->service_list_mutex); +#ifdef CONFIG_ANDROID wake_lock_destroy(&srvman->sm_wake_lock); +#endif } void srvman_set_error(struct srvman *srvman) @@ -162,8 +168,13 @@ static int send_sm_msg_start_blocking(struct scsc_service *service, scsc_mifram_ /* Send to FW in MM stream */ mxmgmt_transport_send(mxmgmt_transport, MMTRANS_CHAN_ID_SERVICE_MANAGEMENT, &message, sizeof(message)); r = wait_for_sm_msg_start_cfm(service); - if (r) + if (r) { SCSC_TAG_ERR(MXMAN, "wait_for_sm_msg_start_cfm() failed: r=%d\n", r); + + /* Report the error in order to get a moredump. Avoid auto-recovering this type of failure */ + if (mxman_recovery_disabled()) + scsc_mx_service_service_failed(service, "SM_MSG_START_CFM timeout"); + } return r; } @@ -247,7 +258,9 @@ int scsc_mx_service_start(struct scsc_service *service, scsc_mifram_ref ref) return 0; #endif mutex_lock(&srvman->api_access_mutex); +#ifdef CONFIG_ANDROID wake_lock(&srvman->sm_wake_lock); +#endif if (srvman->error) { tval = ns_to_timeval(mxman->last_panic_time); SCSC_TAG_ERR(MXMAN, "error: refused due to previous f/w failure scsc_panic_code=0x%x happened at [%6lu.%06ld]\n", @@ -256,7 +269,9 @@ int scsc_mx_service_start(struct scsc_service *service, scsc_mifram_ref ref) /* Print the last panic record to help track ancient failures */ mxman_show_last_panic(mxman); +#ifdef CONFIG_ANDROID wake_unlock(&srvman->sm_wake_lock); +#endif mutex_unlock(&srvman->api_access_mutex); return -EILSEQ; } @@ -264,12 +279,16 @@ int scsc_mx_service_start(struct scsc_service *service, scsc_mifram_ref ref) r = send_sm_msg_start_blocking(service, ref); if (r) { SCSC_TAG_ERR(MXMAN, "send_sm_msg_start_blocking() failed: r=%d\n", r); +#ifdef CONFIG_ANDROID wake_unlock(&srvman->sm_wake_lock); +#endif mutex_unlock(&srvman->api_access_mutex); return r; } +#ifdef CONFIG_ANDROID wake_unlock(&srvman->sm_wake_lock); +#endif mutex_unlock(&srvman->api_access_mutex); return 0; } @@ -333,7 +352,9 @@ int scsc_mx_service_stop(struct scsc_service *service) return 0; #endif mutex_lock(&srvman->api_access_mutex); +#ifdef CONFIG_ANDROID wake_lock(&srvman->sm_wake_lock); +#endif if (srvman->error) { tval = ns_to_timeval(mxman->last_panic_time); SCSC_TAG_ERR(MXMAN, "error: refused due to previous f/w failure scsc_panic_code=0x%x happened at [%6lu.%06ld]\n", @@ -342,7 +363,9 @@ int scsc_mx_service_stop(struct scsc_service *service) /* Print the last panic record to help track ancient failures */ mxman_show_last_panic(mxman); +#ifdef CONFIG_ANDROID wake_unlock(&srvman->sm_wake_lock); +#endif mutex_unlock(&srvman->api_access_mutex); /* Return a special status to allow caller recovery logic to know @@ -359,12 +382,16 @@ int scsc_mx_service_stop(struct scsc_service *service) r = send_sm_msg_stop_blocking(service); if (r) { SCSC_TAG_ERR(MXMAN, "send_sm_msg_stop_blocking() failed: r=%d\n", r); +#ifdef CONFIG_ANDROID wake_unlock(&srvman->sm_wake_lock); +#endif mutex_unlock(&srvman->api_access_mutex); return -EIO; /* operation failed */ } +#ifdef CONFIG_ANDROID wake_unlock(&srvman->sm_wake_lock); +#endif mutex_unlock(&srvman->api_access_mutex); return 0; } @@ -494,7 +521,9 @@ int scsc_mx_service_close(struct scsc_service *service) SCSC_TAG_INFO(MXMAN, "\n"); mutex_lock(&srvman->api_access_mutex); +#ifdef CONFIG_ANDROID wake_lock(&srvman->sm_wake_lock); +#endif if (srvman->error) { tval = ns_to_timeval(mxman->last_panic_time); @@ -505,7 +534,9 @@ int scsc_mx_service_close(struct scsc_service *service) mxman_show_last_panic(mxman); mutex_unlock(&srvman->api_access_mutex); +#ifdef CONFIG_ANDROID wake_unlock(&srvman->sm_wake_lock); +#endif /* Return a special status when recovery is disabled, to allow * calling recovery logic to be aware that recovery is disabled, @@ -532,7 +563,9 @@ int scsc_mx_service_close(struct scsc_service *service) kfree(service); mxman_close(mxman); +#ifdef CONFIG_ANDROID wake_unlock(&srvman->sm_wake_lock); +#endif mutex_unlock(&srvman->api_access_mutex); return 0; } @@ -551,14 +584,18 @@ struct scsc_service *scsc_mx_service_open(struct scsc_mx *mx, enum scsc_service_ SCSC_TAG_INFO(MXMAN, "\n"); mutex_lock(&srvman->api_access_mutex); +#ifdef CONFIG_ANDROID wake_lock(&srvman->sm_wake_lock); +#endif if (srvman->error) { tval = ns_to_timeval(mxman->last_panic_time); SCSC_TAG_ERR(MXMAN, "error: refused due to previous f/w failure scsc_panic_code=0x%x happened at [%6lu.%06ld]\n", mxman->scsc_panic_code, tval.tv_sec, tval.tv_usec); /* Print the last panic record to help track ancient failures */ mxman_show_last_panic(mxman); +#ifdef CONFIG_ANDROID wake_unlock(&srvman->sm_wake_lock); +#endif mutex_unlock(&srvman->api_access_mutex); *status = -EILSEQ; return NULL; @@ -572,7 +609,9 @@ struct scsc_service *scsc_mx_service_open(struct scsc_mx *mx, enum scsc_service_ msecs_to_jiffies(SCSC_MX_SERVICE_RECOVERY_TIMEOUT)); if (r == 0) { SCSC_TAG_ERR(MXMAN, "Recovery timeout\n"); +#ifdef CONFIG_ANDROID wake_unlock(&srvman->sm_wake_lock); +#endif *status = -EIO; return NULL; } @@ -586,7 +625,9 @@ struct scsc_service *scsc_mx_service_open(struct scsc_mx *mx, enum scsc_service_ ret = mxman_open(mxman); if (ret) { kfree(service); +#ifdef CONFIG_ANDROID wake_unlock(&srvman->sm_wake_lock); +#endif mutex_unlock(&srvman->api_access_mutex); *status = ret; return NULL; @@ -609,7 +650,9 @@ struct scsc_service *scsc_mx_service_open(struct scsc_mx *mx, enum scsc_service_ } else *status = -ENOMEM; +#ifdef CONFIG_ANDROID wake_unlock(&srvman->sm_wake_lock); +#endif mutex_unlock(&srvman->api_access_mutex); return service; @@ -635,6 +678,26 @@ void scsc_service_on_halt_ldos_off(struct scsc_service *service) EXPORT_SYMBOL(scsc_service_on_halt_ldos_off); #endif +struct scsc_bt_audio_abox *scsc_mx_service_get_bt_audio_abox(struct scsc_service *service) +{ + struct scsc_mx *mx = service->mx; + struct mifabox *ptr; + + ptr = scsc_mx_get_aboxram(mx); + + return ptr->aboxram; +} + +struct mifabox *scsc_mx_service_get_aboxram(struct scsc_service *service) +{ + struct scsc_mx *mx = service->mx; + struct mifabox *ptr; + + ptr = scsc_mx_get_aboxram(mx); + + return ptr; +} + /** * Allocate a contiguous block of SDRAM accessible to Client Driver * @@ -910,6 +973,12 @@ struct device *scsc_service_get_device(struct scsc_service *service) } EXPORT_SYMBOL(scsc_service_get_device); +struct device *scsc_service_get_device_by_mx(struct scsc_mx *mx) +{ + return scsc_mx_get_device(mx); +} +EXPORT_SYMBOL(scsc_service_get_device_by_mx); + /* Force a FW panic for test purposes only */ int scsc_service_force_panic(struct scsc_service *service) { @@ -984,6 +1053,7 @@ u32 scsc_service_mifsmapper_get_bank_base_address(struct scsc_service *service, EXPORT_SYMBOL(scsc_service_mifsmapper_get_bank_base_address); #endif +#ifdef CONFIG_SCSC_QOS int scsc_service_pm_qos_add_request(struct scsc_service *service, enum scsc_qos_config config) { struct scsc_mx *mx = service->mx; @@ -1016,7 +1086,7 @@ int scsc_service_pm_qos_remove_request(struct scsc_service *service) return 0; } EXPORT_SYMBOL(scsc_service_pm_qos_remove_request); - +#endif #ifdef CONFIG_SCSC_MXLOGGER /* If there is no service/mxman associated, register the observer as global (will affect all the mx instanes)*/ /* Users of these functions should ensure that the registers/unregister functions are balanced (i.e. if observer is registed as global, diff --git a/drivers/misc/samsung/scsc/scsc_wlbtd.c b/drivers/misc/samsung/scsc/scsc_wlbtd.c index 3ae2357aa8df..c8e846edea68 100755 --- a/drivers/misc/samsung/scsc/scsc_wlbtd.c +++ b/drivers/misc/samsung/scsc/scsc_wlbtd.c @@ -9,10 +9,11 @@ #define MAX_TIMEOUT 30000 /* in milisecounds */ /* completion to indicate when moredump is done */ -static DECLARE_COMPLETION(script_done); +static DECLARE_COMPLETION(event_done); static DEFINE_MUTEX(build_type_lock); static char *build_type; +static DEFINE_MUTEX(sable_lock); /** * This callback runs whenever the socket receives messages. @@ -33,7 +34,8 @@ static int msg_from_wlbtd_cb(struct sk_buff *skb, struct genl_info *info) SCSC_TAG_ERR(WLBTD, "returned error : %u\n", status); } - complete(&script_done); + complete(&event_done); + return 0; } @@ -53,7 +55,8 @@ static int msg_from_wlbtd_sable_cb(struct sk_buff *skb, struct genl_info *info) SCSC_TAG_ERR(WLBTD, "returned error : %u\n", status); } - complete(&script_done); + complete(&event_done); + return 0; } @@ -137,7 +140,7 @@ const struct genl_ops scsc_ops[] = { /* The netlink family */ static struct genl_family scsc_nlfamily = { .id = 0, /* Don't bother with a hardcoded ID */ - .name = "scsc_nl_family", /* Have users key off the name instead */ + .name = "scsc_mdp_family", /* Have users key off the name instead */ .hdrsize = 0, /* No private header */ .version = 1, .maxattr = __ATTR_MAX, @@ -223,6 +226,7 @@ int call_wlbtd_sable(const char *trigger, u16 reason_code) unsigned long completion_jiffies = 0; unsigned long max_timeout_jiffies = msecs_to_jiffies(MAX_TIMEOUT); + mutex_lock(&sable_lock); SCSC_TAG_INFO(WLBTD, "start:trigger - %s\n", trigger); skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); @@ -280,11 +284,10 @@ int call_wlbtd_sable(const char *trigger, u16 reason_code) SCSC_TAG_INFO(WLBTD, "waiting for completion\n"); /* wait for script to finish */ - completion_jiffies = wait_for_completion_timeout(&script_done, + completion_jiffies = wait_for_completion_timeout(&event_done, max_timeout_jiffies); if (completion_jiffies) { - completion_jiffies = max_timeout_jiffies - completion_jiffies; SCSC_TAG_INFO(WLBTD, "sable generated in %dms\n", (int)jiffies_to_msecs(completion_jiffies) ? : 1); @@ -292,9 +295,10 @@ int call_wlbtd_sable(const char *trigger, u16 reason_code) SCSC_TAG_ERR(WLBTD, "wait for completion timed out !\n"); /* reinit so completion can be re-used */ - reinit_completion(&script_done); + reinit_completion(&event_done); SCSC_TAG_INFO(WLBTD, " end:trigger - %s\n", trigger); + mutex_unlock(&sable_lock); return rc; @@ -372,19 +376,19 @@ int call_wlbtd(const char *script_path) SCSC_TAG_INFO(WLBTD, "waiting for completion\n"); /* wait for script to finish */ - completion_jiffies = wait_for_completion_timeout(&script_done, + completion_jiffies = wait_for_completion_timeout(&event_done, max_timeout_jiffies); - if (completion_jiffies != max_timeout_jiffies) { + if (completion_jiffies) { completion_jiffies = max_timeout_jiffies - completion_jiffies; SCSC_TAG_INFO(WLBTD, "done in %dms\n", - (int)jiffies_to_msecs(completion_jiffies)); + (int)jiffies_to_msecs(completion_jiffies) ? : 1); } else SCSC_TAG_ERR(WLBTD, "wait for completion timed out !\n"); /* reinit so completion can be re-used */ - reinit_completion(&script_done); + reinit_completion(&event_done); SCSC_TAG_DEBUG(WLBTD, "end\n"); @@ -408,7 +412,7 @@ int scsc_wlbtd_init(void) return -1; } - init_completion(&script_done); + init_completion(&event_done); return r; } diff --git a/drivers/misc/samsung/scsc/scsc_wlbtd.h b/drivers/misc/samsung/scsc/scsc_wlbtd.h index 7c89c536f008..51b821af65af 100644 --- a/drivers/misc/samsung/scsc/scsc_wlbtd.h +++ b/drivers/misc/samsung/scsc/scsc_wlbtd.h @@ -43,7 +43,7 @@ enum events { }; static const struct genl_multicast_group scsc_mcgrp[] = { - { .name = "scsc_mc_grp", }, + { .name = "scsc_mdp_grp", }, }; int scsc_wlbtd_init(void); diff --git a/drivers/misc/samsung/scsc/srvman.h b/drivers/misc/samsung/scsc/srvman.h index 2435b0ee13a5..03d213e1ca43 100755 --- a/drivers/misc/samsung/scsc/srvman.h +++ b/drivers/misc/samsung/scsc/srvman.h @@ -7,7 +7,9 @@ #ifndef _SRVMAN_H #define _SRVMAN_H +#ifdef CONFIG_ANDROID #include +#endif struct srvman; @@ -26,7 +28,9 @@ struct srvman { struct mutex service_list_mutex; struct mutex api_access_mutex; bool error; +#ifdef CONFIG_ANDROID struct wake_lock sm_wake_lock; +#endif }; diff --git a/drivers/misc/samsung/scsc_bt/Makefile b/drivers/misc/samsung/scsc_bt/Makefile index 290e13ca0b1d..c6ae27153ad2 100644 --- a/drivers/misc/samsung/scsc_bt/Makefile +++ b/drivers/misc/samsung/scsc_bt/Makefile @@ -12,10 +12,10 @@ scsc_bt-$(CONFIG_SCSC_ANT) += scsc_ant.o ccflags-y += $(CONFIG_SAMSUNG_MAXWELL_EXTRA) ## See sibling scsc/ Makefile for an explanation of the reasons of ## the following ifeq/else -ifeq ($(CONFIG_SCSC_DEBUG), m) +ifeq ($(CONFIG_SCSC_LOGRING), m) ccflags-y += -DCONFIG_SCSC_PRINTK else -ccflags-$(CONFIG_SCSC_DEBUG) += -DCONFIG_SCSC_PRINTK +ccflags-$(CONFIG_SCSC_LOGRING) += -DCONFIG_SCSC_PRINTK endif ifeq ($(CONFIG_SCSC_BT_BLUEZ), m) diff --git a/drivers/misc/samsung/scsc_bt/scsc_bt_module.c b/drivers/misc/samsung/scsc_bt/scsc_bt_module.c index a3af5c63dfeb..ce5fe1fd332c 100755 --- a/drivers/misc/samsung/scsc_bt/scsc_bt_module.c +++ b/drivers/misc/samsung/scsc_bt/scsc_bt_module.c @@ -44,7 +44,6 @@ #define SCSC_MODDESC "SCSC MX BT Driver" #define SCSC_MODAUTH "Samsung Electronics Co., Ltd" #define SCSC_MODVERSION "-devel" -#define SCSC_BT_LOGGER "/system/bin/bt_dump.sh" #define SLSI_BT_SERVICE_CLOSE_RETRY 60 #define SLSI_BT_SERVICE_STOP_RECOVERY_TIMEOUT 20000 @@ -79,7 +78,7 @@ static int ant_service_start_count; static u64 bluetooth_address; #ifdef CONFIG_ARCH_EXYNOS -static char *bluetooth_address_fallback = "00:00:00:00:00:00"; +static char bluetooth_address_fallback[] = "00:00:00:00:00:00"; #endif static u32 bt_info_trigger; static u32 bt_info_interrupt; @@ -87,13 +86,12 @@ static u32 firmware_control; static bool firmware_control_reset = true; static u32 firmware_mxlog_filter; static bool disable_service; -static bool call_usermode_helper; -static char *envp[] = { "HOME=/", "PATH=/system/bin:/sbin:", NULL }; -static char *argv[] = { SCSC_BT_LOGGER, NULL }; /* Audio */ static struct device *audio_device; +static struct device *previous_audio_device; static bool audio_device_probed; +static bool audio_device_been_probed; static struct scsc_bt_audio bt_audio; module_param(bluetooth_address, ullong, S_IRUGO | S_IWUSR); @@ -101,7 +99,8 @@ MODULE_PARM_DESC(bluetooth_address, "Bluetooth address"); #ifdef CONFIG_ARCH_EXYNOS -module_param(bluetooth_address_fallback, charp, 0444); +module_param_string(bluetooth_address_fallback, bluetooth_address_fallback, + sizeof(bluetooth_address_fallback), 0444); MODULE_PARM_DESC(bluetooth_address_fallback, "Bluetooth address as proposed by the driver"); #endif @@ -126,9 +125,6 @@ module_param(disable_service, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(disable_service, "Disables service startup"); -module_param(call_usermode_helper, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(call_usermode_helper, "Allows the call to the usermode helper"); - /* * Service event callbacks called from mx-core when things go wrong */ @@ -142,6 +138,19 @@ static void bt_stop_on_failure(struct scsc_service_client *client) bt_recovery_in_progress = 1; atomic_inc(&bt_service.error_count); + + /* Zero the shared memory on error. The A-Box does not stop using this + * memory immediately as designed. To prevent noise during recovery we zero the + * shared memory before freeing it + */ + mutex_lock(&bt_audio_mutex); + + if (bt_service.abox_ref != 0 && bt_audio.abox_virtual) { + memset(bt_audio.abox_virtual->abox_to_bt_streaming_if_data, 0, SCSC_BT_AUDIO_ABOX_DATA_SIZE); + memset(bt_audio.abox_virtual->bt_to_abox_streaming_if_data, 0, SCSC_BT_AUDIO_ABOX_DATA_SIZE); + } + + mutex_unlock(&bt_audio_mutex); } static void bt_failure_reset(struct scsc_service_client *client, u16 scsc_panic_code) @@ -205,17 +214,6 @@ static struct scsc_service_client mx_ant_client = { }; #endif -static void scsc_bt_invoke_usermode_helper(void) -{ - int ret = 0; - - ret = call_usermodehelper(SCSC_BT_LOGGER, argv, envp, UMH_WAIT_EXEC); - if (ret != 0) - SCSC_TAG_ERR(BT_COMMON, "Bluetooth logger failed with error: %i\n", ret); - else - SCSC_TAG_INFO(BT_COMMON, "Bluetooth logger invoked successfully\n"); -} - static void slsi_sm_bt_service_cleanup_interrupts(void) { u16 int_src = bt_service.bsmhcp_protocol->header.info_bg_to_ap_int_src; @@ -243,8 +241,8 @@ static int slsi_sm_bt_service_cleanup_stop_service(void) scsc_mx_service_service_failed(bt_service.service, "BT service stop failed"); SCSC_TAG_DEBUG(BT_COMMON, "force service fail complete\n"); - return -EIO; } + return -EIO; } return 0; @@ -273,11 +271,12 @@ static void slsi_bt_audio_remove(void) { size_t size; - if (audio_device == NULL || bt_audio.dev_iommu_unmap == NULL) + if (previous_audio_device == NULL || bt_audio.dev_iommu_unmap == NULL) return; size = PAGE_ALIGN(sizeof(*bt_audio.abox_physical)); - bt_audio.dev_iommu_unmap(audio_device, size); + bt_audio.dev_iommu_unmap(previous_audio_device, size); + previous_audio_device = NULL; } #ifdef CONFIG_SCSC_LOG_COLLECTION @@ -340,9 +339,6 @@ static int slsi_sm_bt_service_cleanup(bool allow_service_stop) mutex_lock(&bt_audio_mutex); if (audio_device) { - if (audio_device_probed) - slsi_bt_audio_remove(); - bt_audio.dev = NULL; bt_audio.abox_virtual = NULL; bt_audio.abox_physical = NULL; @@ -798,15 +794,25 @@ int slsi_sm_bt_service_start(void) * only if the physical start address of the 4MB region is aligned * to 4kB (which maybe will be always the case). */ - err = scsc_mx_service_mifram_alloc(bt_service.service, - sizeof(struct scsc_bt_audio_abox), - &bt_service.abox_ref, - SCSC_BT_AUDIO_PAGE_SIZE); + + /* unmap previously mapped memory if necessary */ + if (audio_device_been_probed) { + slsi_bt_audio_remove(); + /* audio_device_been_probed is always true once set */ + } + + err = scsc_mx_service_mif_ptr_to_addr(bt_service.service, + scsc_mx_service_get_bt_audio_abox(bt_service.service), + &bt_service.abox_ref); if (err) { - SCSC_TAG_WARNING(BT_COMMON, "mifram alloc failed\n"); + SCSC_TAG_WARNING(BT_COMMON, "scsc_mx_service_mif_ptr_to_addr failed\n"); err = -EINVAL; goto exit; } + /* irrespective of the technical definition of probe - wrt to memory allocation it has been */ + audio_device_been_probed = true; + /* ...and this is the audio_device it was associated with */ + previous_audio_device = audio_device; bt_audio.abox_virtual = (struct scsc_bt_audio_abox *) scsc_mx_service_mif_addr_to_ptr( @@ -1135,15 +1141,7 @@ static int scsc_bt_h4_open(struct inode *inode, struct file *file) ret = slsi_sm_bt_service_start(); if (0 == ret) bt_service.h4_users = true; - else if (call_usermode_helper) { - scsc_bt_invoke_usermode_helper(); - call_usermode_helper = false; - } } else { - if (call_usermode_helper) { - scsc_bt_invoke_usermode_helper(); - call_usermode_helper = false; - } ret = -EBUSY; } @@ -1259,15 +1257,7 @@ static int scsc_ant_open(struct inode *inode, struct file *file) ret = slsi_sm_ant_service_start(); if (ret == 0) ant_service.ant_users = true; - else if (call_usermode_helper) { - scsc_bt_invoke_usermode_helper(); - call_usermode_helper = false; - } } else { - if (call_usermode_helper) { - scsc_bt_invoke_usermode_helper(); - call_usermode_helper = false; - } ret = -EBUSY; } @@ -1878,9 +1868,6 @@ int scsc_bt_audio_unregister(struct device *dev) mutex_lock(&bt_audio_mutex); if (audio_device != NULL && dev == audio_device) { - if (audio_device_probed) - slsi_bt_audio_remove(); - bt_audio.dev = NULL; bt_audio.abox_virtual = NULL; bt_audio.abox_physical = NULL; diff --git a/drivers/misc/samsung/scsc_bt/scsc_bt_priv.h b/drivers/misc/samsung/scsc_bt/scsc_bt_priv.h index 8db8f92d6499..1415ea0b43ab 100755 --- a/drivers/misc/samsung/scsc_bt/scsc_bt_priv.h +++ b/drivers/misc/samsung/scsc_bt/scsc_bt_priv.h @@ -281,15 +281,16 @@ extern struct scsc_bt_service bt_service; * - cte type : 1 octet * - Slot durations : 1 octet * - packet_status : 1 octet + * - event_counter : 2 octets * - Sample count : 1 octet ********************************* - * Total : 15 octets + * Total : 17 octets * * The maximum hci event size in bytes is: - * (15 + (number of samples * 2 (both I and Q))) + * (17 + (number of samples * 2 (both I and Q))) * */ -#define HCI_IQ_REPORT_MAX_LEN (15 + (2 * HCI_IQ_REPORTING_MAX_NUM_SAMPLES)) +#define HCI_IQ_REPORT_MAX_LEN (17 + (2 * HCI_IQ_REPORTING_MAX_NUM_SAMPLES)) #define HCI_LE_CONNECTIONLESS_IQ_REPORT_EVENT_SUB_CODE (0x15) #define HCI_LE_CONNECTION_IQ_REPORT_EVENT_SUB_CODE (0x16) diff --git a/drivers/misc/samsung/scsc_bt/scsc_shm.c b/drivers/misc/samsung/scsc_bt/scsc_shm.c index 01d1859d7126..cbf81cf5f8be 100755 --- a/drivers/misc/samsung/scsc_bt/scsc_shm.c +++ b/drivers/misc/samsung/scsc_bt/scsc_shm.c @@ -831,6 +831,8 @@ static ssize_t scsc_bt_shm_h4_read_iq_report_evt(char __user *buf, size_t len) h4_iq_report_evt[index++] = td->cte_type; h4_iq_report_evt[index++] = td->slot_durations; h4_iq_report_evt[index++] = td->packet_status; + h4_iq_report_evt[index++] = td->event_count & 0xFF; + h4_iq_report_evt[index++] = (td->event_count >> 8) & 0xFF; h4_iq_report_evt[index++] = td->sample_count; /* Total length of hci event */ @@ -1166,6 +1168,9 @@ ssize_t scsc_bt_shm_h4_read(struct file *file, char __user *buf, size_t len, lof bool gen_bg_int = false; bool gen_fg_int = false; + if (len == 0) + return 0; + /* Only 1 reader is allowed */ if (1 != atomic_inc_return(&bt_service.h4_readers)) { atomic_dec(&bt_service.h4_readers); @@ -1525,6 +1530,8 @@ unsigned scsc_bt_shm_h4_poll(struct file *file, poll_table *wait) bt_service.bsmhcp_protocol->header.mailbox_acl_rx_read || bt_service.bsmhcp_protocol->header.mailbox_acl_free_write != bt_service.bsmhcp_protocol->header.mailbox_acl_free_read || + bt_service.bsmhcp_protocol->header.mailbox_iq_report_write != + bt_service.bsmhcp_protocol->header.mailbox_iq_report_read || (bt_service.read_operation != BT_READ_OP_NONE && bt_service.read_operation != BT_READ_OP_STOP) || ((BT_READ_OP_STOP != bt_service.read_operation) && diff --git a/drivers/net/wireless/scsc/Kconfig b/drivers/net/wireless/scsc/Kconfig index 97db0870990a..45f2a725026e 100755 --- a/drivers/net/wireless/scsc/Kconfig +++ b/drivers/net/wireless/scsc/Kconfig @@ -119,6 +119,12 @@ config SCSC_WLAN_ENHANCED_LOGGING This option enables the Enhanced Logging Feature. +config SCSC_WLAN_ACM_API + bool "Provide TSF read API" + default n + ---help--- + This option provides API to read TSF. + endif config SCSC_WLAN_MAC_ADDRESS_FILENAME @@ -148,6 +154,12 @@ config SCSC_WLAN_WIFI_SHARING ---help--- This option tells if wifi sharing is supported or not. +config SCSC_WLAN_ENABLE_MAC_RANDOMISATION + bool "Wifi Mac Randomization Support" + default n + ---help--- + This option tells if mac randomization is supported or not. + config SCSC_WLAN_SINGLE_ANTENNA depends on SCSC_WLAN_WIFI_SHARING bool "Single Antenna Supported" diff --git a/drivers/net/wireless/scsc/Makefile b/drivers/net/wireless/scsc/Makefile index 409457b9b77e..23bef07e9042 100755 --- a/drivers/net/wireless/scsc/Makefile +++ b/drivers/net/wireless/scsc/Makefile @@ -4,7 +4,7 @@ # PURPOSE: # Build instructions for SCSC Wlan driver. # -# Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved +# Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved # ---------------------------------------------------------------------------- # Needed since this subdir is symlinked in the main Kernel tree @@ -12,78 +12,84 @@ clean-files := *.o *.ko obj-$(CONFIG_SCSC_WLAN) += scsc_wlan.o -scsc_wlan-y += hip4.o -scsc_wlan-y += mbulk.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += hip4.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += mbulk.o # ---------------------------------------------------------------------------- # HIP4 sampler # ---------------------------------------------------------------------------- ifeq ($(CONFIG_SCSC_WLAN_HIP4_PROFILING),y) -scsc_wlan-y += hip4_sampler.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += hip4_sampler.o endif scsc_wlan-$(CONFIG_SCSC_SMAPPER) += hip4_smapper.o # Upper driver -scsc_wlan-y += dev.o -scsc_wlan-y += cfg80211_ops.o -scsc_wlan-y += netif.o -scsc_wlan-y += rx.o -scsc_wlan-y += tx.o -scsc_wlan-y += ba.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += dev.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += cfg80211_ops.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += netif.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += rx.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += tx.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += ba.o # SAPs -scsc_wlan-y += sap_mlme.o -scsc_wlan-y += sap_ma.o -scsc_wlan-y += sap_dbg.o -scsc_wlan-y += sap_test.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += sap_mlme.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += sap_ma.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += sap_dbg.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += sap_test.o # ---------------------------------------------------------------------------- # Common Driver Files # ---------------------------------------------------------------------------- -scsc_wlan-y += mib.o -scsc_wlan-y += mib_text_convert.o -scsc_wlan-y += debug.o -scsc_wlan-y += debug_frame.o -scsc_wlan-y += procfs.o -scsc_wlan-y += mgt.o -scsc_wlan-y += mlme.o -scsc_wlan-y += udi.o -scsc_wlan-y += log_clients.o -scsc_wlan-y += src_sink.o -scsc_wlan-y += fw_test.o -scsc_wlan-y += cac.o -scsc_wlan-y += scsc_wifi_fcq.o -scsc_wlan-y += ioctl.o -scsc_wlan-y += wakelock.o -scsc_wlan-y += traffic_monitor.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += mib.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += mib_text_convert.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += debug.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += debug_frame.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += procfs.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += mgt.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += mlme.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += udi.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += log_clients.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += src_sink.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += fw_test.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += cac.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += scsc_wifi_fcq.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += ioctl.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += wakelock.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += traffic_monitor.o + +# ---------------------------------------------------------------------------- +# ACM +# ---------------------------------------------------------------------------- +ifeq ($(CONFIG_SCSC_WLAN_ACM_API),y) +scsc_wlan-$(CONFIG_SCSC_WLAN) += acm_api.o +endif # ---------------------------------------------------------------------------- # Building for Hardware # ---------------------------------------------------------------------------- -scsc_wlan-y += hip.o -scsc_wlan-y += cm_if.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += hip.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += cm_if.o ifeq ($(CONFIG_SCSC_WLAN_KIC_OPS),y) -scsc_wlan-y += kic.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += kic.o endif ccflags-$(CONFIG_SCSC_WLAN_KIC_OPS) += -DCONFIG_SCSC_WLAN_KIC_OPS ifeq ($(CONFIG_SCSC_WLAN_GSCAN_ENABLE),y) -scsc_wlan-y += nl80211_vendor.o +scsc_wlan-$(CONFIG_SCSC_WLAN) += nl80211_vendor.o ccflags-y += -DCONFIG_SCSC_WLAN_GSCAN_ENABLE endif ifeq ($(CONFIG_SCSC_WLAN_KEY_MGMT_OFFLOAD),y) ccflags-y += -DCONFIG_SCSC_WLAN_KEY_MGMT_OFFLOAD endif + # --------------------------------------------------------------------------- # Include # --------------------------------------------------------------------------- -ccflags-y += -Idrivers/misc/samsung/scsc -ccflags-y += -Iinclude/scsc -ccflags-y += $(CONFIG_SAMSUNG_MAXWELL_EXTRA) -ccflags-y += -I$(src) +# TODO: This is only required because scsc_wifilogger is in the wrong driver directory +ccflags-y += -Idrivers/misc/samsung/scsc # ---------------------------------------------------------------------------- # Wlan configuration @@ -102,6 +108,7 @@ ccflags-$(CONFIG_SCSC_WLAN_MUTEX_DEBUG) += -DC ccflags-$(CONFIG_SCSC_WLAN_BLOCK_IPV6) += -DCONFIG_SCSC_WLAN_BLOCK_IPV6 ccflags-$(CONFIG_SCSC_WLAN_DISABLE_NAT_KA) += -DCONFIG_SCSC_WLAN_DISABLE_NAT_KA +ccflags-y += $(CONFIG_SAMSUNG_MAXWELL_EXTRA) ccflags-y += -DCONFIG_SCSC_WLAN_MAX_INTERFACES=$(CONFIG_SCSC_WLAN_MAX_INTERFACES) # Android specific build options @@ -109,8 +116,8 @@ ccflags-$(CONFIG_SCSC_WLAN_ANDROID) += -DCONFIG_SCSC_WLAN_ANDROID ## See drivers/misc/samsung/scsc/ Makefile for an explanation of the reasons ## of the following ifeq/else -ifeq ($(CONFIG_SCSC_DEBUG), m) +ifeq ($(CONFIG_SCSC_LOGRING), m) ccflags-y += -DCONFIG_SCSC_PRINTK else -ccflags-$(CONFIG_SCSC_DEBUG) += -DCONFIG_SCSC_PRINTK +ccflags-$(CONFIG_SCSC_LOGRING) += -DCONFIG_SCSC_PRINTK endif diff --git a/drivers/net/wireless/scsc/acm_api.c b/drivers/net/wireless/scsc/acm_api.c new file mode 100755 index 000000000000..8cba1489ea40 --- /dev/null +++ b/drivers/net/wireless/scsc/acm_api.c @@ -0,0 +1,74 @@ +/***************************************************************************** + * + * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * + ****************************************************************************/ + +#include +#include "mlme.h" +#include "mib.h" +#include "debug.h" +/* PSID Hdr(4) + VLDATA Hdr(1) + TSF(8) * + padding(1)*/ +#define TSF_RESP_SIZE (14) + +unsigned long long SDA_getTsf(const unsigned char if_id) +{ + struct net_device *dev = NULL; + struct netdev_vif *ndev_vif = NULL; + struct slsi_dev *sdev = NULL; + struct slsi_mib_data mibreq = { 0, NULL }; + struct slsi_mib_data mibrsp = { 0, NULL }; + /* Alloc buffer in stack to avoid possible scheduling when malloc.*/ + u8 res_payload[TSF_RESP_SIZE] = { 0 }; + int r = 0; + int rx_length = 0; + unsigned long long ret = 0; + + read_lock(&dev_base_lock); + dev = first_net_device(&init_net); + while (dev) { + if (if_id == 0 && !dev->name && memcmp(dev->name, "wlan0", 5) == 0) + break; + else if (if_id == 1 && !dev->name && memcmp(dev->name, "p2p0", 4) == 0) + break; + dev = next_net_device(dev); + } + read_unlock(&dev_base_lock); + + if (!dev) { + SLSI_ERR(sdev, "dev is null\n"); + return 0; + } + ndev_vif = netdev_priv(dev); + if (!ndev_vif) { + SLSI_ERR(sdev, "ndev_vif is null\n"); + return 0; + } + sdev = ndev_vif->sdev; + if (!sdev) { + SLSI_ERR(sdev, "sdev is null\n"); + return 0; + } + + SLSI_DBG3(sdev, SLSI_MLME, "\n"); + slsi_mib_encode_get(&mibreq, SLSI_PSID_UNIFI_CURRENT_TSF_TIME, 0); + mibrsp.dataLength = sizeof(res_payload); + mibrsp.data = res_payload; + + r = slsi_mlme_get(sdev, dev, mibreq.data, mibreq.dataLength, mibrsp.data, mibrsp.dataLength, &rx_length); + + kfree(mibreq.data); + + if (r == 0) { + mibrsp.dataLength = rx_length; + if (rx_length == 0) { + SLSI_ERR(sdev, "Mib decode error\n"); + return 0; + } + slsi_mib_decodeInt64(&mibrsp.data[4], &ret); + } else { + SLSI_ERR(sdev, "Mib read failed (error: %d)\n", r); + return 0; + } + return ret; +} diff --git a/drivers/net/wireless/scsc/ba.c b/drivers/net/wireless/scsc/ba.c index 603c9660d53f..1bf1e4d43259 100755 --- a/drivers/net/wireless/scsc/ba.c +++ b/drivers/net/wireless/scsc/ba.c @@ -98,11 +98,7 @@ void slsi_ba_process_complete(struct net_device *dev) struct sk_buff *skb; while ((skb = slsi_skb_dequeue(&ndev_vif->ba_complete)) != NULL) { -#ifdef CONFIG_SCSC_WLAN_RX_NAPI - slsi_rx_data_napi(ndev_vif->sdev, dev, skb, true); -#else - slsi_rx_data(ndev_vif->sdev, dev, skb, true); -#endif + slsi_rx_data_deliver_skb(ndev_vif->sdev, dev, skb); } } @@ -111,7 +107,9 @@ static void slsi_ba_signal_process_complete(struct net_device *dev) struct netdev_vif *ndev_vif = netdev_priv(dev); atomic_set(&ndev_vif->ba_flush, 1); +#ifndef CONFIG_SCSC_WLAN_RX_NAPI slsi_skb_schedule_work(&ndev_vif->rx_data); +#endif } static void ba_add_frame_to_ba_complete(struct net_device *dev, struct slsi_ba_frame_desc *frame_desc) @@ -250,9 +248,17 @@ static int ba_consume_frame_or_get_buffer_index(struct net_device *dev, struct s return i; } +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +static void slsi_ba_aging_timeout_handler(struct timer_list *t) +#else static void slsi_ba_aging_timeout_handler(unsigned long data) +#endif { +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + struct slsi_ba_session_rx *ba_session_rx = from_timer(ba_session_rx, t, ba_age_timer); +#else struct slsi_ba_session_rx *ba_session_rx = (struct slsi_ba_session_rx *)data; +#endif u8 i, j; u8 gap = 1; u16 temp_sn; @@ -298,7 +304,11 @@ static void slsi_ba_aging_timeout_handler(unsigned long data) } slsi_spinlock_unlock(&ba_session_rx->ba_lock); /* Process the data now marked as completed */ +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + slsi_ba_process_complete(dev); +#else slsi_ba_signal_process_complete(dev); +#endif } else { slsi_spinlock_unlock(&ba_session_rx->ba_lock); } @@ -494,9 +504,13 @@ static int slsi_rx_ba_start(struct net_device *dev, ba_session_rx->trigger_ba_after_ssn = false; ba_session_rx->tid = tid; ba_session_rx->timer_on = false; +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + timer_setup(&ba_session_rx->ba_age_timer, slsi_ba_aging_timeout_handler, 0); +#else ba_session_rx->ba_age_timer.function = slsi_ba_aging_timeout_handler; ba_session_rx->ba_age_timer.data = (unsigned long)ba_session_rx; init_timer(&ba_session_rx->ba_age_timer); +#endif ba_session_rx->active = true; SLSI_NET_DBG1(dev, SLSI_RX_BA, "Started a new BA session tid=%d buffer_size=%d start_sn=%d\n", @@ -522,7 +536,6 @@ static void slsi_ba_process_error(struct net_device *dev, ba_scroll_window(dev, ba_session_rx, sequence_number); slsi_spinlock_unlock(&ba_session_rx->ba_lock); - slsi_ba_signal_process_complete(dev); } diff --git a/drivers/net/wireless/scsc/cfg80211_ops.c b/drivers/net/wireless/scsc/cfg80211_ops.c index a550c1881b3b..4f9541e9a631 100755 --- a/drivers/net/wireless/scsc/cfg80211_ops.c +++ b/drivers/net/wireless/scsc/cfg80211_ops.c @@ -16,7 +16,9 @@ #include "unifiio.h" #include "mib.h" +#ifdef CONFIG_ANDROID #include "scsc_wifilogger_rings.h" +#endif #define SLSI_MAX_CHAN_2G_BAND 14 @@ -61,7 +63,7 @@ struct net_device *slsi_add_ virtual_intf(struct wiphy *wiphy, #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 0)) SLSI_UNUSED_PARAMETER(flags); #endif - SLSI_NET_DBG1(dev, SLSI_CFG80211, "Intf name:%d, type:%d, macaddr:%pM\n", name, type, params->macaddr); + SLSI_NET_DBG1(dev, SLSI_CFG80211, "Intf name:%s, type:%d, macaddr:%pM\n", name, type, params->macaddr); dev = slsi_new_interface_create(wiphy, name, type, params); if (!dev) goto exit_with_error; @@ -91,7 +93,7 @@ int slsi_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) if (WARN_ON(!dev)) return -EINVAL; - SLSI_NET_DBG1(dev, SLSI_CFG80211, "Dev name:%d\n", dev->name); + SLSI_NET_DBG1(dev, SLSI_CFG80211, "Dev name:%s\n", dev->name); slsi_stop_net_dev(sdev, dev); slsi_netif_remove_rtlnl_locked(sdev, dev); @@ -421,6 +423,9 @@ int slsi_scan(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *channels[64]; int i, chan_count = 0; struct cfg80211_scan_info info = {.aborted = false}; +#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION + u8 mac_addr_mask[ETH_ALEN] = {0xFF}; +#endif if (WARN_ON(!request->wdev)) return -EINVAL; @@ -516,6 +521,27 @@ int slsi_scan(struct wiphy *wiphy, struct net_device *dev, ndev_vif->scan[SLSI_SCAN_HW_ID].is_blocking_scan = false; slsi_purge_scan_results(ndev_vif, SLSI_SCAN_HW_ID); + +#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION + if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { + memcpy(sdev->scan_mac_addr, request->mac_addr, ETH_ALEN); + r = slsi_set_mac_randomisation_mask(sdev, request->mac_addr_mask); + if (!r) + sdev->scan_addr_set = 1; + } else if (sdev->scan_addr_set == 1) { + memset(mac_addr_mask, 0xFF, ETH_ALEN); + for (i = 3; i < ETH_ALEN; i++) + mac_addr_mask[i] = 0x00; + slsi_set_mac_randomisation_mask(sdev, mac_addr_mask); + } else { + if (sdev->scan_addr_set) { + memset(mac_addr_mask, 0xFF, ETH_ALEN); + slsi_set_mac_randomisation_mask(sdev, mac_addr_mask); + if (!r) + sdev->scan_addr_set = 0; + } + } +#endif r = slsi_mlme_add_scan(sdev, dev, scan_type, @@ -705,9 +731,11 @@ static void slsi_abort_hw_scan(struct slsi_dev *sdev, struct net_device *dev) struct netdev_vif *ndev_vif = netdev_priv(dev); SLSI_MUTEX_LOCK(ndev_vif->scan_mutex); + SLSI_NET_DBG1(dev, SLSI_CFG80211, "Abort on-going scan, vif_index:%d," - "ndev_vif->scan[SLSI_SCAN_HW_ID].scan_req:%d\n", ndev_vif->ifnum, + "ndev_vif->scan[SLSI_SCAN_HW_ID].scan_req:%p\n", ndev_vif->ifnum, ndev_vif->scan[SLSI_SCAN_HW_ID].scan_req); + if (ndev_vif->scan[SLSI_SCAN_HW_ID].scan_req) { (void)slsi_mlme_del_scan(sdev, dev, ndev_vif->ifnum << 8 | SLSI_SCAN_HW_ID, false); slsi_scan_complete(sdev, dev, SLSI_SCAN_HW_ID, false); @@ -732,6 +760,7 @@ int slsi_connect(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *channel; const u8 *connected_ssid = NULL; u8 peer_address[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + u16 center_freq = 0; if (slsi_is_test_mode_enabled()) { SLSI_NET_INFO(dev, "Skip sending signal, WlanLite FW does not support MLME_CONNECT.request\n"); @@ -755,20 +784,26 @@ int slsi_connect(struct wiphy *wiphy, struct net_device *dev, if (ndev_vif->sta.sta_bss) SLSI_ETHER_COPY(peer_address, ndev_vif->sta.sta_bss->bssid); - SLSI_NET_DBG2(dev, SLSI_CFG80211, - "%.*s CentFreq=%d vifStatus=%d CurrBssid:%pM NewBssid:%pM QOSinfo:%d\n", - (int)sme->ssid_len, sme->ssid, sme->channel->center_freq, ndev_vif->sta.vif_status, + + center_freq = sme->channel ? sme->channel->center_freq : 0; + + SLSI_NET_INFO(dev, "%.*s CentFreq=%d vifStatus=%d CurrBssid:%pM NewBssid:%pM QOSinfo:%d\n", + (int)sme->ssid_len, sme->ssid, center_freq, ndev_vif->sta.vif_status, peer_address, sme->bssid, sdev->device_config.qos_info); +#ifdef CONFIG_SCSC_WIFILOGGER SCSC_WLOG_PKTFATE_NEW_ASSOC(); - SCSC_WLOG_DRIVER_EVENT(WLOG_NORMAL, WIFI_EVENT_ASSOCIATION_REQUESTED, 3, - WIFI_TAG_BSSID, ETH_ALEN, sme->bssid, - WIFI_TAG_SSID, sme->ssid_len, sme->ssid, - WIFI_TAG_CHANNEL, sizeof(u16), &sme->channel->center_freq); - // ?? WIFI_TAG_VENDOR_SPECIFIC, sizeof(RSSE), RSSE); + if (sme->bssid) { + SCSC_WLOG_DRIVER_EVENT(WLOG_NORMAL, WIFI_EVENT_ASSOCIATION_REQUESTED, 3, + WIFI_TAG_BSSID, ETH_ALEN, sme->bssid, + WIFI_TAG_SSID, sme->ssid_len, sme->ssid, + WIFI_TAG_CHANNEL, sizeof(u16), ¢er_freq); + // ?? WIFI_TAG_VENDOR_SPECIFIC, sizeof(RSSE), RSSE); + } +#endif if (SLSI_IS_HS2_UNSYNC_VIF(ndev_vif)) { - slsi_hs2_vif_deactivate(sdev, dev, true); + slsi_wlan_unsync_vif_deactivate(sdev, dev, true); } else if (SLSI_IS_VIF_INDEX_P2P(ndev_vif)) { SLSI_NET_ERR(dev, "Connect requested on incorrect vif\n"); goto exit_with_error; @@ -1037,9 +1072,11 @@ int slsi_disconnect(struct wiphy *wiphy, struct net_device *dev, peer = ndev_vif->peer_sta_record[SLSI_STA_PEER_QUEUESET]; +#ifdef CONFIG_SCSC_WIFILOGGER SCSC_WLOG_DRIVER_EVENT(WLOG_NORMAL, WIFI_EVENT_DISASSOCIATION_REQUESTED, 2, WIFI_TAG_BSSID, ETH_ALEN, peer->address, WIFI_TAG_REASON_CODE, sizeof(u16), &reason_code); +#endif switch (ndev_vif->vif_type) { case FAPI_VIFTYPE_STATION: @@ -1465,7 +1502,7 @@ int slsi_set_monitor_channel(struct wiphy *wiphy, struct cfg80211_chan_def *chan SLSI_MUTEX_LOCK(ndev_vif->vif_mutex); - if (slsi_mlme_set_channel(sdev, dev, chandef->chan, 0, 0, 0) != 0) { + if (slsi_test_sap_configure_monitor_mode(sdev, dev, chandef) != 0) { SLSI_ERR(sdev, "set Monitor channel failed\n"); SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex); return -EINVAL; @@ -1549,9 +1586,8 @@ int slsi_remain_on_channel(struct wiphy *wiphy, SLSI_MUTEX_LOCK(ndev_vif->vif_mutex); SLSI_NET_DBG2(dev, SLSI_CFG80211, "channel freq = %d, duration = %d, vif_type = %d, vif_index = %d," - "sdev->p2p_state = %d\n", chan->center_freq, duration, ndev_vif->vif_type, ndev_vif->ifnum, + "sdev->p2p_state = %s\n", chan->center_freq, duration, ndev_vif->vif_type, ndev_vif->ifnum, slsi_p2p_state_text(sdev->p2p_state)); - if (!SLSI_IS_VIF_INDEX_P2P(ndev_vif)) { SLSI_NET_ERR(dev, "Invalid vif type\n"); goto exit_with_error; @@ -1666,7 +1702,7 @@ int slsi_cancel_remain_on_channel(struct wiphy *wiphy, SLSI_MUTEX_LOCK(ndev_vif->vif_mutex); - SLSI_NET_DBG2(dev, SLSI_CFG80211, "Cookie = 0x%llx, vif_type = %d, vif_index = %d, sdev->p2p_state = %d," + SLSI_NET_DBG2(dev, SLSI_CFG80211, "Cookie = 0x%llx, vif_type = %d, vif_index = %d, sdev->p2p_state = %s," "ndev_vif->ap.p2p_gc_keys_set = %d, ndev_vif->unsync.roc_cookie = 0x%llx\n", cookie, ndev_vif->vif_type, ndev_vif->ifnum, slsi_p2p_state_text(sdev->p2p_state), ndev_vif->ap.p2p_gc_keys_set, ndev_vif->unsync.roc_cookie); @@ -1911,9 +1947,9 @@ int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev, slsi_abort_hw_scan(sdev, wlan_dev); SLSI_NET_DBG1(dev, SLSI_CFG80211, "AP frequency received: %d\n", settings->chandef.chan->center_freq); -#ifdef CONFIG_SCSC_WLAN_WIFI_SHARING mgmt = (struct ieee80211_mgmt *)settings->beacon.head; beacon_ie_head_len = settings->beacon.head_len - ((u8 *)mgmt->u.beacon.variable - (u8 *)mgmt); +#ifdef CONFIG_SCSC_WLAN_WIFI_SHARING ndev_sta_vif = netdev_priv(wlan_dev); if (SLSI_IS_INTERFACE_WIFI_SHARING_AP(ndev_vif)) { SLSI_MUTEX_LOCK(ndev_sta_vif->vif_mutex); @@ -1950,30 +1986,34 @@ int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev, r = -EINVAL; goto exit_with_vif_mutex; } - if ((channel->flags) & (IEEE80211_CHAN_INDOOR_ONLY)) { - chan_flags = (IEEE80211_CHAN_INDOOR_ONLY | IEEE80211_CHAN_RADAR | IEEE80211_CHAN_DISABLED | + if (ndev_vif->iftype != NL80211_IFTYPE_P2P_GO) { + if ((channel->flags) & (IEEE80211_CHAN_INDOOR_ONLY)) { + chan_flags = (IEEE80211_CHAN_INDOOR_ONLY | IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_DISABLED | #if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 10, 13) - IEEE80211_CHAN_PASSIVE_SCAN + IEEE80211_CHAN_PASSIVE_SCAN #else - IEEE80211_CHAN_NO_IR -#endif - ); - - for (i = 0; i < wiphy->bands[NL80211_BAND_5GHZ]->n_channels; i++) { - if (!(wiphy->bands[NL80211_BAND_5GHZ]->channels[i].flags & chan_flags)) { - center_freq = wiphy->bands[NL80211_BAND_5GHZ]->channels[i].center_freq; - settings->chandef.chan = ieee80211_get_channel(wiphy, center_freq); - settings->chandef.center_freq1 = center_freq; - SLSI_DBG1(sdev, SLSI_CFG80211, "ap valid frequency :%d, chan_flags:%x\n", - center_freq, wiphy->bands[NL80211_BAND_5GHZ]->channels[i].flags); - indoor_channel = 1; - break; + IEEE80211_CHAN_NO_IR +#endif + ); + + for (i = 0; i < wiphy->bands[NL80211_BAND_5GHZ]->n_channels; i++) { + if (!(wiphy->bands[NL80211_BAND_5GHZ]->channels[i].flags & chan_flags)) { + center_freq = wiphy->bands[NL80211_BAND_5GHZ]->channels[i].center_freq; + settings->chandef.chan = ieee80211_get_channel(wiphy, center_freq); + settings->chandef.center_freq1 = center_freq; + SLSI_DBG1(sdev, SLSI_CFG80211, "ap valid frequency:%d,chan_flags:%x\n", + center_freq, + wiphy->bands[NL80211_BAND_5GHZ]->channels[i].flags); + indoor_channel = 1; + break; + } + } + if (indoor_channel == 0) { + SLSI_ERR(sdev, "No valid channel found to start the AP"); + r = -EINVAL; + goto exit_with_vif_mutex; } - } - if (indoor_channel == 0) { - SLSI_ERR(sdev, "No valid channel found to start the AP"); - r = -EINVAL; - goto exit_with_vif_mutex; } } } @@ -2061,7 +2101,11 @@ int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev, #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) - if (slsi_check_channelization(sdev, ndev_vif->chandef) != 0) { +#ifdef CONFIG_SCSC_WLAN_WIFI_SHARING + if (slsi_check_channelization(sdev, ndev_vif->chandef, wifi_sharing_channel_switched) != 0) { +#else + if (slsi_check_channelization(sdev, ndev_vif->chandef, 0) != 0) { +#endif #else if (slsi_check_channelization(sdev, ndev_vif->channel_type) != 0) { #endif @@ -2137,13 +2181,13 @@ int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev, } #endif -if ((indoor_channel == 1) + if ((indoor_channel == 1) #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING -|| (wifi_sharing_channel_switched == 1) + || (wifi_sharing_channel_switched == 1) #endif -) - slsi_modify_ies_on_channel_switch(dev, settings, ds_params_ie, ht_operation_ie, mgmt, beacon_ie_head_len); - + ) { + slsi_modify_ies_on_channel_switch(dev, settings, ds_params_ie, ht_operation_ie, mgmt, beacon_ie_head_len); + } ndev_vif->vif_type = FAPI_VIFTYPE_AP; if (slsi_mlme_add_vif(sdev, dev, dev->dev_addr, device_address) != 0) { @@ -2493,8 +2537,9 @@ int slsi_mgmt_tx_cancel_wait(struct wiphy *wiphy, SLSI_NET_DBG2(dev, SLSI_CFG80211, "iface_num = %d, cookie = 0x%llx, vif_index = %d, vif_type = %d," "sdev->p2p_state = %d, ndev_vif->mgmt_tx_data.cookie = 0x%llx, sdev->p2p_group_exp_frame = %d," - "sdev->hs2_state = %d\n", ndev_vif->ifnum, cookie, ndev_vif->vif_type, sdev->p2p_state, - ndev_vif->mgmt_tx_data.cookie, sdev->p2p_group_exp_frame, sdev->hs2_state); + "sdev->wlan_unsync_vif_state = %d\n", ndev_vif->ifnum, cookie, + ndev_vif->vif_type, sdev->p2p_state, ndev_vif->mgmt_tx_data.cookie, + sdev->p2p_group_exp_frame, sdev->wlan_unsync_vif_state); /* If device was in frame tx_rx state, clear mgmt tx data and change state */ if ((sdev->p2p_state == P2P_ACTION_FRAME_TX_RX) && (ndev_vif->mgmt_tx_data.cookie == cookie)) { @@ -2513,8 +2558,8 @@ int slsi_mgmt_tx_cancel_wait(struct wiphy *wiphy, } else if ((SLSI_IS_P2P_GROUP_STATE(sdev)) && (sdev->p2p_group_exp_frame != SLSI_P2P_PA_INVALID)) { /* acquire mutex lock if it is not group net dev */ slsi_clear_offchannel_data(sdev, (!SLSI_IS_VIF_INDEX_P2P_GROUP(ndev_vif)) ? true : false); - } else if ((sdev->hs2_state == HS2_VIF_TX) && (ndev_vif->mgmt_tx_data.cookie == cookie)) { - sdev->hs2_state = HS2_VIF_ACTIVE; + } else if ((sdev->wlan_unsync_vif_state == WLAN_UNSYNC_VIF_TX) && (ndev_vif->mgmt_tx_data.cookie == cookie)) { + sdev->wlan_unsync_vif_state = WLAN_UNSYNC_VIF_ACTIVE; cancel_delayed_work(&ndev_vif->unsync.hs2_del_vif_work); queue_delayed_work(sdev->device_wq, &ndev_vif->unsync.hs2_del_vif_work, msecs_to_jiffies(SLSI_HS2_UNSYNC_VIF_EXTRA_MSEC)); } @@ -2549,7 +2594,7 @@ void slsi_mgmt_frame_register(struct wiphy *wiphy, SLSI_UNUSED_PARAMETER(sdev); } -static int slsi_hs2_mgmt_tx(struct slsi_dev *sdev, struct net_device *dev, +static int slsi_wlan_mgmt_tx(struct slsi_dev *sdev, struct net_device *dev, struct ieee80211_channel *chan, unsigned int wait, const u8 *buf, size_t len, bool dont_wait_for_ack, u64 *cookie) { @@ -2558,10 +2603,10 @@ static int slsi_hs2_mgmt_tx(struct slsi_dev *sdev, struct net_device *dev, int r = 0; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; - slsi_hs2_dump_public_action_subtype(mgmt, true); + slsi_wlan_dump_public_action_subtype(mgmt, true); if (!ndev_vif->activated) { - r = slsi_hs2_vif_activate(sdev, dev, chan, wait); + r = slsi_wlan_unsync_vif_activate(sdev, dev, chan, wait); if (r) return r; @@ -2569,7 +2614,7 @@ static int slsi_hs2_mgmt_tx(struct slsi_dev *sdev, struct net_device *dev, if (r) goto exit_with_vif; - sdev->hs2_state = HS2_VIF_TX; + sdev->wlan_unsync_vif_state = WLAN_UNSYNC_VIF_TX; queue_delayed_work(sdev->device_wq, &ndev_vif->unsync.hs2_del_vif_work, msecs_to_jiffies(wait)); } else { /* vif is active*/ @@ -2588,7 +2633,7 @@ static int slsi_hs2_mgmt_tx(struct slsi_dev *sdev, struct net_device *dev, r = slsi_mlme_send_frame_mgmt(sdev, dev, buf, len, FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME, FAPI_MESSAGETYPE_IEEE80211_ACTION, host_tag, 0, wait * 1000, 0); if (r) goto exit_with_vif; - sdev->hs2_state = HS2_VIF_TX; + sdev->wlan_unsync_vif_state = WLAN_UNSYNC_VIF_TX; queue_delayed_work(sdev->device_wq, &ndev_vif->unsync.hs2_del_vif_work, msecs_to_jiffies(wait)); } else if (ndev_vif->chan->hw_value == chan->hw_value) { SLSI_NET_DBG1(dev, SLSI_CFG80211, "STA VIF is active on same channel, send GAS (ANQP) request on channel freq %d\n", chan->center_freq); @@ -2608,7 +2653,7 @@ static int slsi_hs2_mgmt_tx(struct slsi_dev *sdev, struct net_device *dev, return r; exit_with_vif: - slsi_hs2_vif_deactivate(sdev, dev, true); + slsi_wlan_unsync_vif_deactivate(sdev, dev, true); return r; } @@ -2679,7 +2724,7 @@ int slsi_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, } if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif)) { - r = slsi_hs2_mgmt_tx(SDEV_FROM_WIPHY(wiphy), dev, chan, wait, buf, len, dont_wait_for_ack, cookie); + r = slsi_wlan_mgmt_tx(SDEV_FROM_WIPHY(wiphy), dev, chan, wait, buf, len, dont_wait_for_ack, cookie); goto exit; } @@ -3273,6 +3318,10 @@ struct slsi_dev *slsi_cfg80211_new(struct device *dev) /* TDLS support */ wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; +#endif + /* Mac Randomization */ +#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION + wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; #endif return sdev; } diff --git a/drivers/net/wireless/scsc/cm_if.c b/drivers/net/wireless/scsc/cm_if.c index 7f59f52481a3..ea0a07441528 100755 --- a/drivers/net/wireless/scsc/cm_if.c +++ b/drivers/net/wireless/scsc/cm_if.c @@ -14,7 +14,6 @@ #include "hip4_sampler.h" #endif -#include "../scsc/scsc_mx_impl.h" /* TODO */ #include #ifdef CONFIG_SCSC_LOG_COLLECTION #include @@ -185,7 +184,7 @@ void slsi_wlan_service_probe(struct scsc_mx_module_client *module_client, struct mx_wlan_client.suspend = wlan_suspend; mx_wlan_client.resume = wlan_resume; - dev = scsc_mx_get_device(mx); + dev = scsc_service_get_device_by_mx(mx); /* The mutex must be released at this point since the attach * process may call various functions including diff --git a/drivers/net/wireless/scsc/debug.h b/drivers/net/wireless/scsc/debug.h index 1a1fd31b471f..721cf0005e85 100644 --- a/drivers/net/wireless/scsc/debug.h +++ b/drivers/net/wireless/scsc/debug.h @@ -9,14 +9,13 @@ #include #include "dev.h" +#include /* Logging modules * ======================= */ -#ifdef CONFIG_SCSC_DEBUG_COMPATIBILITY -#include -#else +#ifndef CONFIG_SCSC_DEBUG_COMPATIBILITY extern const int SLSI_INIT_DEINIT; extern const int SLSI_NETDEV; extern const int SLSI_CFG80211; @@ -68,26 +67,26 @@ extern int *slsi_dbg_filters[]; #define SLSI_EWI_NET_DEV(ndev) (likely(ndev) ? SLSI_EWI_DEV(((struct netdev_vif *)netdev_priv(ndev))->sdev) : NULL) #define SLSI_EWI_NET_NAME(ndev) (likely(ndev) ? netdev_name(ndev) : NULL) -#define SLSI_EWI(output, sdev, label, fmt, arg ...) output(SLSI_EWI_DEV(sdev), " : " label ": %s: " fmt, __func__, ## arg) -#define SLSI_EWI_NET(output, ndev, label, fmt, arg ...) output(SLSI_EWI_NET_DEV(ndev), "%-5s: " label ": %s: " fmt, SLSI_EWI_NET_NAME(ndev), __func__, ## arg) -#define SLSI_EWI_NODEV(output, label, fmt, arg ...) output(SLSI_EWI_NODEV_LABEL label ": %s: " fmt, __func__, ## arg) +#define SLSI_EWI(output, sdev, label, fmt, arg ...) output(SLSI_EWI_DEV(sdev), SCSC_PREFIX label ": %s: " fmt, __func__, ## arg) +#define SLSI_EWI_NET(output, ndev, label, fmt, arg ...) output(SLSI_EWI_NET_DEV(ndev), SCSC_PREFIX "%s: " label ": %s: " fmt, SLSI_EWI_NET_NAME(ndev), __func__, ## arg) +#define SLSI_EWI_NODEV(output, label, fmt, arg ...) output(SLSI_EWI_NODEV_LABEL SCSC_PREFIX label ": %s: " fmt, __func__, ## arg) #define SLSI_EWI_HEX(output, klevel, sdev, label, p, len, fmt, arg ...) \ do { \ SLSI_EWI(output, sdev, label, fmt, ## arg); \ - print_hex_dump(klevel, "", DUMP_PREFIX_OFFSET, 16, 1, p, len, 0); \ + print_hex_dump(klevel, SCSC_PREFIX, DUMP_PREFIX_OFFSET, 16, 1, p, len, 0); \ } while (0) #define SLSI_EWI_HEX_NET(output, klevel, dev, label, p, len, fmt, arg ...) \ do { \ SLSI_EWI_NET(output, dev, label, fmt, ## arg); \ - print_hex_dump(klevel, "", DUMP_PREFIX_OFFSET, 16, 1, p, len, 0); \ + print_hex_dump(klevel, SCSC_PREFIX, DUMP_PREFIX_OFFSET, 16, 1, p, len, 0); \ } while (0) #define SLSI_EWI_HEX_NODEV(output, klevel, label, p, len, fmt, arg ...) \ do { \ SLSI_EWI_NODEV(output, label, fmt, ## arg); \ - print_hex_dump(klevel, "", DUMP_PREFIX_OFFSET, 16, 1, p, len, 0); \ + print_hex_dump(klevel, SCSC_PREFIX, DUMP_PREFIX_OFFSET, 16, 1, p, len, 0); \ } while (0) #define SLSI_ERR(sdev, fmt, arg ...) SLSI_EWI(dev_err, sdev, "E", fmt, ## arg) diff --git a/drivers/net/wireless/scsc/dev.c b/drivers/net/wireless/scsc/dev.c index 6302411db888..32eff2068740 100755 --- a/drivers/net/wireless/scsc/dev.c +++ b/drivers/net/wireless/scsc/dev.c @@ -72,6 +72,9 @@ MODULE_PARM_DESC(vo_vi_block_ack_disabled, "Disable VO VI Block Ack logic added static int max_scan_result_count = 200; module_param(max_scan_result_count, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(max_scan_result_count, "Max scan results to be reported"); +static bool rtt_disabled = 1; +module_param(rtt_disabled, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(rtt_disabled, "Disable rtt: to disable rtt set 1"); static bool nan_disabled; module_param(nan_disabled, bool, S_IRUGO | S_IWUSR); @@ -82,6 +85,11 @@ bool slsi_dev_gscan_supported(void) return !gscan_disabled; } +bool slsi_dev_rtt_supported(void) +{ + return !rtt_disabled; +} + bool slsi_dev_llslogs_supported(void) { return !llslogs_disabled; @@ -139,7 +147,7 @@ static int slsi_dev_inetaddr_changed(struct notifier_block *nb, unsigned long da SLSI_NET_INFO(dev, "IP: %pI4\n", &ifa->ifa_address); SLSI_MUTEX_LOCK(ndev_vif->vif_mutex); -#ifndef SLSI_TEST_DEV +#if !defined SLSI_TEST_DEV && defined CONFIG_ANDROID if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif) && wake_lock_active(&sdev->wlan_wl_roam)) { SLSI_NET_DBG2(dev, SLSI_NETDEV, "Releasing the roaming wakelock\n"); wake_unlock(&sdev->wlan_wl_roam); @@ -235,6 +243,7 @@ struct slsi_dev *slsi_dev_attach(struct device *dev, struct scsc_mx *core, struc sdev->mlme_blocked = false; SLSI_MUTEX_INIT(sdev->netdev_add_remove_mutex); + SLSI_MUTEX_INIT(sdev->netdev_remove_mutex); SLSI_MUTEX_INIT(sdev->start_stop_mutex); SLSI_MUTEX_INIT(sdev->device_config_mutex); #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING @@ -271,7 +280,7 @@ struct slsi_dev *slsi_dev_attach(struct device *dev, struct scsc_mx *core, struc slsi_wakelock_init(&sdev->wlan_wl, "wlan"); slsi_wakelock_init(&sdev->wlan_wl_mlme, "wlan_mlme"); slsi_wakelock_init(&sdev->wlan_wl_ma, "wlan_ma"); -#ifndef SLSI_TEST_DEV +#if !defined SLSI_TEST_DEV && defined CONFIG_ANDROID wake_lock_init(&sdev->wlan_wl_roam, WAKE_LOCK_SUSPEND, "wlan_roam"); #endif sdev->recovery_next_state = 0; @@ -419,7 +428,7 @@ err_if: slsi_wakelock_exit(&sdev->wlan_wl); slsi_wakelock_exit(&sdev->wlan_wl_mlme); slsi_wakelock_exit(&sdev->wlan_wl_ma); -#ifndef SLSI_TEST_DEV +#if !defined SLSI_TEST_DEV && defined CONFIG_ANDROID wake_lock_destroy(&sdev->wlan_wl_roam); #endif slsi_cfg80211_free(sdev); @@ -488,7 +497,7 @@ void slsi_dev_detach(struct slsi_dev *sdev) slsi_wakelock_exit(&sdev->wlan_wl); slsi_wakelock_exit(&sdev->wlan_wl_mlme); slsi_wakelock_exit(&sdev->wlan_wl_ma); -#ifndef SLSI_TEST_DEV +#if !defined SLSI_TEST_DEV && defined CONFIG_ANDROID wake_lock_destroy(&sdev->wlan_wl_roam); #endif @@ -517,6 +526,10 @@ int __init slsi_dev_load(void) sap_dbg_init(); sap_test_init(); +/* Always create devnode if TW Android P on */ +#if defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000 + slsi_create_sysfs_macaddr(); +#endif SLSI_INFO_NODEV("--- Maxwell Wi-Fi driver loaded successfully ---\n"); return 0; } @@ -525,6 +538,9 @@ void __exit slsi_dev_unload(void) { SLSI_INFO_NODEV("Unloading Maxwell Wi-Fi driver\n"); +#if defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000 + slsi_destroy_sysfs_macaddr(); +#endif /* Unregister SAPs */ sap_mlme_deinit(); sap_ma_deinit(); diff --git a/drivers/net/wireless/scsc/dev.h b/drivers/net/wireless/scsc/dev.h index 24257c16aac8..402833a102dc 100755 --- a/drivers/net/wireless/scsc/dev.h +++ b/drivers/net/wireless/scsc/dev.h @@ -57,6 +57,56 @@ #define SLSI_80211_MODE_11A 3 #define SLSI_80211_MODE_11AC 4 +#define SLSI_FW_API_RATE_HT_SELECTOR_FIELD 0xc000 +#define SLSI_FW_API_RATE_NON_HT_SELECTED 0x4000 +#define SLSI_FW_API_RATE_HT_SELECTED 0x8000 +#define SLSI_FW_API_RATE_VHT_SELECTED 0xc000 + +#define SLSI_FW_API_RATE_VHT_MCS_FIELD 0x000F +#define SLSI_FW_API_RATE_HT_MCS_FIELD 0x003F +#define SLSI_FW_API_RATE_INDEX_FIELD 0x1fff +#define SLSI_FW_API_RATE_VHT_NSS_FIELD 0x0070 +#define SLSI_FW_API_RATE_HT_NSS_FIELD 0x0040 + +#define SLSI_FW_API_RATE_BW_FIELD 0x0600 +#define SLSI_FW_API_RATE_BW_40MHZ 0x0200 +#define SLSI_FW_API_RATE_BW_20MHZ 0x0000 + +#define SLSI_FW_API_RATE_SGI 0x0100 +#define SLSI_FW_API_RATE_GF 0x0080 + +/* indices: 3= BW20->idx_0, BW40->idx_1, BW80->idx_2. + * 2= noSGI->idx_0, SGI->idx_1 + * 10= mcs index + * rate units 100kbps + * This table for single stream Nss=1and does not include 160MHz BW and 80+80MHz BW. + */ +static const u16 slsi_rates_table[3][2][10] = { + { /* BW20 */ + { /* no SGI */ + 65, 130, 195, 260, 390, 520, 585, 650, 780, 0 + }, + { /* SGI */ + 72, 144, 217, 289, 433, 578, 650, 722, 867, 0 + } + }, + { /* BW40 */ + { /* no SGI */ + 135, 270, 405, 540, 810, 1080, 1215, 1350, 1620, 1800 + }, + { /* SGI */ + 150, 300, 450, 600, 900, 1200, 1350, 1500, 1800, 2000 + } + }, + { /* BW80 */ + { /* no SGI */ + 293, 585, 878, 1170, 1755, 2340, 2633, 2925, 3510, 3900 + }, + { /* SGI */ + 325, 650, 975, 1300, 1950, 2600, 2925, 3250, 3900, 4333 + } + } +}; /* MSDU subframe Header */ struct msduhdr { unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ @@ -104,7 +154,8 @@ static inline void ethr_ii_to_subframe_msdu(struct sk_buff *skb) #define NUM_BA_SESSIONS_PER_PEER 8 #define MAX_CHANNEL_LIST 20 #define SLSI_MAX_RX_BA_SESSIONS (8) -#define SLSI_STA_ACTION_FRAME_BITMAP (SLSI_ACTION_FRAME_PUBLIC | SLSI_ACTION_FRAME_WMM | SLSI_ACTION_FRAME_WNM | SLSI_ACTION_FRAME_QOS) +#define SLSI_STA_ACTION_FRAME_BITMAP (SLSI_ACTION_FRAME_PUBLIC | SLSI_ACTION_FRAME_WMM | SLSI_ACTION_FRAME_WNM |\ + SLSI_ACTION_FRAME_QOS | SLSI_ACTION_FRAME_PROTECTED_DUAL) /* Default value for MIB SLSI_PSID_UNIFI_DISCONNECT_TIMEOUT + 1 sec*/ #define SLSI_DEFAULT_AP_DISCONNECT_IND_TIMEOUT 3000 @@ -241,15 +292,6 @@ struct slsi_ba_session_rx { #define SLSI_AMPDU_F_CREATED (0x0002) #define SLSI_AMPDU_F_OPERATIONAL (0x0004) -#ifdef CONFIG_SCSC_WLAN_RX_NAPI -struct slsi_napi { - struct napi_struct napi; - struct sk_buff_head rx_data; - struct slsi_spinlock lock; - bool interrupt_enabled; -}; -#endif - #define SLSI_SCAN_HW_ID 0 #define SLSI_SCAN_SCHED_ID 1 #define SLSI_SCAN_MAX 3 @@ -592,10 +634,6 @@ struct slsi_tcp_ack_s { ktime_t last_sample_time; u32 last_ack_seq; u64 num_bytes; - - /* corresponding socket to get stats (e.g. congestion window) */ - struct sock *tcp_sk; - #ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING u8 stream_id; u8 rx_window_scale; @@ -641,11 +679,10 @@ struct netdev_vif { struct mutex vif_mutex; #endif struct slsi_sig_send sig_wait; +#ifndef CONFIG_SCSC_WLAN_RX_NAPI struct slsi_skb_work rx_data; - struct slsi_skb_work rx_mlme; -#ifdef CONFIG_SCSC_WLAN_RX_NAPI - struct slsi_napi napi; #endif + struct slsi_skb_work rx_mlme; u16 ifnum; enum nl80211_iftype iftype; enum nl80211_channel_type channel_type; @@ -835,10 +872,10 @@ enum slsi_p2p_states { */ }; -enum slsi_hs2_state { - HS2_NO_VIF = 0, /* Initial state - Unsync vif is not present */ - HS2_VIF_ACTIVE, /* Unsync vif is activated but no HS procedure in progress */ - HS2_VIF_TX /* Unsync vif is activated and HS procedure in progress */ +enum slsi_wlan_state { + WLAN_UNSYNC_NO_VIF = 0, /* Initial state - Unsync vif is not present */ + WLAN_UNSYNC_VIF_ACTIVE, /* Unsync vif is activated but no wlan procedure in progress */ + WLAN_UNSYNC_VIF_TX /* Unsync vif is activated and wlan procedure in progress */ }; /* Wakelock timeouts */ @@ -875,6 +912,8 @@ static inline char *slsi_p2p_state_text(u8 state) } } +#define SLSI_WLAN_MAX_HCF_PLATFORM_LEN (128) + struct slsi_dev_mib_info { char *mib_file_name; unsigned int mib_hash; @@ -882,6 +921,7 @@ struct slsi_dev_mib_info { /* Cached File MIB Configuration values from User Space */ u8 *mib_data; u32 mib_len; + char platform[SLSI_WLAN_MAX_HCF_PLATFORM_LEN]; }; #define SLSI_WLAN_MAX_MIB_FILE 2 /* Number of WLAN HCFs to load */ @@ -922,9 +962,12 @@ struct slsi_dev { #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG struct slsi_mutex netdev_add_remove_mutex; + struct slsi_mutex netdev_remove_mutex; #else /* a std mutex */ struct mutex netdev_add_remove_mutex; + /* a std mutex */ + struct mutex netdev_remove_mutex; #endif int netdev_up_count; struct net_device __rcu *netdev[CONFIG_SCSC_WLAN_MAX_INTERFACES + 1]; /* 0 is reserved */ @@ -964,7 +1007,7 @@ struct slsi_dev { struct slsi_wake_lock wlan_wl; struct slsi_wake_lock wlan_wl_mlme; struct slsi_wake_lock wlan_wl_ma; -#ifndef SLSI_TEST_DEV +#if !defined SLSI_TEST_DEV && defined CONFIG_ANDROID struct wake_lock wlan_wl_roam; #endif struct slsi_sig_send sig_wait; @@ -986,7 +1029,7 @@ struct slsi_dev { struct workqueue_struct *device_wq; /* Driver Workqueue */ enum slsi_p2p_states p2p_state; /* Store current P2P operation */ - enum slsi_hs2_state hs2_state; /* Store current HS2 operations */ + enum slsi_wlan_state wlan_unsync_vif_state; /* Store current sate of unsync wlan vif */ int current_tspec_id; int tspec_error_code; @@ -1003,9 +1046,9 @@ struct slsi_dev { struct list_head hotlist_results; bool epno_active; #endif -#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_OUI - u8 scan_oui[6]; - bool scan_oui_active; +#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION + u8 scan_mac_addr[6]; + bool scan_addr_set; #endif #ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING int minor_prof; @@ -1058,6 +1101,8 @@ struct slsi_dev { #endif #endif struct slsi_traffic_mon_clients traffic_mon_clients; + /*Store vif index corresponding to rtt id for FTM*/ + u16 rtt_vif[8]; }; /* Compact representation of channels a ESS has been seen on @@ -1092,7 +1137,7 @@ struct llc_snap_hdr { #ifdef CONFIG_SCSC_WLAN_RX_NAPI int slsi_rx_data_napi(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb, bool from_ba); #endif -int slsi_rx_data(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb, bool from_ba); +void slsi_rx_data_deliver_skb(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); void slsi_rx_dbg_sap_work(struct work_struct *work); void slsi_rx_netdev_data_work(struct work_struct *work); void slsi_rx_netdev_mlme_work(struct work_struct *work); @@ -1120,6 +1165,7 @@ int slsi_dev_get_scan_result_count(void); bool slsi_dev_llslogs_supported(void); int slsi_dev_nan_supported(struct slsi_dev *sdev); void slsi_regd_init(struct slsi_dev *sdev); +bool slsi_dev_rtt_supported(void); static inline u16 slsi_tx_host_tag(struct slsi_dev *sdev, enum slsi_traffic_q tq) { diff --git a/drivers/net/wireless/scsc/fapi.h b/drivers/net/wireless/scsc/fapi.h index a83507b57ccc..b726062af1f6 100644 --- a/drivers/net/wireless/scsc/fapi.h +++ b/drivers/net/wireless/scsc/fapi.h @@ -602,8 +602,8 @@ static inline struct slsi_skb_cb *slsi_skb_cb_init(struct sk_buff *skb) #define FAPI_RTTSTATUS_FAIL_INVALID_REQUEST 0x000d #define FAPI_RTTSTATUS_FAIL_FTM_PARAMETER_OVERRIDE 0x000f -#define FAPI_RTTTYPE_ONE_SIDED 0x0000 -#define FAPI_RTTTYPE_TWO_SIDED 0x0001 +#define FAPI_RTTTYPE_ONE_SIDED 0x0001 +#define FAPI_RTTTYPE_TWO_SIDED 0x0002 #define FAPI_RXSTARTFLAGS_NONE 0x0000 #define FAPI_RXSTARTFLAGS_SCAN_CHANNEL 0x0001 diff --git a/drivers/net/wireless/scsc/hip4.c b/drivers/net/wireless/scsc/hip4.c index e59ac59e812c..de762b2e5f49 100755 --- a/drivers/net/wireless/scsc/hip4.c +++ b/drivers/net/wireless/scsc/hip4.c @@ -13,16 +13,29 @@ #include #include #include +#ifdef CONFIG_SCSC_WLAN_RX_NAPI +#include +#include +#endif #include "hip4.h" #include "mbulk.h" #include "dev.h" #include "hip4_sampler.h" +#ifdef CONFIG_ANDROID #include "scsc_wifilogger_rings.h" +#endif #include "debug.h" +#ifdef CONFIG_SCSC_LOGRING +static bool hip4_dynamic_logging = true; +module_param(hip4_dynamic_logging, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(hip4_dynamic_logging, "Dynamic logging, logring is disabled if tput > hip4_qos_med_tput_in_mbps. (default: Y)"); +#endif + +#ifdef CONFIG_SCSC_QOS static bool hip4_qos_enable = true; module_param(hip4_qos_enable, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(hip4_qos_enable, "enable HIP4 PM QoS. (default: Y)"); @@ -34,6 +47,7 @@ MODULE_PARM_DESC(hip4_qos_max_tput_in_mbps, "throughput (in Mbps) to apply Max P static int hip4_qos_med_tput_in_mbps = 150; module_param(hip4_qos_med_tput_in_mbps, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(hip4_qos_med_tput_in_mbps, "throughput (in Mbps) to apply Median PM QoS"); +#endif #ifdef CONFIG_SCSC_SMAPPER static bool hip4_smapper_enable = true; @@ -42,9 +56,32 @@ MODULE_PARM_DESC(hip4_smapper_enable, "enable HIP4 SMAPPER. (default: Y)"); static bool hip4_smapper_is_enabled; #endif +#ifdef CONFIG_SCSC_WLAN_RX_NAPI +/* run NAPI poll on a specific CPU (preferably a big CPU if online) */ +static int napi_select_cpu = 4; /* CPU number */ +module_param(napi_select_cpu, int, 0644); +MODULE_PARM_DESC(napi_select_cpu, "select a specific CPU to execute NAPI poll"); +#endif + +static int max_buffered_frames = 10000; +module_param(max_buffered_frames, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(max_buffered_frames, "Maximum number of frames to buffer in the driver"); + +#ifdef CONFIG_SCSC_WLAN_RX_NAPI +static ktime_t intr_received_fb; +static ktime_t bh_init_fb; +static ktime_t bh_end_fb; +static ktime_t intr_received_ctrl; +static ktime_t bh_init_ctrl; +static ktime_t bh_end_ctrl; +static ktime_t intr_received_data; +static ktime_t bh_init_data; +static ktime_t bh_end_data; +#else static ktime_t intr_received; static ktime_t bh_init; static ktime_t bh_end; +#endif static ktime_t wdt; static ktime_t send; static ktime_t closing; @@ -347,8 +384,8 @@ static int hip4_proc_show(struct seq_file *m, void *v) seq_printf(m, "ktime start %lld (ns)\n", ktime_to_ns(hip->hip_priv->stats.start)); seq_printf(m, "ktime now %lld (ns)\n\n", ktime_to_ns(ktime_get())); - seq_printf(m, "rx_intr_tohost 0x%x\n", hip->hip_priv->rx_intr_tohost); - seq_printf(m, "rx_intr_fromhost 0x%x\n\n", hip->hip_priv->rx_intr_fromhost); + seq_printf(m, "rx_intr_tohost 0x%x\n", hip->hip_priv->intr_tohost); + seq_printf(m, "rx_intr_fromhost 0x%x\n\n", hip->hip_priv->intr_fromhost); /* HIP statistics */ seq_printf(m, "HIP IRQs: %u\n", atomic_read(&hip->hip_priv->stats.irqs)); @@ -363,7 +400,6 @@ static int hip4_proc_show(struct seq_file *m, void *v) seq_printf(m, "Q%dR\t0x%x\t%d\n", i, hip4_read_index(hip, i, ridx), hip->hip_priv->stats.q_num_frames[i]); } seq_puts(m, "\n"); - return 0; } @@ -498,8 +534,14 @@ static void hip4_dump_dbg(struct slsi_hip4 *hip, struct mbulk *m, struct sk_buff unsigned int i = 0; scsc_mifram_ref ref; - SLSI_ERR_NODEV("rx_intr_tohost 0x%x\n", hip->hip_priv->rx_intr_tohost); - SLSI_ERR_NODEV("rx_intr_fromhost 0x%x\n", hip->hip_priv->rx_intr_fromhost); +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + SLSI_ERR_NODEV("intr_tohost_fb 0x%x\n", hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_RFB]); + SLSI_ERR_NODEV("intr_tohost_ctrl 0x%x\n", hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_CTRL]); + SLSI_ERR_NODEV("intr_tohost_dat 0x%x\n", hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]); +#else + SLSI_ERR_NODEV("intr_tohost 0x%x\n", hip->hip_priv->intr_tohost); +#endif + SLSI_ERR_NODEV("intr_fromhost 0x%x\n", hip->hip_priv->intr_fromhost); /* Print scoreboard */ for (i = 0; i < 6; i++) { @@ -514,16 +556,28 @@ static void hip4_dump_dbg(struct slsi_hip4 *hip, struct mbulk *m, struct sk_buff if (scsc_mx_service_mif_ptr_to_addr(service, m, &ref)) return; SLSI_ERR_NODEV("m: %p 0x%x\n", m, ref); - print_hex_dump(KERN_ERR, "mbulk ", DUMP_PREFIX_NONE, 16, 1, m, sizeof(struct mbulk), 0); + print_hex_dump(KERN_ERR, SCSC_PREFIX "mbulk ", DUMP_PREFIX_NONE, 16, 1, m, sizeof(struct mbulk), 0); } if (skb) - print_hex_dump(KERN_ERR, "skb ", DUMP_PREFIX_NONE, 16, 1, skb->data, skb->len > 0xff ? 0xff : skb->len, 0); + print_hex_dump(KERN_ERR, SCSC_PREFIX "skb ", DUMP_PREFIX_NONE, 16, 1, skb->data, skb->len > 0xff ? 0xff : skb->len, 0); SLSI_ERR_NODEV("time: wdt %lld\n", ktime_to_ns(wdt)); SLSI_ERR_NODEV("time: send %lld\n", ktime_to_ns(send)); +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + SLSI_ERR_NODEV("time: intr_fb %lld\n", ktime_to_ns(intr_received_fb)); + SLSI_ERR_NODEV("time: bh_init_fb %lld\n", ktime_to_ns(bh_init_fb)); + SLSI_ERR_NODEV("time: bh_end_fb %lld\n", ktime_to_ns(bh_end_fb)); + SLSI_ERR_NODEV("time: intr_ctrl %lld\n", ktime_to_ns(intr_received_ctrl)); + SLSI_ERR_NODEV("time: bh_init_ctrl %lld\n", ktime_to_ns(bh_init_ctrl)); + SLSI_ERR_NODEV("time: bh_end_ctrl %lld\n", ktime_to_ns(bh_end_ctrl)); + SLSI_ERR_NODEV("time: intr_data %lld\n", ktime_to_ns(intr_received_data)); + SLSI_ERR_NODEV("time: bh_init_data %lld\n", ktime_to_ns(bh_init_data)); + SLSI_ERR_NODEV("time: bh_end_data %lld\n", ktime_to_ns(bh_end_data)); +#else SLSI_ERR_NODEV("time: intr %lld\n", ktime_to_ns(intr_received)); SLSI_ERR_NODEV("time: bh_init %lld\n", ktime_to_ns(bh_init)); SLSI_ERR_NODEV("time: bh_end %lld\n", ktime_to_ns(bh_end)); +#endif SLSI_ERR_NODEV("time: closing %lld\n", ktime_to_ns(closing)); #ifdef CONFIG_SCSC_WLAN_DEBUG /* Discard noise if it is a mbulk/skb issue */ @@ -740,7 +794,7 @@ cont: p = mbulk_get_signal(m); if (!p) { SLSI_ERR_NODEV("No signal in Mbulk\n"); - print_hex_dump(KERN_ERR, "mbulk ", DUMP_PREFIX_NONE, 16, 1, m, sizeof(struct mbulk), 0); + print_hex_dump(KERN_ERR, SCSC_PREFIX "mbulk ", DUMP_PREFIX_NONE, 16, 1, m, sizeof(struct mbulk), 0); slsi_kfree_skb(skb); return NULL; } @@ -795,14 +849,23 @@ static int hip4_q_add_signal(struct slsi_hip4 *hip, enum hip4_hip_q_conf conf, s hip4_update_index(hip, conf, widx, idx_w); send = ktime_get(); - scsc_service_mifintrbit_bit_set(service, hip_priv->rx_intr_fromhost, SCSC_MIFINTR_TARGET_R4); + scsc_service_mifintrbit_bit_set(service, hip_priv->intr_fromhost, SCSC_MIFINTR_TARGET_R4); return 0; } +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +static void hip4_watchdog(struct timer_list *t) +#else static void hip4_watchdog(unsigned long data) +#endif { +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + struct hip4_priv *priv = from_timer(priv, t, watchdog); + struct slsi_hip4 *hip = priv->hip; +#else struct slsi_hip4 *hip = (struct slsi_hip4 *)data; +#endif struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); struct scsc_service *service; ktime_t intr_ov; @@ -817,14 +880,25 @@ static void hip4_watchdog(unsigned long data) wdt = ktime_get(); +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + /* if intr_received > wdt skip as intr has been unblocked */ + if (test_and_clear_bit(HIP4_MIF_Q_FH_RFB, hip->hip_priv->irq_bitmap)) + intr_ov = ktime_add_ms(intr_received_fb, jiffies_to_msecs(HZ)); + if (test_and_clear_bit(HIP4_MIF_Q_TH_CTRL, hip->hip_priv->irq_bitmap)) + intr_ov = ktime_add_ms(intr_received_ctrl, jiffies_to_msecs(HZ)); + if (test_and_clear_bit(HIP4_MIF_Q_TH_DAT, hip->hip_priv->irq_bitmap)) + intr_ov = ktime_add_ms(intr_received_data, jiffies_to_msecs(HZ)); +#else /* if intr_received > wdt skip as intr has been unblocked */ if (ktime_compare(intr_received, wdt) > 0) { wdt = ktime_set(0, 0); goto exit; } - /* Check that wdt is > 1 HZ intr */ intr_ov = ktime_add_ms(intr_received, jiffies_to_msecs(HZ)); +#endif + + /* Check that wdt is > 1 HZ intr */ if (!(ktime_compare(intr_ov, wdt) < 0)) { wdt = ktime_set(0, 0); /* Retrigger WDT to check flags again in the future */ @@ -841,38 +915,496 @@ static void hip4_watchdog(unsigned long data) SLSI_INFO_NODEV("Hip4 watchdog triggered\n"); - if (scsc_service_mifintrbit_bit_mask_status_get(service) & (1 << hip->hip_priv->rx_intr_tohost)) { +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + for (u8 i = 0; i < MIF_HIP_CFG_Q_NUM; i++) { + if (scsc_service_mifintrbit_bit_mask_status_get(service) & (1 << hip->hip_priv->intr_tohost_mul[i])) { + /* Interrupt might be pending! */ + SLSI_INFO_NODEV("%d: Interrupt Masked. Unmask to restart Interrupt processing\n", i); + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[i]); + } + } +#else + if (scsc_service_mifintrbit_bit_mask_status_get(service) & (1 << hip->hip_priv->intr_tohost)) { /* Interrupt might be pending! */ SLSI_INFO_NODEV("Interrupt Masked. Unmask to restart Interrupt processing\n"); - scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->rx_intr_tohost); + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost); } +#endif exit: spin_unlock_irqrestore(&hip->hip_priv->watchdog_lock, flags); } -/* Tasklet: high priority, low latency atomic tasks - * cannot sleep (run atomically in soft IRQ context and are guaranteed to - * never run on more than one CPU of a given processor, for a given tasklet) - */ +#ifdef CONFIG_SCSC_WLAN_RX_NAPI +static void hip4_irq_handler_stub(int irq, void *data) +{ + /* should not happen */ + WARN_ON(1); +} + +static void hip4_wq_fb(struct work_struct *data) +{ + struct hip4_priv *hip_priv = container_of(data, struct hip4_priv, intr_wq_fb); + struct slsi_hip4 *hip = hip_priv->hip; + struct hip4_hip_control *ctrl = hip->hip_control; + struct scsc_service *service; + struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); + bool no_change = true; + u8 idx_r; + u8 idx_w; + scsc_mifram_ref ref; + void *mem; + + if (!hip || !sdev || !sdev->service || !hip->hip_priv) + return; + + spin_lock_bh(&hip_priv->rx_lock); + service = sdev->service; + SCSC_HIP4_SAMPLER_INT_BH(hip->hip_priv->minor, 2); + bh_init_fb = ktime_get(); + clear_bit(HIP4_MIF_Q_FH_RFB, hip->hip_priv->irq_bitmap); + + idx_r = hip4_read_index(hip, HIP4_MIF_Q_FH_RFB, ridx); + idx_w = hip4_read_index(hip, HIP4_MIF_Q_FH_RFB, widx); + +#ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING + if (idx_r != idx_w) { + SCSC_HIP4_SAMPLER_Q(hip_priv->minor, HIP4_MIF_Q_FH_RFB, ridx, idx_r, 1); + SCSC_HIP4_SAMPLER_Q(hip_priv->minor, HIP4_MIF_Q_FH_RFB, widx, idx_w, 1); + } +#endif + while (idx_r != idx_w) { + struct mbulk *m; + u16 colour; + + no_change = false; + ref = ctrl->q[HIP4_MIF_Q_FH_RFB].array[idx_r]; +#ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING + SCSC_HIP4_SAMPLER_QREF(hip_priv->minor, ref, HIP4_MIF_Q_FH_RFB); +#endif + mem = scsc_mx_service_mif_addr_to_ptr(service, ref); + m = (struct mbulk *)mem; + + if (!m) { + SLSI_ERR_NODEV("FB: Mbulk is NULL\n"); + goto consume_fb_mbulk; + } + /* colour is defined as: */ + /* u16 register bits: + * 0 - do not use + * [2:1] - vif + * [7:3] - peer_index + * [10:8] - ac queue + */ + colour = ((m->clas & 0xc0) << 2) | (m->pid & 0xfe); + /* Account ONLY for data RFB */ + if ((m->pid & 0x1) == MBULK_CLASS_FROM_HOST_DAT) { +#ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING + SCSC_HIP4_SAMPLER_VIF_PEER(hip->hip_priv->minor, 0, (colour & 0x6) >> 1, (colour & 0xf8) >> 3); + /* to profile round-trip */ + { + u16 host_tag; + u8 *get_host_tag; + /* This is a nasty way of getting the host_tag without involving mbulk processing + * This hostag value should also be include in the cb descriptor which goes to + * mbulk descriptor (no room left at the moment) + */ + get_host_tag = (u8 *)m; + host_tag = get_host_tag[37] << 8 | get_host_tag[36]; + SCSC_HIP4_SAMPLER_PKT_TX_FB(hip->hip_priv->minor, host_tag); + } +#endif + /* Ignore return value */ + slsi_hip_tx_done(sdev, colour); + } + mbulk_free_virt_host(m); +consume_fb_mbulk: + /* Increase index */ + idx_r++; + idx_r &= (MAX_NUM - 1); + hip4_update_index(hip, HIP4_MIF_Q_FH_RFB, ridx, idx_r); + } + + if (no_change) + atomic_inc(&hip->hip_priv->stats.spurious_irqs); + + scsc_service_mifintrbit_bit_unmask(sdev->service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_RFB]); + SCSC_HIP4_SAMPLER_INT_OUT_BH(hip->hip_priv->minor, 2); + bh_end_fb = ktime_get(); + spin_unlock_bh(&hip_priv->rx_lock); +} + +static void hip4_irq_handler_fb(int irq, void *data) +{ + struct slsi_hip4 *hip = (struct slsi_hip4 *)data; + struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); + + SCSC_HIP4_SAMPLER_INT(hip->hip_priv->minor, 2); + intr_received_fb = ktime_get(); + + if (!atomic_read(&hip->hip_priv->watchdog_timer_active)) { + atomic_set(&hip->hip_priv->watchdog_timer_active, 1); + mod_timer(&hip->hip_priv->watchdog, jiffies + HZ); + } + set_bit(HIP4_MIF_Q_FH_RFB, hip->hip_priv->irq_bitmap); + + scsc_service_mifintrbit_bit_mask(sdev->service, irq); + schedule_work(&hip->hip_priv->intr_wq_fb); + /* Clear interrupt */ + scsc_service_mifintrbit_bit_clear(sdev->service, irq); + SCSC_HIP4_SAMPLER_INT_OUT(hip->hip_priv->minor, 2); +} + +static void hip4_wq_ctrl(struct work_struct *data) +{ + struct hip4_priv *hip_priv = container_of(data, struct hip4_priv, intr_wq_ctrl); + struct slsi_hip4 *hip = hip_priv->hip; + struct hip4_hip_control *ctrl = hip->hip_control; + struct scsc_service *service; + struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); + u8 retry; + bool no_change = true; + u8 idx_r; + u8 idx_w; + scsc_mifram_ref ref; + void *mem; + struct mbulk *m; +#if defined(CONFIG_SCSC_WLAN_DEBUG) || defined(CONFIG_SCSC_WLAN_HIP4_PROFILING) + int id; +#endif + + if (!hip || !sdev || !sdev->service || !hip->hip_priv) + return; + + spin_lock_bh(&hip_priv->rx_lock); + service = sdev->service; + SCSC_HIP4_SAMPLER_INT_BH(hip->hip_priv->minor, 1); + bh_init_ctrl = ktime_get(); + clear_bit(HIP4_MIF_Q_TH_CTRL, hip->hip_priv->irq_bitmap); + + idx_r = hip4_read_index(hip, HIP4_MIF_Q_TH_CTRL, ridx); + idx_w = hip4_read_index(hip, HIP4_MIF_Q_TH_CTRL, widx); + +#ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING + if (idx_r != idx_w) { + SCSC_HIP4_SAMPLER_Q(hip_priv->minor, HIP4_MIF_Q_TH_CTRL, ridx, idx_r, 1); + SCSC_HIP4_SAMPLER_Q(hip_priv->minor, HIP4_MIF_Q_TH_CTRL, widx, idx_w, 1); + } +#endif + while (idx_r != idx_w) { + struct sk_buff *skb; + /* TODO: currently the max number to be freed is 2. In future + * implementations (i.e. AMPDU) this number may be bigger + * list of mbulks to be freedi + */ + scsc_mifram_ref to_free[MBULK_MAX_CHAIN + 1] = { 0 }; + u8 i = 0; + + no_change = false; + /* Catch-up with idx_w */ + ref = ctrl->q[HIP4_MIF_Q_TH_CTRL].array[idx_r]; +#ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING + SCSC_HIP4_SAMPLER_QREF(hip_priv->minor, ref, HIP4_MIF_Q_TH_CTRL); +#endif + mem = scsc_mx_service_mif_addr_to_ptr(service, ref); + m = (struct mbulk *)(mem); + /* Process Control Signal */ + + skb = hip4_mbulk_to_skb(service, m, to_free, false); + if (!skb) { + SLSI_ERR_NODEV("Ctrl: Error parsing skb\n"); + hip4_dump_dbg(hip, m, skb, service); + goto consume_ctl_mbulk; + } + +#if defined(CONFIG_SCSC_WLAN_DEBUG) || defined(CONFIG_SCSC_WLAN_HIP4_PROFILING) + id = fapi_get_sigid(skb); +#endif +#ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING + /* log control signal, not unidata not debug */ + if (fapi_is_mlme(skb)) + SCSC_HIP4_SAMPLER_SIGNAL_CTRLRX(hip_priv->minor, (id & 0xff00) >> 8, id & 0xff); +#endif +#ifdef CONFIG_SCSC_WLAN_DEBUG + hip4_history_record_add(TH, id); +#endif + if (slsi_hip_rx(sdev, skb) < 0) { + SLSI_ERR_NODEV("Ctrl: Error detected slsi_hip_rx\n"); + hip4_dump_dbg(hip, m, skb, service); + slsi_kfree_skb(skb); + } +consume_ctl_mbulk: + /* Increase index */ + idx_r++; + idx_r &= (MAX_NUM - 1); + + /* Go through the list of references to free */ + while ((ref = to_free[i++])) { + /* Set the number of retries */ + retry = FB_NO_SPC_NUM_RET; + /* return to the firmware */ + while (hip4_q_add_signal(hip, HIP4_MIF_Q_TH_RFB, ref, service) && retry > 0) { + SLSI_WARN_NODEV("Ctrl: Not enough space in FB, retry: %d/%d\n", retry, FB_NO_SPC_NUM_RET); + spin_unlock_bh(&hip_priv->rx_lock); + msleep(FB_NO_SPC_SLEEP_MS); + spin_lock_bh(&hip_priv->rx_lock); + retry--; + if (retry == 0) + SLSI_ERR_NODEV("Ctrl: FB has not been freed for %d ms\n", FB_NO_SPC_NUM_RET * FB_NO_SPC_SLEEP_MS); + SCSC_HIP4_SAMPLER_QFULL(hip_priv->minor, HIP4_MIF_Q_TH_RFB); + } + } + hip4_update_index(hip, HIP4_MIF_Q_TH_CTRL, ridx, idx_r); + } + + if (no_change) + atomic_inc(&hip->hip_priv->stats.spurious_irqs); + + scsc_service_mifintrbit_bit_unmask(sdev->service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_CTRL]); + SCSC_HIP4_SAMPLER_INT_OUT_BH(hip->hip_priv->minor, 1); + bh_end_ctrl = ktime_get(); + spin_unlock_bh(&hip_priv->rx_lock); +} + +static void hip4_irq_handler_ctrl(int irq, void *data) +{ + struct slsi_hip4 *hip = (struct slsi_hip4 *)data; + struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); + + SCSC_HIP4_SAMPLER_INT(hip->hip_priv->minor, 1); + intr_received_ctrl = ktime_get(); + + if (!atomic_read(&hip->hip_priv->watchdog_timer_active)) { + atomic_set(&hip->hip_priv->watchdog_timer_active, 1); + mod_timer(&hip->hip_priv->watchdog, jiffies + HZ); + } + set_bit(HIP4_MIF_Q_TH_CTRL, hip->hip_priv->irq_bitmap); + + scsc_service_mifintrbit_bit_mask(sdev->service, irq); + + schedule_work(&hip->hip_priv->intr_wq_ctrl); + /* Clear interrupt */ + scsc_service_mifintrbit_bit_clear(sdev->service, irq); + SCSC_HIP4_SAMPLER_INT_OUT(hip->hip_priv->minor, 1); +} + +static int hip4_napi_poll(struct napi_struct *napi, int budget) +{ + struct hip4_priv *hip_priv = container_of(napi, struct hip4_priv, napi); + struct slsi_hip4 *hip = hip_priv->hip; + struct hip4_hip_control *ctrl = hip->hip_control; + struct scsc_service *service; + struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); + +#ifdef CONFIG_SCSC_WLAN_DEBUG + int id; +#endif + u8 idx_r; + u8 idx_w; + scsc_mifram_ref ref; + void *mem; + struct mbulk *m; + u8 retry; + int work_done = 0; + + if (!hip || !sdev || !sdev->service || !hip->hip_priv) + return 0; + + spin_lock_bh(&hip_priv->rx_lock); + SCSC_HIP4_SAMPLER_INT_BH(hip->hip_priv->minor, 0); + if (ktime_compare(bh_init_data, bh_end_data) < 0) + bh_init_data = ktime_get(); + clear_bit(HIP4_MIF_Q_TH_DAT, hip->hip_priv->irq_bitmap); + + idx_r = hip4_read_index(hip, HIP4_MIF_Q_TH_DAT, ridx); + idx_w = hip4_read_index(hip, HIP4_MIF_Q_TH_DAT, widx); + + service = sdev->service; + + SLSI_DBG4(sdev, SLSI_RX, "todo:%d\n", (idx_w - idx_r) & 0xff); + if (idx_r == idx_w) { + SLSI_DBG4(sdev, SLSI_RX, "nothing to do, NAPI Complete\n"); + bh_end_data = ktime_get(); + napi_complete(napi); + /* Nothing more to drain, unmask interrupt */ + scsc_service_mifintrbit_bit_unmask(sdev->service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]); + goto end; + } + +#ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING + if (idx_r != idx_w) { + SCSC_HIP4_SAMPLER_Q(hip_priv->minor, HIP4_MIF_Q_TH_DAT, ridx, idx_r, 1); + SCSC_HIP4_SAMPLER_Q(hip_priv->minor, HIP4_MIF_Q_TH_DAT, widx, idx_w, 1); + } +#endif + + while (idx_r != idx_w) { + struct sk_buff *skb; + /* TODO: currently the max number to be freed is 2. In future + * implementations (i.e. AMPDU) this number may be bigger + */ + /* list of mbulks to be freed */ + scsc_mifram_ref to_free[MBULK_MAX_CHAIN + 1] = { 0 }; + u8 i = 0; + + /* Catch-up with idx_w */ + ref = ctrl->q[HIP4_MIF_Q_TH_DAT].array[idx_r]; +#ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING + SCSC_HIP4_SAMPLER_QREF(hip_priv->minor, ref, HIP4_MIF_Q_TH_DAT); +#endif + mem = scsc_mx_service_mif_addr_to_ptr(service, ref); + m = (struct mbulk *)(mem); + skb = hip4_mbulk_to_skb(service, m, to_free, false); + if (!skb) { + SLSI_ERR_NODEV("Dat: Error parsing skb\n"); + hip4_dump_dbg(hip, m, skb, service); + goto consume_dat_mbulk; + } +#ifdef CONFIG_SCSC_WLAN_DEBUG + id = fapi_get_sigid(skb); + hip4_history_record_add(TH, id); +#endif + if (slsi_hip_rx(sdev, skb) < 0) { + SLSI_ERR_NODEV("Dat: Error detected slsi_hip_rx\n"); + hip4_dump_dbg(hip, m, skb, service); + slsi_kfree_skb(skb); + } +consume_dat_mbulk: + /* Increase index */ + idx_r++; + idx_r &= (MAX_NUM - 1); + + while ((ref = to_free[i++])) { + /* Set the number of retries */ + retry = 100; + while (hip4_q_add_signal(hip, HIP4_MIF_Q_TH_RFB, ref, service) && retry > 0) { + SLSI_WARN_NODEV("Dat: Not enough space in FB, retry: %d/%d\n", retry, FB_NO_SPC_NUM_RET); + udelay(FB_NO_SPC_SLEEP_MS); + retry--; + + if (retry == 0) + SLSI_ERR_NODEV("Dat: FB has not been freed for %d us\n", FB_NO_SPC_NUM_RET * FB_NO_SPC_SLEEP_MS); +#ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING + SCSC_HIP4_SAMPLER_QFULL(hip_priv->minor, HIP4_MIF_Q_TH_RFB); +#endif + } + } + + work_done++; + if (budget == work_done) { + /* We have consumed all the bugdet */ + break; + } + } + + hip4_update_index(hip, HIP4_MIF_Q_TH_DAT, ridx, idx_r); + + if (work_done < budget) { + SLSI_DBG4(sdev, SLSI_RX, "NAPI Complete\n"); + bh_end_data = ktime_get(); + napi_complete(napi); + /* Nothing more to drain, unmask interrupt */ + scsc_service_mifintrbit_bit_unmask(sdev->service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]); + } +end: + SLSI_DBG4(sdev, SLSI_RX, "work done:%d\n", work_done); + SCSC_HIP4_SAMPLER_INT_OUT_BH(hip->hip_priv->minor, 0); + spin_unlock_bh(&hip_priv->rx_lock); + return work_done; +} + +static void hip4_napi_schedule(void *data) +{ + struct slsi_hip4 *hip = (struct slsi_hip4 *)data; + + napi_schedule(&hip->hip_priv->napi); +} + +static void hip4_irq_data_tasklet(unsigned long data) +{ + /* TODO: NAPI - formalize the CPU selection code */ + struct slsi_hip4 *hip = (struct slsi_hip4 *)data; + int err = -EINVAL; + + if (cpu_online(napi_select_cpu)) + err = smp_call_function_single(napi_select_cpu, hip4_napi_schedule, hip, 0); + + if (err) + napi_schedule(&hip->hip_priv->napi); +} + +static void hip4_irq_handler_dat(int irq, void *data) +{ + struct slsi_hip4 *hip = (struct slsi_hip4 *)data; + struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); + + if (!hip || !sdev || !sdev->service || !hip->hip_priv) + return; + + SCSC_HIP4_SAMPLER_INT(hip->hip_priv->minor, 0); + intr_received_data = ktime_get(); + + if (!atomic_read(&hip->hip_priv->watchdog_timer_active)) { + atomic_set(&hip->hip_priv->watchdog_timer_active, 1); + mod_timer(&hip->hip_priv->watchdog, jiffies + HZ); + } + set_bit(HIP4_MIF_Q_TH_DAT, hip->hip_priv->irq_bitmap); + + if (napi_select_cpu) + tasklet_schedule(&hip->hip_priv->intr_tasklet); + else + napi_schedule(&hip->hip_priv->napi); + + /* Mask interrupt to avoid interrupt storm and let BH run */ + scsc_service_mifintrbit_bit_mask(sdev->service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]); + /* Clear interrupt */ + scsc_service_mifintrbit_bit_clear(sdev->service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]); + SCSC_HIP4_SAMPLER_INT_OUT(hip->hip_priv->minor, 0); +} + +#else /* #ifdef CONFIG_SCSC_WLAN_RX_NAPI */ + +static bool slsi_check_rx_flowcontrol(struct slsi_dev *sdev) +{ + struct netdev_vif *ndev_vif; + int qlen = 0; + + ndev_vif = netdev_priv(sdev->netdev[SLSI_NET_INDEX_WLAN]); + if (ndev_vif) + qlen = skb_queue_len(&ndev_vif->rx_data.queue); + + SLSI_MUTEX_LOCK(sdev->netdev_remove_mutex); +#if defined(SLSI_NET_INDEX_P2PX_SWLAN) + if (sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]) { + ndev_vif = netdev_priv(sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]); + if (ndev_vif) + qlen += skb_queue_len(&ndev_vif->rx_data.queue); + } +#elif defined(SLSI_NET_INDEX_P2PX) + if (sdev->netdev[SLSI_NET_INDEX_P2PX]) { + ndev_vif = netdev_priv(sdev->netdev[SLSI_NET_INDEX_P2PX]); + if (ndev_vif) + qlen += skb_queue_len(&ndev_vif->rx_data.queue); + } +#endif + SLSI_MUTEX_UNLOCK(sdev->netdev_remove_mutex); + + if (qlen > max_buffered_frames) { + SLSI_DBG1_NODEV(SLSI_HIP, "max qlen reached: %d\n", qlen); + return true; + } + SLSI_DBG3_NODEV(SLSI_HIP, "qlen %d\n", qlen); + + return false; +} /* Worqueue: Lower priority, run in process context. Can run simultaneously on * different CPUs */ -#ifdef TASKLET -static void hip4_tasklet(unsigned long data) -#else static void hip4_wq(struct work_struct *data) -#endif { -#ifdef TASKLET - struct slsi_hip4 *hip = (struct slsi_hip4 *)data; - struct hip4_priv *hip_priv = hip->hip_priv; - struct hip4_hip_control *ctrl = hip->hip_control; -#else struct hip4_priv *hip_priv = container_of(data, struct hip4_priv, intr_wq); struct slsi_hip4 *hip = hip_priv->hip; struct hip4_hip_control *ctrl = hip->hip_control; -#endif scsc_mifram_ref ref; void *mem; struct mbulk *m; @@ -883,6 +1415,7 @@ static void hip4_wq(struct work_struct *data) bool no_change = true; u8 retry; u32 packets_total; + bool rx_flowcontrol = false; #if defined(CONFIG_SCSC_WLAN_HIP4_PROFILING) || defined(CONFIG_SCSC_WLAN_DEBUG) int id; @@ -893,11 +1426,12 @@ static void hip4_wq(struct work_struct *data) return; } + if (slsi_check_rx_flowcontrol(sdev)) + rx_flowcontrol = true; + service = sdev->service; -#ifndef TASKLET spin_lock_bh(&hip_priv->rx_lock); -#endif atomic_set(&hip->hip_priv->in_rx, 1); bh_init = ktime_get(); @@ -921,6 +1455,7 @@ static void hip4_wq(struct work_struct *data) histogram_5++; else histogram_6++; + if (jitter > max_jitter) max_jitter = jitter; } @@ -1081,6 +1616,9 @@ consume_ctl_mbulk: SCSC_HIP4_SAMPLER_INT_OUT_BH(hip_priv->minor, 1); + if (rx_flowcontrol) + goto skip_data_q; + atomic_set(&hip->hip_priv->in_rx, 3); idx_r = hip4_read_index(hip, HIP4_MIF_Q_TH_DAT, ridx); @@ -1205,23 +1743,23 @@ consume_dat_mbulk: if (no_change) atomic_inc(&hip->hip_priv->stats.spurious_irqs); +skip_data_q: if (!atomic_read(&hip->hip_priv->closing)) { /* Reset status variable. DO THIS BEFORE UNMASKING!!!*/ atomic_set(&hip->hip_priv->watchdog_timer_active, 0); - scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->rx_intr_tohost); + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost); } +#ifdef CONFIG_ANDROID if (wake_lock_active(&hip->hip_priv->hip4_wake_lock)) { wake_unlock(&hip->hip_priv->hip4_wake_lock); SCSC_WLOG_WAKELOCK(WLOG_LAZY, WL_RELEASED, "hip4_wake_lock", WL_REASON_RX); } +#endif bh_end = ktime_get(); atomic_set(&hip->hip_priv->in_rx, 0); - -#ifndef TASKLET spin_unlock_bh(&hip_priv->rx_lock); -#endif } /* IRQ handler for hip4. The function runs in Interrupt context, so all the @@ -1245,10 +1783,12 @@ static void hip4_irq_handler(int irq, void *data) intr_received = ktime_get(); +#ifdef CONFIG_ANDROID if (!wake_lock_active(&hip->hip_priv->hip4_wake_lock)) { wake_lock(&hip->hip_priv->hip4_wake_lock); SCSC_WLOG_WAKELOCK(WLOG_LAZY, WL_TAKEN, "hip4_wake_lock", WL_REASON_RX); } +#endif /* if wd timer is active system might be in trouble as it should be * cleared in the BH. Ignore updating the timer @@ -1260,14 +1800,12 @@ static void hip4_irq_handler(int irq, void *data) SLSI_ERR_NODEV("INT triggered while WDT is active\n"); SLSI_ERR_NODEV("bh_init %lld\n", ktime_to_ns(bh_init)); SLSI_ERR_NODEV("bh_end %lld\n", ktime_to_ns(bh_end)); -#ifndef TASKLET SLSI_ERR_NODEV("hip4_wq work_busy %d\n", work_busy(&hip->hip_priv->intr_wq)); -#endif SLSI_ERR_NODEV("hip4_priv->in_rx %d\n", atomic_read(&hip->hip_priv->in_rx)); } /* If system is not in suspend, mask interrupt to avoid interrupt storm and let BH run */ if (!atomic_read(&hip->hip_priv->in_suspend)) { - scsc_service_mifintrbit_bit_mask(sdev->service, hip->hip_priv->rx_intr_tohost); + scsc_service_mifintrbit_bit_mask(sdev->service, hip->hip_priv->intr_tohost); hip->hip_priv->storm_count = 0; } else if (++hip->hip_priv->storm_count >= MAX_STORM) { /* A MAX_STORM number of interrupts has been received @@ -1276,23 +1814,21 @@ static void hip4_irq_handler(int irq, void *data) * interrupt storm. */ hip->hip_priv->storm_count = 0; - scsc_service_mifintrbit_bit_mask(sdev->service, hip->hip_priv->rx_intr_tohost); + scsc_service_mifintrbit_bit_mask(sdev->service, hip->hip_priv->intr_tohost); } atomic_inc(&hip->hip_priv->stats.irqs); -#ifdef TASKLET - tasklet_schedule(&hip->hip_priv->intr_tq); -#else schedule_work(&hip->hip_priv->intr_wq); -#endif end: /* Clear interrupt */ - scsc_service_mifintrbit_bit_clear(sdev->service, hip->hip_priv->rx_intr_tohost); + scsc_service_mifintrbit_bit_clear(sdev->service, hip->hip_priv->intr_tohost); SCSC_HIP4_SAMPLER_INT_OUT(hip->hip_priv->minor, 0); SCSC_HIP4_SAMPLER_INT_OUT(hip->hip_priv->minor, 1); SCSC_HIP4_SAMPLER_INT_OUT(hip->hip_priv->minor, 2); } +#endif /* #ifdef CONFIG_SCSC_WLAN_RX_NAPI */ +#ifdef CONFIG_SCSC_QOS static void hip4_pm_qos_work(struct work_struct *data) { struct hip4_priv *hip_priv = container_of(data, struct hip4_priv, pm_qos_work); @@ -1322,16 +1858,29 @@ static void hip4_traffic_monitor_cb(void *client_ctx, u32 state, u32 tput_tx, u3 spin_lock_bh(&hip->hip_priv->pm_qos_lock); SLSI_DBG1(sdev, SLSI_HIP, "event (state:%u, tput_tx:%u bps, tput_rx:%u bps)\n", state, tput_tx, tput_rx); - if (state == TRAFFIC_MON_CLIENT_STATE_HIGH) + if (state == TRAFFIC_MON_CLIENT_STATE_HIGH) { hip->hip_priv->pm_qos_state = SCSC_QOS_MAX; - else if (state == TRAFFIC_MON_CLIENT_STATE_MID) +#ifdef CONFIG_SCSC_LOGRING + if (hip4_dynamic_logging) + scsc_logring_enable(false); +#endif + } else if (state == TRAFFIC_MON_CLIENT_STATE_MID) { hip->hip_priv->pm_qos_state = SCSC_QOS_MED; - else +#ifdef CONFIG_SCSC_LOGRING + if (hip4_dynamic_logging) + scsc_logring_enable(false); +#endif + } else { hip->hip_priv->pm_qos_state = SCSC_QOS_DISABLED; +#ifdef CONFIG_SCSC_LOGRING + scsc_logring_enable(true); +#endif + } spin_unlock_bh(&hip->hip_priv->pm_qos_lock); schedule_work(&hip->hip_priv->pm_qos_work); } +#endif int hip4_init(struct slsi_hip4 *hip) { @@ -1364,7 +1913,7 @@ int hip4_init(struct slsi_hip4 *hip) memset(&hip->hip_priv->stats, 0, sizeof(hip->hip_priv->stats)); hip->hip_priv->stats.start = ktime_get(); hip->hip_priv->stats.procfs_dir = proc_mkdir("driver/hip4", NULL); - if (NULL != hip->hip_priv->stats.procfs_dir) { + if (!hip->hip_priv->stats.procfs_dir) { proc_create_data("info", S_IRUSR | S_IRGRP, hip->hip_priv->stats.procfs_dir, &hip4_procfs_stats_fops, hip); proc_create_data("history", S_IRUSR | S_IRGRP, @@ -1435,15 +1984,40 @@ int hip4_init(struct slsi_hip4 *hip) /* Set driver is not ready to receive interrupts */ atomic_set(&hip->hip_priv->rx_ready, 0); +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + /* TOHOST Handler allocator */ + /* Q0 FH CTRL */ + hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_CTRL] = + scsc_service_mifintrbit_register_tohost(service, hip4_irq_handler_stub, hip); + /* Mask the interrupt to prevent intr been kicked during start */ + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_CTRL]); + /* Q1 FH DAT - Use the same stub interrupt handler */ + hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_DAT] = hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_CTRL]; + /* Q2 FH FB */ + hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_RFB] = + scsc_service_mifintrbit_register_tohost(service, hip4_irq_handler_fb, hip); + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_RFB]); + /* Q3 TH CTRL */ + hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_CTRL] = + scsc_service_mifintrbit_register_tohost(service, hip4_irq_handler_ctrl, hip); + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_CTRL]); + /* Q4 TH DAT */ + hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT] = + scsc_service_mifintrbit_register_tohost(service, hip4_irq_handler_dat, hip); + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]); + /* Q5 TH RFB - Use the same stub interrupt handler */ + hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_RFB] = hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_CTRL]; +#else /* TOHOST Handler allocator */ - hip->hip_priv->rx_intr_tohost = + hip->hip_priv->intr_tohost = scsc_service_mifintrbit_register_tohost(service, hip4_irq_handler, hip); /* Mask the interrupt to prevent intr been kicked during start */ - scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->rx_intr_tohost); + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost); +#endif /* FROMHOST Handler allocator */ - hip->hip_priv->rx_intr_fromhost = + hip->hip_priv->intr_fromhost = scsc_service_mifintrbit_alloc_fromhost(service, SCSC_MIFINTR_TARGET_R4); /* Get hip_control pointer on shared memory */ @@ -1503,9 +2077,16 @@ int hip4_init(struct slsi_hip4 *hip) hip_control->config_v4.fw_buf_loc = hip->hip_ref + HIP4_WLAN_RX_OFFSET; hip_control->config_v4.fw_buf_sz = HIP4_WLAN_RX_SIZE; hip_control->config_v4.log_config_loc = 0; - hip_control->config_v4.mif_fh_int_n = hip->hip_priv->rx_intr_fromhost; - for (i = 0; i < MIF_HIP_CFG_Q_NUM; i++) - hip_control->config_v4.mif_th_int_n[i] = hip->hip_priv->rx_intr_tohost; + + hip_control->config_v4.mif_fh_int_n = hip->hip_priv->intr_fromhost; + for (i = 0; i < MIF_HIP_CFG_Q_NUM; i++) { +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + hip_control->config_v4.mif_th_int_n[i] = hip->hip_priv->intr_tohost_mul[i]; +#else + hip_control->config_v4.mif_th_int_n[i] = hip->hip_priv->intr_tohost; +#endif + } + hip_control->config_v4.scbrd_loc = (u32)ref_scoreboard; hip_control->config_v4.q_num = 6; hip_control->config_v4.q_len = 256; @@ -1529,8 +2110,8 @@ int hip4_init(struct slsi_hip4 *hip) hip_control->config_v3.fw_buf_loc = hip->hip_ref + HIP4_WLAN_RX_OFFSET; hip_control->config_v3.fw_buf_sz = HIP4_WLAN_RX_SIZE; hip_control->config_v3.log_config_loc = 0; - hip_control->config_v3.mif_fh_int_n = hip->hip_priv->rx_intr_fromhost; - hip_control->config_v3.mif_th_int_n = hip->hip_priv->rx_intr_tohost; + hip_control->config_v3.mif_fh_int_n = hip->hip_priv->intr_fromhost; + hip_control->config_v3.mif_th_int_n = hip->hip_priv->intr_tohost; hip_control->config_v3.q_num = 6; hip_control->config_v3.q_len = 256; hip_control->config_v3.q_idx_sz = 1; @@ -1557,41 +2138,53 @@ int hip4_init(struct slsi_hip4 *hip) hip->hip_control = hip_control; hip->hip_priv->scbrd_base = &hip_control->scoreboard; -#ifndef TASKLET + spin_lock_init(&hip->hip_priv->rx_lock); -#endif atomic_set(&hip->hip_priv->in_rx, 0); spin_lock_init(&hip->hip_priv->tx_lock); atomic_set(&hip->hip_priv->in_tx, 0); -#ifdef TASKLET - /* Init tasklet */ - tasklet_init(&hip->hip_priv->intr_tq, hip4_tasklet, (unsigned long)hip); + + /* Init work structs */ +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + tasklet_init(&hip->hip_priv->intr_tasklet, hip4_irq_data_tasklet, (unsigned long)hip); + INIT_WORK(&hip->hip_priv->intr_wq_ctrl, hip4_wq_ctrl); + INIT_WORK(&hip->hip_priv->intr_wq_fb, hip4_wq_fb); #else - /* Init wq */ INIT_WORK(&hip->hip_priv->intr_wq, hip4_wq); #endif + rwlock_init(&hip->hip_priv->rw_scoreboard); /* Setup watchdog timer */ atomic_set(&hip->hip_priv->watchdog_timer_active, 0); spin_lock_init(&hip->hip_priv->watchdog_lock); +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + timer_setup(&hip->hip_priv->watchdog, hip4_watchdog, 0); +#else setup_timer(&hip->hip_priv->watchdog, hip4_watchdog, (unsigned long)hip); +#endif atomic_set(&hip->hip_priv->gmod, HIP4_DAT_SLOTS); atomic_set(&hip->hip_priv->gactive, 1); spin_lock_init(&hip->hip_priv->gbot_lock); hip->hip_priv->saturated = 0; +#ifdef CONFIG_ANDROID wake_lock_init(&hip->hip_priv->hip4_wake_lock, WAKE_LOCK_SUSPEND, "hip4_wake_lock"); +#endif #ifdef CONFIG_SCSC_SMAPPER /* Init SMAPPER */ if (hip4_smapper_enable) { - hip4_smapper_init(sdev, hip); - hip4_smapper_is_enabled = true; + if (hip4_smapper_init(sdev, hip)) { + SLSI_ERR_NODEV("Error on hip4_smapper init\n"); + hip4_smapper_is_enabled = false; + } else { + hip4_smapper_is_enabled = true; + } } #endif - +#ifdef CONFIG_SCSC_QOS /* setup for PM QoS */ spin_lock_init(&hip->hip_priv->pm_qos_lock); @@ -1606,6 +2199,7 @@ int hip4_init(struct slsi_hip4 *hip) SLSI_WARN(sdev, "failed to add PM QoS request\n"); } } +#endif return 0; } @@ -1644,10 +2238,12 @@ int scsc_wifi_transmit_frame(struct slsi_hip4 *hip, bool ctrl_packet, struct sk_ spin_lock_bh(&hip->hip_priv->tx_lock); atomic_set(&hip->hip_priv->in_tx, 1); +#ifdef CONFIG_ANDROID if (!wake_lock_active(&hip->hip_priv->hip4_wake_lock)) { wake_lock(&hip->hip_priv->hip4_wake_lock); SCSC_WLOG_WAKELOCK(WLOG_LAZY, WL_TAKEN, "hip4_wake_lock", WL_REASON_TX); } +#endif service = sdev->service; @@ -1714,10 +2310,12 @@ int scsc_wifi_transmit_frame(struct slsi_hip4 *hip, bool ctrl_packet, struct sk_ return 0; error: +#ifdef CONFIG_ANDROID if (wake_lock_active(&hip->hip_priv->hip4_wake_lock)) { wake_unlock(&hip->hip_priv->hip4_wake_lock); SCSC_WLOG_WAKELOCK(WLOG_LAZY, WL_RELEASED, "hip4_wake_lock", WL_REASON_TX); } +#endif atomic_set(&hip->hip_priv->in_tx, 0); spin_unlock_bh(&hip->hip_priv->tx_lock); return ret; @@ -1731,6 +2329,9 @@ int hip4_setup(struct slsi_hip4 *hip) struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); struct scsc_service *service; u32 conf_hip4_ver = 0; +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + struct net_device *dev; +#endif if (!sdev || !sdev->service) return -EIO; @@ -1749,13 +2350,26 @@ int hip4_setup(struct slsi_hip4 *hip) return -EIO; } - /* If version 4 is used */ if (conf_hip4_ver == 4) { hip->hip_priv->unidat_req_headroom = scsc_wifi_get_hip_config_u8(&hip->hip_control, unidat_req_headroom, 4); hip->hip_priv->unidat_req_tailroom = scsc_wifi_get_hip_config_u8(&hip->hip_control, unidat_req_tailroom, 4); hip->hip_priv->version = 4; + +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + rcu_read_lock(); + /* one NAPI instance is ok for multiple netdev devices */ + dev = slsi_get_netdev_rcu(sdev, SLSI_NET_INDEX_WLAN); + if (!dev) { + SLSI_ERR(sdev, "netdev No longer exists\n"); + rcu_read_unlock(); + return -EINVAL; + } + netif_napi_add(dev, &hip->hip_priv->napi, hip4_napi_poll, NAPI_POLL_WEIGHT); + napi_enable(&hip->hip_priv->napi); + rcu_read_unlock(); +#endif } else { /* version 3 */ hip->hip_priv->unidat_req_headroom = @@ -1773,17 +2387,27 @@ int hip4_setup(struct slsi_hip4 *hip) /* Driver is ready to process IRQ */ atomic_set(&hip->hip_priv->rx_ready, 1); - scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->rx_intr_tohost); +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_RFB]); + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_CTRL]); + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]); +#else + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost); +#endif return 0; } /* On suspend hip4 needs to ensure that TH interrupts *are* unmasked */ void hip4_suspend(struct slsi_hip4 *hip) { - struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); + struct slsi_dev *sdev; struct scsc_service *service; + if (!hip || !hip->hip_priv) + return; + + sdev = container_of(hip, struct slsi_dev, hip4_inst); if (!sdev || !sdev->service) return; @@ -1796,14 +2420,24 @@ void hip4_suspend(struct slsi_hip4 *hip) SCSC_HIP4_SAMPLER_SUSPEND(hip->hip_priv->minor); atomic_set(&hip->hip_priv->in_suspend, 1); - scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->rx_intr_tohost); + +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + for (u8 i = 0; i < MIF_HIP_CFG_Q_NUM; i++) + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[i]); +#else + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost); +#endif } /* TH interrupts can be masked/unmasked */ void hip4_resume(struct slsi_hip4 *hip) { - struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); + struct slsi_dev *sdev; + + if (!hip || !hip->hip_priv) + return; + sdev = container_of(hip, struct slsi_dev, hip4_inst); if (!sdev) return; @@ -1814,9 +2448,13 @@ void hip4_resume(struct slsi_hip4 *hip) void hip4_freeze(struct slsi_hip4 *hip) { - struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); + struct slsi_dev *sdev; struct scsc_service *service; + if (!hip || !hip->hip_priv) + return; + + sdev = container_of(hip, struct slsi_dev, hip4_inst); if (!sdev || !sdev->service) return; @@ -1829,16 +2467,20 @@ void hip4_freeze(struct slsi_hip4 *hip) atomic_set(&hip->hip_priv->closing, 1); hip4_dump_dbg(hip, NULL, NULL, service); +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + for (u8 i = 0; i < MIF_HIP_CFG_Q_NUM; i++) + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost_mul[i]); - scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->rx_intr_tohost); - -#ifdef TASKLET - tasklet_kill(&hip->hip_priv->intr_tq); + tasklet_kill(&hip->hip_priv->intr_tasklet); + cancel_work_sync(&hip->hip_priv->intr_wq_ctrl); + cancel_work_sync(&hip->hip_priv->intr_wq_fb); #else + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost); cancel_work_sync(&hip->hip_priv->intr_wq); #endif atomic_set(&hip->hip_priv->rx_ready, 0); atomic_set(&hip->hip_priv->watchdog_timer_active, 0); + /* Deactive the wd timer prior its expiration */ del_timer_sync(&hip->hip_priv->watchdog); } @@ -1853,9 +2495,15 @@ void hip4_deinit(struct slsi_hip4 *hip) service = sdev->service; +#ifdef CONFIG_SCSC_QOS +#ifdef CONFIG_SCSC_LOGRING + /* Reenable logring in case was disabled */ + scsc_logring_enable(true); +#endif /* de-register with traffic monitor */ slsi_traffic_mon_client_unregister(sdev, hip); scsc_service_pm_qos_remove_request(service); +#endif #ifdef CONFIG_SCSC_SMAPPER /* Init SMAPPER */ @@ -1864,20 +2512,31 @@ void hip4_deinit(struct slsi_hip4 *hip) hip4_smapper_deinit(sdev, hip); } #endif +#ifdef CONFIG_ANDROID wake_lock_destroy(&hip->hip_priv->hip4_wake_lock); +#endif closing = ktime_get(); atomic_set(&hip->hip_priv->closing, 1); - scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->rx_intr_tohost); +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + for (u8 i = 0; i < MIF_HIP_CFG_Q_NUM; i++) + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost_mul[i]); -#ifdef TASKLET - tasklet_kill(&hip->hip_priv->intr_tq); + netif_napi_del(&hip->hip_priv->napi); + tasklet_kill(&hip->hip_priv->intr_tasklet); + cancel_work_sync(&hip->hip_priv->intr_wq_ctrl); + cancel_work_sync(&hip->hip_priv->intr_wq_fb); + + for (i = 0; i < MIF_HIP_CFG_Q_NUM; i++) + scsc_service_mifintrbit_unregister_tohost(service, hip->hip_priv->intr_tohost_mul[i]); #else + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost); cancel_work_sync(&hip->hip_priv->intr_wq); + scsc_service_mifintrbit_unregister_tohost(service, hip->hip_priv->intr_tohost); #endif - scsc_service_mifintrbit_unregister_tohost(service, hip->hip_priv->rx_intr_tohost); - scsc_service_mifintrbit_free_fromhost(service, hip->hip_priv->rx_intr_fromhost, SCSC_MIFINTR_TARGET_R4); + + scsc_service_mifintrbit_free_fromhost(service, hip->hip_priv->intr_fromhost, SCSC_MIFINTR_TARGET_R4); /* If we get to that point with rx_lock/tx_lock claimed, trigger BUG() */ WARN_ON(atomic_read(&hip->hip_priv->in_tx)); diff --git a/drivers/net/wireless/scsc/hip4.h b/drivers/net/wireless/scsc/hip4.h index 346452966693..85b59ddea054 100755 --- a/drivers/net/wireless/scsc/hip4.h +++ b/drivers/net/wireless/scsc/hip4.h @@ -21,9 +21,14 @@ #include #include #include +#ifdef CONFIG_SCSC_WLAN_RX_NAPI +#include +#endif #ifndef SLSI_TEST_DEV +#ifdef CONFIG_ANDROID #include #endif +#endif #include "mbulk.h" #ifdef CONFIG_SCSC_SMAPPER #include "hip4_smapper.h" @@ -126,10 +131,10 @@ struct hip4_hip_config_version_4 { u32 log_config_loc; /* Logging Configuration Location in MIF_ADDR */ u32 log_config_sz; /* Logging Configuration Size in MIF_ADDR */ - u8 mif_fh_int_n; /* MIF from-host interrupt bit position for all HIP queue */ + u8 mif_fh_int_n; /* MIF from-host interrupt bit position for all HIP queue */ u8 reserved1[3]; - u8 mif_th_int_n[6]; /* MIF to-host interrupt bit positions for each HIP queue */ + u8 mif_th_int_n[6]; /* MIF to-host interrupt bit positions for each HIP queue */ u8 reserved2[2]; u32 scbrd_loc; /* Scoreboard locatin in MIF_ADDR */ @@ -149,7 +154,6 @@ struct hip4_hip_config_version_4 { u8 smapper_pow_sz[16]; /* Power of size of entry i.e. 12 = 4096B */ u32 smapper_bank_addr[16]; /* Bank start addr */ #endif - u8 reserved4[16]; } __packed; @@ -230,19 +234,25 @@ struct hip4_hip_control { struct slsi_hip4; -/* #define TASKLET 1 */ /* This struct is private to the HIP implementation */ struct hip4_priv { -#ifdef TASKLET - struct tasklet_struct intr_tq; +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + struct tasklet_struct intr_tasklet; + struct work_struct intr_wq_ctrl; + struct work_struct intr_wq_fb; + struct napi_struct napi; #else struct work_struct intr_wq; #endif - /* Interrupts cache */ + + /* Interrupts cache < v4 */ /* TOHOST */ - u32 rx_intr_tohost; + u32 intr_tohost; + + /* Interrupts cache v4 */ + u32 intr_tohost_mul[MIF_HIP_CFG_Q_NUM]; /* FROMHOST */ - u32 rx_intr_fromhost; + u32 intr_fromhost; /* For workqueue */ struct slsi_hip4 *hip; @@ -252,10 +262,8 @@ struct hip4_priv { /* Pool for ctl frames*/ u8 host_pool_id_ctl; -#ifndef TASKLET /* rx cycle lock */ spinlock_t rx_lock; -#endif /* tx cycle lock */ spinlock_t tx_lock; @@ -268,8 +276,11 @@ struct hip4_priv { spinlock_t watchdog_lock; /* wd timer control */ atomic_t watchdog_timer_active; +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + DECLARE_BITMAP(irq_bitmap, MIF_HIP_CFG_Q_NUM); +#endif -#ifndef SLSI_TEST_DEV +#if !defined SLSI_TEST_DEV && defined CONFIG_ANDROID /* Wakelock for modem_ctl */ struct wake_lock hip4_wake_lock; #endif @@ -320,13 +331,13 @@ struct hip4_priv { struct hip4_smapper_bank smapper_banks[HIP4_SMAPPER_TOTAL_BANKS]; struct hip4_smapper_control smapper_control; #endif - +#ifdef CONFIG_SCSC_QOS /* PM QoS control */ struct work_struct pm_qos_work; /* PM QoS control spinlock */ spinlock_t pm_qos_lock; u8 pm_qos_state; - +#endif /* Collection artificats */ void *mib_collect; u16 mib_sz; @@ -357,9 +368,9 @@ int scsc_wifi_transmit_frame(struct slsi_hip4 *hip, bool ctrl_packet, struct sk_ #define scsc_wifi_get_hip_config_version_4_u8(buff_ptr, member) le16_to_cpu((((struct hip4_hip_config_version_4 *)(buff_ptr))->member)) #define scsc_wifi_get_hip_config_version_4_u16(buff_ptr, member) le16_to_cpu((((struct hip4_hip_config_version_4 *)(buff_ptr))->member)) #define scsc_wifi_get_hip_config_version_4_u32(buff_ptr, member) le32_to_cpu((((struct hip4_hip_config_version_4 *)(buff_ptr))->member)) -#define scsc_wifi_get_hip_config_version_3_u8(buff_ptr, member) le16_to_cpu((((struct hip4_hip_config_version_4 *)(buff_ptr))->member)) -#define scsc_wifi_get_hip_config_version_3_u16(buff_ptr, member) le16_to_cpu((((struct hip4_hip_config_version_4 *)(buff_ptr))->member)) -#define scsc_wifi_get_hip_config_version_3_u32(buff_ptr, member) le32_to_cpu((((struct hip4_hip_config_version_4 *)(buff_ptr))->member)) +#define scsc_wifi_get_hip_config_version_3_u8(buff_ptr, member) le16_to_cpu((((struct hip4_hip_config_version_3 *)(buff_ptr))->member)) +#define scsc_wifi_get_hip_config_version_3_u16(buff_ptr, member) le16_to_cpu((((struct hip4_hip_config_version_3 *)(buff_ptr))->member)) +#define scsc_wifi_get_hip_config_version_3_u32(buff_ptr, member) le32_to_cpu((((struct hip4_hip_config_version_3 *)(buff_ptr))->member)) #define scsc_wifi_get_hip_config_u8(buff_ptr, member, ver) le16_to_cpu((((struct hip4_hip_config_version_##ver *)(buff_ptr->config_v##ver))->member)) #define scsc_wifi_get_hip_config_u16(buff_ptr, member, ver) le16_to_cpu((((struct hip4_hip_config_version_##ver *)(buff_ptr->config_v##ver))->member)) #define scsc_wifi_get_hip_config_u32(buff_ptr, member, ver) le32_to_cpu((((struct hip4_hip_config_version_##ver *)(buff_ptr->config_v##ver))->member)) diff --git a/drivers/net/wireless/scsc/hip4_sampler.c b/drivers/net/wireless/scsc/hip4_sampler.c index 23dcb63e6717..f24918183160 100755 --- a/drivers/net/wireless/scsc/hip4_sampler.c +++ b/drivers/net/wireless/scsc/hip4_sampler.c @@ -265,7 +265,7 @@ void hip4_sampler_update_record(u32 minor, u8 param1, u8 param2, u8 param3, u8 p struct hip4_sampler_dev *hip4_dev; unsigned long flags; - if (!hip4_sampler_enable) + if (!hip4_sampler_enable || !hip4_sampler.init) return; if (atomic_read(&in_read)) @@ -451,19 +451,17 @@ void hip4_sampler_tcp_decode(struct slsi_dev *sdev, struct net_device *dev, u8 * if ((tcp_ack->dport == tcp_hdr->source) && (tcp_ack->sport == tcp_hdr->dest)) { if (from_ba && tcp_hdr->syn && tcp_hdr->ack) { unsigned char *options; - u32 optlen, len = 0; + u32 optlen = 0, len = 0; - optlen = (tcp_hdr->doff - 5) * 4; - if (optlen > 60) { - SLSI_WARN(sdev, "Error optlen : %u\n", optlen); - optlen = 60; - } + if (tcp_hdr->doff > 5) + optlen = (tcp_hdr->doff - 5) * 4; options = (u8 *)tcp_hdr + TCP_ACK_SUPPRESSION_OPTIONS_OFFSET; while (optlen > 0) { switch (options[0]) { case TCP_ACK_SUPPRESSION_OPTION_EOL: + len = 1; break; case TCP_ACK_SUPPRESSION_OPTION_NOP: len = 1; @@ -476,8 +474,10 @@ void hip4_sampler_tcp_decode(struct slsi_dev *sdev, struct net_device *dev, u8 * len = options[1]; break; } - /* if length field in TCP options is 0, then options are bogus; return here */ - if (len == 0) + /* if length field in TCP options is 0, or greater than + * total options length, then options are incorrect + */ + if ((len == 0) || (len >= optlen)) break; if (optlen >= len) @@ -898,6 +898,7 @@ void hip4_sampler_create(struct slsi_dev *sdev, struct scsc_mx *mx) hip4_collect_client.prv = mx; scsc_log_collector_register_client(&hip4_collect_client); #endif + spin_lock_init(&g_spinlock); hip4_sampler.init = true; SLSI_INFO_NODEV("%s: Ready to start sampling....\n", DRV_NAME); diff --git a/drivers/net/wireless/scsc/hip4_smapper.c b/drivers/net/wireless/scsc/hip4_smapper.c index 14cf5521125c..c3c65a7fbe20 100644 --- a/drivers/net/wireless/scsc/hip4_smapper.c +++ b/drivers/net/wireless/scsc/hip4_smapper.c @@ -320,6 +320,11 @@ int hip4_smapper_init(struct slsi_dev *sdev, struct slsi_hip4 *hip) if (dma_set_mask_and_coherent(sdev->dev, DMA_BIT_MASK(64)) != 0) return -EIO; + if (!scsc_mx_service_alloc_mboxes(sdev->service, 1, &control->mbox_scb)) { + SLSI_DBG4_NODEV(SLSI_SMAPPER, "Unable to allocate mbox\n"); + return -ENODEV; + } + /* Claim the RX buffers */ hip4_smapper_alloc_bank(sdev, hip->hip_priv, RX_0, SMAPPER_GRANULARITY, HIP4_SMAPPER_BANK_LARGE); hip4_smapper_alloc_bank(sdev, hip->hip_priv, RX_1, SMAPPER_GRANULARITY, HIP4_SMAPPER_BANK_LARGE); @@ -331,13 +336,12 @@ int hip4_smapper_init(struct slsi_dev *sdev, struct slsi_hip4 *hip) hip4_smapper_allocate_skb_buffers(sdev, &hip->hip_priv->smapper_banks[RX_2]); hip4_smapper_allocate_skb_buffers(sdev, &hip->hip_priv->smapper_banks[RX_3]); - /* Allocate Maxwell resources - TODO: remove the emul */ + /* Allocate Maxwell resources */ control->th_req = scsc_service_mifintrbit_register_tohost(sdev->service, hip4_smapper_refill_isr, hip); control->fh_ind = scsc_service_mifintrbit_alloc_fromhost(sdev->service, SCSC_MIFINTR_TARGET_R4); - scsc_mx_service_alloc_mboxes(sdev->service, 1, &control->mbox_scb); control->mbox_ptr = scsc_mx_service_get_mbox_ptr(sdev->service, control->mbox_scb); @@ -379,9 +383,6 @@ void hip4_smapper_deinit(struct slsi_dev *sdev, struct slsi_hip4 *hip) control = &(hip->hip_priv->smapper_control); spin_lock_irqsave(&control->smapper_lock, flags); - scsc_service_mifintrbit_unregister_tohost(sdev->service, control->th_req); - scsc_service_mifintrbit_free_fromhost(sdev->service, control->fh_ind, SCSC_MIFINTR_TARGET_R4); - for (i = RX_0; i < END_RX_BANKS; i++) { bank = &hip->hip_priv->smapper_banks[i]; bank->in_use = false; @@ -391,4 +392,9 @@ void hip4_smapper_deinit(struct slsi_dev *sdev, struct slsi_hip4 *hip) scsc_service_mifsmapper_free_bank(sdev->service, bank->bank); } spin_unlock_irqrestore(&control->smapper_lock, flags); + + scsc_service_mifintrbit_unregister_tohost(sdev->service, control->th_req); + scsc_service_mifintrbit_free_fromhost(sdev->service, control->fh_ind, SCSC_MIFINTR_TARGET_R4); + scsc_service_free_mboxes(sdev->service, 1, control->mbox_scb); + } diff --git a/drivers/net/wireless/scsc/ioctl.c b/drivers/net/wireless/scsc/ioctl.c index 1fab43e49051..4da79ab1b247 100755 --- a/drivers/net/wireless/scsc/ioctl.c +++ b/drivers/net/wireless/scsc/ioctl.c @@ -1387,7 +1387,7 @@ static ssize_t slsi_auto_chan_write(struct net_device *dev, char *command, int b } - SLSI_DBG3(sdev, SLSI_INIT_DEINIT, "Number of channels for autchannel selection= %d", count_channels); + SLSI_DBG3(sdev, SLSI_INIT_DEINIT, "Number of channels for autochannel selection= %d", count_channels); SLSI_MUTEX_LOCK(sdev->device_config_mutex); sdev->device_config.ap_auto_chan = 0; @@ -1403,7 +1403,7 @@ if ((ndev_sta_vif->activated) && (ndev_sta_vif->vif_type == FAPI_VIFTYPE_STATION sdev->device_config.ap_auto_chan = ieee80211_frequency_to_channel(sta_frequency); else sdev->device_config.ap_auto_chan = 1; - SLSI_DBG1(sdev, SLSI_INIT_DEINIT, "Auto channel written = %d", sdev->device_config.ap_auto_chan); + SLSI_INFO(sdev, "Channel selected = %d", sdev->device_config.ap_auto_chan); SLSI_MUTEX_UNLOCK(sdev->device_config_mutex); return 0; } @@ -2066,7 +2066,7 @@ int slsi_fake_mac_write(struct net_device *dev, char *cmd) else enable = 0; - status = slsi_mib_encode_bool(&mib_data, SLSI_PSID_UNIFI_MAC_ADDRESS_RANDOMISATION, enable, 0); + status = slsi_mib_encode_bool(&mib_data, SLSI_PSID_UNIFI_MAC_ADDRESS_RANDOMISATION_ACTIVATED, enable, 0); if (status != SLSI_MIB_STATUS_SUCCESS) { SLSI_ERR(sdev, "FAKE MAC FAIL: no mem for MIB\n"); return -ENOMEM; @@ -2389,6 +2389,12 @@ int slsi_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) priv_cmd.total_len - skip); } else if (strncasecmp(command, CMD_GETROAMSCANCHANNELS, strlen(CMD_GETROAMSCANCHANNELS)) == 0) { ret = slsi_roam_scan_channels_read(dev, command, priv_cmd.total_len); + } else if (strncasecmp(command, CMD_SETROAMOFFLOAD, strlen(CMD_SETROAMOFFLOAD)) == 0) { + ret = slsi_roam_mode_write(dev, command + strlen(CMD_SETROAMOFFLOAD) + 1, + priv_cmd.total_len - (strlen(CMD_SETROAMOFFLOAD) + 1)); + } else if (strncasecmp(command, CMD_SETROAMOFFLAPLIST, strlen(CMD_SETROAMOFFLAPLIST)) == 0) { + ret = slsi_roam_offload_ap_list(dev, command + strlen(CMD_SETROAMOFFLAPLIST) + 1, + priv_cmd.total_len - (strlen(CMD_SETROAMOFFLAPLIST) + 1)); #endif } else if (strncasecmp(command, CMD_SET_PMK, strlen(CMD_SET_PMK)) == 0) { ret = slsi_set_pmk(dev, command, priv_cmd.total_len); @@ -2431,12 +2437,6 @@ int slsi_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } else if (strncasecmp(command, CMD_TDLSCHANNELSWITCH, strlen(CMD_TDLSCHANNELSWITCH)) == 0) { ret = slsi_tdls_channel_switch(dev, command + strlen(CMD_TDLSCHANNELSWITCH) + 1, priv_cmd.total_len - (strlen(CMD_TDLSCHANNELSWITCH) + 1)); - } else if (strncasecmp(command, CMD_SETROAMOFFLOAD, strlen(CMD_SETROAMOFFLOAD)) == 0) { - ret = slsi_roam_mode_write(dev, command + strlen(CMD_SETROAMOFFLOAD) + 1, - priv_cmd.total_len - (strlen(CMD_SETROAMOFFLOAD) + 1)); - } else if (strncasecmp(command, CMD_SETROAMOFFLAPLIST, strlen(CMD_SETROAMOFFLAPLIST)) == 0) { - ret = slsi_roam_offload_ap_list(dev, command + strlen(CMD_SETROAMOFFLAPLIST) + 1, - priv_cmd.total_len - (strlen(CMD_SETROAMOFFLAPLIST) + 1)); } else if (strncasecmp(command, CMD_SET_TX_POWER_CALLING, strlen(CMD_SET_TX_POWER_CALLING)) == 0) { ret = slsi_set_tx_power_calling(dev, command + strlen(CMD_SET_TX_POWER_CALLING) + 1, priv_cmd.total_len - (strlen(CMD_SET_TX_POWER_CALLING) + 1)); diff --git a/drivers/net/wireless/scsc/mgt.c b/drivers/net/wireless/scsc/mgt.c index e0d82a0361d1..b8319d1256ec 100755 --- a/drivers/net/wireless/scsc/mgt.c +++ b/drivers/net/wireless/scsc/mgt.c @@ -44,17 +44,22 @@ #define SLSI_MIB_MAX_CLIENT (10) #define SLSI_REG_PARAM_START_INDEX (1) -/* temp until it gets integrated into mib.h by Autogen */ -#define SLSI_PSID_UNIFI_REG_DOM_VERSION 8019 - static char *mib_file_t = "wlan_t.hcf"; module_param(mib_file_t, charp, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(mib_file_t, "mib data filename"); -static char *mib_file2_t = "wlan_sw_t.hcf"; +static char *mib_file2_t = "wlan_t_sw.hcf"; module_param(mib_file2_t, charp, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(mib_file2_t, "mib data filename"); +/* MAC address override. If set to FF's, then + * the address is taken from config files or + * default derived from HW ID. + */ +static char *mac_addr_override = "ff:ff:ff:ff:ff:ff"; +module_param_named(mac_addr, mac_addr_override, charp, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(mac_addr_override, "WLAN MAC address override"); + static int slsi_mib_open_file(struct slsi_dev *sdev, struct slsi_dev_mib_info *mib_info, const struct firmware **fw); static int slsi_mib_close_file(struct slsi_dev *sdev, const struct firmware *e); static int slsi_mib_download_file(struct slsi_dev *sdev, struct slsi_dev_mib_info *mib_info); @@ -69,6 +74,73 @@ static int slsi_5ghz_all_channels[] = {5180, 5200, 5220, 5240, 5260, 5280, 5300, 5745, 5765, 5785, 5805, 5825 }; #endif +/* MAC address override stored in /sys/wifi/mac_addr */ +static ssize_t sysfs_show_macaddr(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); +static ssize_t sysfs_store_macaddr(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count); + +static char sysfs_mac_override[] = "ff:ff:ff:ff:ff:ff"; +static struct kobject *macaddr_kobj_ref; +static struct kobj_attribute mac_attr = __ATTR(mac_addr, 0660, sysfs_show_macaddr, sysfs_store_macaddr); + +/* Retrieve mac address in sysfs global */ +static ssize_t sysfs_show_macaddr(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return snprintf(buf, sizeof(sysfs_mac_override), "%s", sysfs_mac_override); +} + +/* Update mac address in sysfs global */ +static ssize_t sysfs_store_macaddr(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + int r; + + SLSI_INFO_NODEV("Override WLAN MAC address %s\n", buf); + + /* size of macaddr string */ + r = sscanf(buf, "%18s", &sysfs_mac_override); + + return (r > 0) ? count : 0; +} + +/* Register sysfs mac address override */ +void slsi_create_sysfs_macaddr(void) +{ + int r; + + /* Create sysfs directory /sys/wifi */ + macaddr_kobj_ref = kobject_create_and_add("wifi", NULL); + + /* Create sysfs file /sys/wifi/mac_addr */ + r = sysfs_create_file(macaddr_kobj_ref, &mac_attr.attr); + if (r) { + /* Failed, so clean up dir */ + pr_err("Can't create /sys/wifi/mac_addr\n"); + + kobject_put(macaddr_kobj_ref); + macaddr_kobj_ref = NULL; + return; + } +} + +/* Unregister sysfs mac address override */ +void slsi_destroy_sysfs_macaddr(void) +{ + if (!macaddr_kobj_ref) + return; + + /* Destroy /sys/wifi/mac_addr file */ + sysfs_remove_file(kernel_kobj, &mac_attr.attr); + + /* Destroy /sys/wifi virtual dir */ + kobject_put(macaddr_kobj_ref); +} + void slsi_purge_scan_results_locked(struct netdev_vif *ndev_vif, u16 scan_id) { struct slsi_scan_result *scan_result; @@ -127,8 +199,49 @@ void slsi_get_hw_mac_address(struct slsi_dev *sdev, u8 *addr) u32 u[ETH_ALEN]; char path_name[MX_WLAN_FILE_PATH_LEN_MAX]; int r; + bool valid = false; + + /* Module parameter override */ + r = sscanf(mac_addr_override, "%02X:%02X:%02X:%02X:%02X:%02X", &u[0], &u[1], &u[2], &u[3], &u[4], &u[5]); + if (r != ETH_ALEN) { + SLSI_ERR(sdev, "mac_addr modparam set, but format is incorrect (should be e.g. xx:xx:xx:xx:xx:xx)\n"); + goto mac_sysfs; + } + for (i = 0; i < ETH_ALEN; i++) { + if (u[i] != 0xff) + valid = true; + addr[i] = u[i] & 0xff; + } + + /* If the override is valid, use it */ + if (valid) { + SLSI_INFO(sdev, "MAC address from modparam: %02X:%02X:%02X:%02X:%02X:%02X\n", + u[0], u[1], u[2], u[3], u[4], u[5]); + return; + } + + /* Sysfs parameter override */ +mac_sysfs: + r = sscanf(sysfs_mac_override, "%02X:%02X:%02X:%02X:%02X:%02X", &u[0], &u[1], &u[2], &u[3], &u[4], &u[5]); + if (r != ETH_ALEN) { + SLSI_ERR(sdev, "mac_addr in sysfs set, but format is incorrect (should be e.g. xx:xx:xx:xx:xx:xx)\n"); + goto mac_file; + } + for (i = 0; i < ETH_ALEN; i++) { + if (u[i] != 0xff) + valid = true; + addr[i] = u[i] & 0xff; + } + + /* If the override is valid, use it */ + if (valid) { + SLSI_INFO(sdev, "MAC address from sysfs: %02X:%02X:%02X:%02X:%02X:%02X\n", + u[0], u[1], u[2], u[3], u[4], u[5]); + return; + } - /* read maddr_file */ + /* read mac.txt */ +mac_file: if (sdev->maddr_file_name) { scnprintf(path_name, MX_WLAN_FILE_PATH_LEN_MAX, "wlan/%s", sdev->maddr_file_name); SLSI_DBG1(sdev, SLSI_INIT_DEINIT, "MAC address file : %s\n", path_name); @@ -153,6 +266,7 @@ void slsi_get_hw_mac_address(struct slsi_dev *sdev, u8 *addr) return; } mac_efs: +#ifdef CONFIG_SCSC_WLAN_MAC_ADDRESS_FILENAME r = mx140_request_file(sdev->maxwell_core, CONFIG_SCSC_WLAN_MAC_ADDRESS_FILENAME, &e); if (r != 0) goto mac_default; @@ -170,6 +284,7 @@ mac_efs: SLSI_INFO(sdev, "MAC address loaded from %s: %02X:%02X:%02X:%02X:%02X:%02X\n", CONFIG_SCSC_WLAN_MAC_ADDRESS_FILENAME, u[0], u[1], u[2], u[3], u[4], u[5]); mx140_release_file(sdev->maxwell_core, e); return; +#endif mac_default: /* This is safe to call, even if the struct firmware handle is NULL */ @@ -184,6 +299,7 @@ mac_default: #endif SLSI_DBG1(sdev, SLSI_INIT_DEINIT, "MAC addr file NOT found, using default MAC ADDR: %pM\n", addr); + #else /* We use FIXED Mac addresses with the unittest driver */ struct slsi_test_dev *uftestdev = (struct slsi_test_dev *)sdev->maxwell_core; @@ -196,7 +312,11 @@ mac_default: static void write_wifi_version_info_file(struct slsi_dev *sdev) { struct file *fp = NULL; +#if defined(ANDROID_VERSION) && (ANDROID_VERSION >= 90000) char *filepath = "/data/vendor/conn/.wifiver.info"; +#else + char *filepath = "/data/misc/conn/.wifiver.info"; +#endif char buf[256]; char build_id_fw[128]; char build_id_drv[64]; @@ -219,25 +339,47 @@ static void write_wifi_version_info_file(struct slsi_dev *sdev) * as it can have fatal consequences. * The framework parser for the version may depend on this * exact formatting. + * + * Also beware that ANDROID_VERSION will not be defined in AOSP. */ +#if defined(ANDROID_VERSION) && (ANDROID_VERSION >= 90000) + /* P-OS */ snprintf(buf, sizeof(buf), - "drv_ver: %s\n" + "%s\n" /* drv_ver: already appended by mxman_get_driver_version() */ "f/w_ver: %s\n" - "hcf_ver_hw: %u\n" - "hcf_ver_sw: %u\n" + "hcf_ver_hw: %s\n" + "hcf_ver_sw: %s\n" "regDom_ver: %d.%d\n", build_id_drv, build_id_fw, - sdev->mib[0].mib_hash, - sdev->mib[1].mib_hash, + sdev->mib[0].platform, + sdev->mib[1].platform, + ((sdev->reg_dom_version >> 8) & 0xFF), (sdev->reg_dom_version & 0xFF)); +#else + /* O-OS, or unknown */ + snprintf(buf, sizeof(buf), + "%s (f/w_ver: %s)\nregDom_ver: %d.%d\n", + build_id_drv, + build_id_fw, ((sdev->reg_dom_version >> 8) & 0xFF), (sdev->reg_dom_version & 0xFF)); +#endif +/* If ANDROID_VERSION is not known, avoid writing the file, as it could go to the wrong + * location. + */ +#ifdef ANDROID_VERSION +#ifdef CONFIG_SCSC_WLBTD + wlbtd_write_file(filepath, buf); +#else kernel_write(fp, buf, strlen(buf), 0); if (fp) filp_close(fp, NULL); - +#endif SLSI_INFO(sdev, "Succeed to write firmware/host information to .wifiver.info\n"); +#else + SLSI_UNUSED_PARAMETER(filepath); +#endif } #ifdef CONFIG_SCSC_WLAN_DEBUG @@ -416,7 +558,7 @@ int slsi_start(struct slsi_dev *sdev) /* Only the first file is mandatory */ if (i == 0 && err) { - SLSI_ERR(sdev, "slsi_mib_open_file failed: err=%d\n", err); + SLSI_ERR(sdev, "mib: Mandatory wlan hcf missing. WLAN will not start (err=%d)\n", err); slsi_sm_wlan_service_close(sdev); goto err_done; } @@ -500,6 +642,11 @@ int slsi_start(struct slsi_dev *sdev) } else { offset = snprintf(buf + offset, sizeof(buf), "#softap.info\n"); offset += snprintf(buf + offset, sizeof(buf), "DualBandConcurrency=%s\n", sdev->dualband_concurrency ? "yes" : "no"); +#ifdef CONFIG_SCSC_WLAN_WIFI_SHARING + offset += snprintf(buf + offset, sizeof(buf), "DualInterface=%s\n", "yes"); +#else + offset += snprintf(buf + offset, sizeof(buf), "DualInterface=%s\n", "no"); +#endif offset += snprintf(buf + offset, sizeof(buf), "5G=%s\n", sdev->band_5g_supported ? "yes" : "no"); offset += snprintf(buf + offset, sizeof(buf), "maxClient=%d\n", !sdev->softap_max_client ? SLSI_MIB_MAX_CLIENT : sdev->softap_max_client); @@ -524,6 +671,7 @@ int slsi_start(struct slsi_dev *sdev) slsi_update_supported_channels_regd_flags(sdev); SLSI_DBG2(sdev, SLSI_INIT_DEINIT, "---Driver started successfully---\n"); sdev->device_state = SLSI_DEVICE_STATE_STARTED; + memset(sdev->rtt_vif, -1, sizeof(sdev->rtt_vif)); SLSI_MUTEX_UNLOCK(sdev->start_stop_mutex); slsi_kic_system_event(slsi_kic_system_event_category_initialisation, @@ -683,7 +831,6 @@ void slsi_vif_cleanup(struct slsi_dev *sdev, struct net_device *dev, bool hw_ava if (hw_available) { struct slsi_peer *peer; int j = 0; - int r = 0; while (j < SLSI_PEER_INDEX_MAX) { peer = ndev_vif->peer_sta_record[j]; @@ -691,9 +838,6 @@ void slsi_vif_cleanup(struct slsi_dev *sdev, struct net_device *dev, bool hw_ava slsi_ps_port_control(sdev, dev, peer, SLSI_STA_CONN_STATE_DISCONNECTED); ++j; } - r = slsi_mlme_disconnect(sdev, dev, NULL, WLAN_REASON_DEAUTH_LEAVING, true); - if (r != 0) - SLSI_NET_ERR(dev, "Disconnection returned with CFM failure\n"); slsi_mlme_del_vif(sdev, dev); } SLSI_DBG2(sdev, SLSI_INIT_DEINIT, "Calling slsi_vif_deactivated\n"); @@ -703,7 +847,7 @@ void slsi_vif_cleanup(struct slsi_dev *sdev, struct net_device *dev, bool hw_ava SLSI_P2P_STATE_CHANGE(sdev, P2P_IDLE_NO_VIF); } else if (ndev_vif->vif_type == FAPI_VIFTYPE_UNSYNCHRONISED) { if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif)) { - slsi_hs2_vif_deactivate(sdev, dev, hw_available); + slsi_wlan_unsync_vif_deactivate(sdev, dev, hw_available); } else { SLSI_DBG2(sdev, SLSI_INIT_DEINIT, "P2P active - Deactivate\n"); slsi_p2p_vif_deactivate(sdev, dev, hw_available); @@ -861,6 +1005,133 @@ static u8 *slsi_mib_slice(struct slsi_dev *sdev, const u8 *data, u32 length, u32 return mib_slice; } +/* Extract the platform name string from the HCF file */ +static int slsi_mib_get_platform(struct slsi_dev_mib_info *mib_info) +{ + size_t plat_name_len; + int pos = 0; + + /* The mib_data passed to this function should already + * have had its HCF header skipped. + * + * This is shoehorned into specific PSIDs to allow backward + * compatibility, so we must look into the HCF payload + * instead of the header :( + * + * The updated configcmd util guarantees that these keys + * will appear first: + * + * PSIDs: + * 0xfffe - 16 bit version ID, value 1. + * 0xffff - If version ID=1, holds platform name string. + */ + + mib_info->platform[0] = '\0'; + + /* Sanity - payload long enough for info? */ + if (mib_info->mib_len < 12) { + SLSI_INFO_NODEV("HCF file too short\n"); + return -EINVAL; /* file too short */ + } + + if (mib_info->mib_data[pos++] != 0xFE || /* Version ID FFFE */ + mib_info->mib_data[pos++] != 0xFF) { + SLSI_INFO_NODEV("No HCF version ID\n"); + return -EINVAL; /* No version ID */ + } + if (mib_info->mib_data[pos++] != 0x01 || /* Len 1, LE */ + mib_info->mib_data[pos++] != 0x00) { + SLSI_INFO_NODEV("Bad length\n"); + return -EINVAL; /* Unknown length */ + } + if (mib_info->mib_data[pos++] != 0x01 || /* Header ID 1, LE */ + mib_info->mib_data[pos++] != 0x00) { + SLSI_INFO_NODEV("Bad version ID\n"); + return -EINVAL; /* Unknown version ID */ + } + if (mib_info->mib_data[pos++] != 0xFF || /* Platform Name FFFF */ + mib_info->mib_data[pos++] != 0xFF) { + SLSI_INFO_NODEV("No HCF platform name\n"); + return -EINVAL; /* No platform name */ + } + + /* Length of platform name */ + plat_name_len = mib_info->mib_data[pos++]; + plat_name_len |= (mib_info->mib_data[pos++] << 16); + + /* Sanity check */ + if (plat_name_len + pos > mib_info->mib_len || plat_name_len < 2) { + SLSI_ERR_NODEV("Bad HCF FFFF key length %zu\n", + plat_name_len); + return -EINVAL; /* Implausible length */ + } + + /* Skip vldata header SC-506179-SP. This conveys the + * length of the platform string and is 2 or 3 octets long + * depending on the length of the string. + */ + { +#define SLSI_VLDATA_STRING 0xA0 +#define SLSI_VLDATA_LEN 0x17 + + u8 vlen_hdr = mib_info->mib_data[pos++]; + u8 vlen_len = vlen_hdr & SLSI_VLDATA_LEN; /* size of length field */ + + /* Skip vlen header octet */ + plat_name_len--; + + SLSI_DBG1_NODEV(SLSI_INIT_DEINIT, "vlhdr 0x%x, len %u\n", vlen_hdr, vlen_len); + + /* Is it an octet string type? */ + if (!(vlen_hdr & SLSI_VLDATA_STRING)) { + SLSI_ERR_NODEV("No string vlen header 0x%x\n", vlen_hdr); + return -EINVAL; + } + + /* Handle 1 or 2 octet length field only */ + if (vlen_len > 2) { + SLSI_ERR_NODEV("Too long octet string header %u\n", vlen_len); + return -EINVAL; + } + + /* Skip over the string length field. + * Note we just use datalength anyway. + */ + pos += vlen_len; + plat_name_len -= vlen_len; + } + + /* Limit the platform name to space in driver and read */ + { + size_t trunc_len = plat_name_len; + + if (trunc_len > sizeof(mib_info->platform)) + trunc_len = sizeof(mib_info->platform) - 1; + + /* Extract platform name */ + memcpy(mib_info->platform, &mib_info->mib_data[pos], trunc_len); + mib_info->platform[trunc_len] = '\0'; + + /* Print non-truncated string in log now */ + SLSI_INFO_NODEV("MIB platform: %.*s\n", (int)plat_name_len, &mib_info->mib_data[pos]); + + SLSI_DBG1_NODEV(SLSI_INIT_DEINIT, "plat_name_len: %zu + %u\n", + plat_name_len, (plat_name_len & 1)); + } + + /* Pad string to 16-bit boundary */ + plat_name_len += (plat_name_len & 1); + pos += plat_name_len; + + /* Advance over the keys we read, FW doesn't need them */ + mib_info->mib_data += pos; + mib_info->mib_len -= pos; + + SLSI_DBG1_NODEV(SLSI_INIT_DEINIT, "Skip %d octets HCF payload\n", pos); + + return 0; +} + #define MGT_HASH_SIZE_BYTES 2 /* Hash will be contained in a uint32 */ #define MGT_HASH_OFFSET 4 static int slsi_mib_open_file(struct slsi_dev *sdev, struct slsi_dev_mib_info *mib_info, const struct firmware **fw) @@ -897,9 +1168,9 @@ static int slsi_mib_open_file(struct slsi_dev *sdev, struct slsi_dev_mib_info *m r = mx140_file_request_conf(sdev->maxwell_core, &e, "wlan", mib_file_name); if (r || (!e)) { - SLSI_DBG2(sdev, SLSI_INIT_DEINIT, "Skip MIB download as file [%s] is NOT found and is optional\n", mib_file_name); + SLSI_DBG2(sdev, SLSI_INIT_DEINIT, "Skip MIB download as file %s is NOT found\n", mib_file_name); *fw = e; - return 0; + return r; } mib_info->mib_data = (u8 *)e->data; @@ -936,6 +1207,9 @@ cont: /* All good - skip header and continue */ mib_info->mib_data += 8; mib_info->mib_len -= 8; + + /* Extract platform name if available */ + slsi_mib_get_platform(mib_info); } else { /* Bad header */ SLSI_ERR(sdev, "configuration file '%s' has bad header\n", mib_info->mib_file_name); @@ -1021,7 +1295,7 @@ static int slsi_mib_initial_get(struct slsi_dev *sdev) { SLSI_PSID_UNIFI_HARDWARE_PLATFORM, {0, 0} }, { SLSI_PSID_UNIFI_REG_DOM_VERSION, {0, 0} }, { SLSI_PSID_UNIFI_NAN_ENABLED, {0, 0} }, - { SLSI_PSID_UNIFI_FORCED_SCHEDULE_DURATION, {0, 0} }, + { SLSI_PSID_UNIFI_DEFAULT_DWELL_TIME, {0, 0} }, #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING { SLSI_PSID_UNIFI_WI_FI_SHARING5_GHZ_CHANNEL, {0, 0} }, #endif @@ -1332,6 +1606,49 @@ int slsi_mib_get_gscan_cap(struct slsi_dev *sdev, struct slsi_nl_gscan_capabilit } #endif +int slsi_mib_get_rtt_cap(struct slsi_dev *sdev, struct net_device *dev, struct slsi_rtt_capabilities *cap) +{ + struct slsi_mib_data supported_rtt_capab = { 0, NULL }; + struct slsi_mib_data mibrsp = { 0, NULL }; + struct slsi_mib_value *values = NULL; + + struct slsi_mib_get_entry get_values[] = { { SLSI_PSID_UNIFI_RTT_CAPABILITIES, { 0, 0 } } }; + + mibrsp.dataLength = 64; + mibrsp.data = kmalloc(mibrsp.dataLength, GFP_KERNEL); + if (!mibrsp.data) { + SLSI_ERR(sdev, "Cannot kmalloc %d bytes\n", mibrsp.dataLength); + kfree(mibrsp.data); + return -ENOMEM; + } + + values = slsi_read_mibs(sdev, dev, get_values, 1, &mibrsp); + if (!values) { + kfree(mibrsp.data); + return -EINVAL; + } + + if (values[0].type != SLSI_MIB_TYPE_OCTET) { + SLSI_ERR(sdev, "Invalid type (%d) for SLSI_PSID_UNIFI_RTT_CAPABILITIES", values[0].type); + kfree(mibrsp.data); + kfree(values); + return -EINVAL; + } + supported_rtt_capab = values[0].u.octetValue; + cap->rtt_one_sided_supported = supported_rtt_capab.data[0]; + cap->rtt_ftm_supported = supported_rtt_capab.data[1]; + cap->lci_support = supported_rtt_capab.data[2]; + cap->lcr_support = supported_rtt_capab.data[3]; + cap->responder_supported = supported_rtt_capab.data[4]; + cap->preamble_support = supported_rtt_capab.data[5]; + cap->bw_support = supported_rtt_capab.data[6]; + cap->mc_version = supported_rtt_capab.data[7]; + + kfree(values); + kfree(mibrsp.data); + return 0; +} + struct slsi_peer *slsi_peer_add(struct slsi_dev *sdev, struct net_device *dev, u8 *peer_address, u16 aid) { struct netdev_vif *ndev_vif = netdev_priv(dev); @@ -1766,10 +2083,9 @@ void slsi_vif_deactivated(struct slsi_dev *sdev, struct net_device *dev) /* MUST be done first to ensure that other code doesn't treat the VIF as still active */ ndev_vif->activated = false; +#ifndef CONFIG_SCSC_WLAN_RX_NAPI slsi_skb_queue_purge(&ndev_vif->rx_data.queue); - - slsi_skb_queue_purge(&ndev_vif->rx_data.queue); - +#endif for (i = 0; i < (SLSI_ADHOC_PEER_CONNECTIONS_MAX); i++) { struct slsi_peer *peer = ndev_vif->peer_sta_record[i]; @@ -1845,7 +2161,7 @@ static int slsi_sta_ieee80211_mode(struct net_device *dev, u16 current_bss_chann static int slsi_get_sta_mode(struct net_device *dev, const u8 *last_peer_mac) { struct netdev_vif *ndev_vif = netdev_priv(dev); - struct slsi_dev *sdev; + struct slsi_dev *sdev = ndev_vif->sdev; struct slsi_peer *last_peer; const u8 *peer_ie; @@ -3015,8 +3331,6 @@ int slsi_auto_chan_select_scan(struct slsi_dev *sdev, int n_channels, struct iee return r; } - SLSI_NET_DBG1(dev, SLSI_CFG80211, "number of Channels %d\n", n_channels); - ndev_vif = netdev_priv(dev); SLSI_MUTEX_LOCK(ndev_vif->scan_mutex); @@ -3096,6 +3410,8 @@ next_scan: SLSI_MUTEX_LOCK(sdev->device_config_mutex); sdev->device_config.ap_auto_chan = channels[selected_index]->hw_value & 0xFF; SLSI_MUTEX_UNLOCK(sdev->device_config_mutex); + + SLSI_INFO(sdev, "Channel selected = %d", sdev->device_config.ap_auto_chan); } slsi_skb_queue_purge(&unique_scan_results); ndev_vif->scan[SLSI_SCAN_HW_ID].is_blocking_scan = false; @@ -3556,25 +3872,40 @@ u8 slsi_p2p_get_exp_peer_frame_subtype(u8 subtype) } } -void slsi_hs2_dump_public_action_subtype(struct ieee80211_mgmt *mgmt, bool tx) +void slsi_wlan_dump_public_action_subtype(struct ieee80211_mgmt *mgmt, bool tx) { u8 action_code = ((u8 *)&mgmt->u.action.u)[0]; + u8 action_category = mgmt->u.action.category; - switch (action_code) { - case SLSI_PA_GAS_INITIAL_REQ: - SLSI_DBG1_NODEV(SLSI_CFG80211, "%s: GAS Initial Request\n", tx ? "TX" : "RX"); - break; - case SLSI_PA_GAS_INITIAL_RSP: - SLSI_DBG1_NODEV(SLSI_CFG80211, "%s: GAS Initial Response\n", tx ? "TX" : "RX"); - break; - case SLSI_PA_GAS_COMEBACK_REQ: - SLSI_DBG1_NODEV(SLSI_CFG80211, "%s: GAS Comeback Request\n", tx ? "TX" : "RX"); - break; - case SLSI_PA_GAS_COMEBACK_RSP: - SLSI_DBG1_NODEV(SLSI_CFG80211, "%s: GAS Comeback Response\n", tx ? "TX" : "RX"); - break; - default: - SLSI_DBG1_NODEV(SLSI_CFG80211, "Unknown GAS Frame : %d\n", action_code); + switch (action_category) { + case WLAN_CATEGORY_RADIO_MEASUREMENT: + switch (action_code) { + case SLSI_RM_NEIGH_REP_REQ: + SLSI_DBG1_NODEV(SLSI_CFG80211, "%s: RM Neigh Report Request\n", tx ? "TX" : "RX"); + break; + case SLSI_RM_NEIGH_REP_RSP: + SLSI_DBG1_NODEV(SLSI_CFG80211, "%s: RM Neigh Report Response\n", tx ? "TX" : "RX"); + break; + default: + SLSI_DBG1_NODEV(SLSI_CFG80211, "Unknown Radio Measurement Frame : %d\n", action_code); + } + case WLAN_CATEGORY_PUBLIC: + switch (action_code) { + case SLSI_PA_GAS_INITIAL_REQ: + SLSI_DBG1_NODEV(SLSI_CFG80211, "%s: GAS Initial Request\n", tx ? "TX" : "RX"); + break; + case SLSI_PA_GAS_INITIAL_RSP: + SLSI_DBG1_NODEV(SLSI_CFG80211, "%s: GAS Initial Response\n", tx ? "TX" : "RX"); + break; + case SLSI_PA_GAS_COMEBACK_REQ: + SLSI_DBG1_NODEV(SLSI_CFG80211, "%s: GAS Comeback Request\n", tx ? "TX" : "RX"); + break; + case SLSI_PA_GAS_COMEBACK_RSP: + SLSI_DBG1_NODEV(SLSI_CFG80211, "%s: GAS Comeback Response\n", tx ? "TX" : "RX"); + break; + default: + SLSI_DBG1_NODEV(SLSI_CFG80211, "Unknown GAS Frame : %d\n", action_code); + } } } @@ -4123,12 +4454,9 @@ void slsi_modify_ies_on_channel_switch(struct net_device *dev, struct cfg80211_a u8 *ds_params_ie, u8 *ht_operation_ie, struct ieee80211_mgmt *mgmt, u16 beacon_ie_head_len) { - ds_params_ie = (u8 *)cfg80211_find_ie(WLAN_EID_DS_PARAMS, mgmt->u.beacon.variable, beacon_ie_head_len); slsi_modify_ies(dev, WLAN_EID_DS_PARAMS, mgmt->u.beacon.variable, beacon_ie_head_len, 2, ieee80211_frequency_to_channel(settings->chandef.chan->center_freq)); - ht_operation_ie = (u8 *)cfg80211_find_ie(WLAN_EID_HT_OPERATION, settings->beacon.tail, - settings->beacon.tail_len); slsi_modify_ies(dev, WLAN_EID_HT_OPERATION, (u8 *)settings->beacon.tail, settings->beacon.tail_len, 2, ieee80211_frequency_to_channel(settings->chandef.chan->center_freq)); @@ -4372,7 +4700,49 @@ exit: return 0; } #endif +#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION +int slsi_set_mac_randomisation_mask(struct slsi_dev *sdev, u8 *mac_address_mask) +{ + int r = 0; + struct slsi_mib_data mib_data = { 0, NULL }; + SLSI_DBG1(sdev, SLSI_CFG80211, "Mask is :%pM\n", mac_address_mask); + r = slsi_mib_encode_octet(&mib_data, SLSI_PSID_UNIFI_MAC_ADDRESS_RANDOMISATION_MASK, ETH_ALEN, + mac_address_mask, 0); + if (r != SLSI_MIB_STATUS_SUCCESS) { + SLSI_ERR(sdev, "Err setting unifiMacAddrRandomistaionMask MIB. error = %d\n", r); + if (sdev->scan_addr_set) { + struct slsi_mib_data mib_data_randomization_activated = { 0, NULL }; + + r = slsi_mib_encode_bool(&mib_data_randomization_activated, + SLSI_PSID_UNIFI_MAC_ADDRESS_RANDOMISATION_ACTIVATED, 1, 0); + if (r != SLSI_MIB_STATUS_SUCCESS) { + SLSI_ERR(sdev, "UNIFI_MAC_ADDRESS_RANDOMISATION_ACTIVATED: no mem for MIB\n"); + return -ENOMEM; + } + + r = slsi_mlme_set(sdev, NULL, mib_data_randomization_activated.data, + mib_data_randomization_activated.dataLength); + + kfree(mib_data_randomization_activated.data); + + if (r) + SLSI_ERR(sdev, "Err setting unifiMacAddrRandomistaionActivated MIB. error = %d\n", r); + return r; + } + return -ENOMEM; + } + if (mib_data.dataLength == 0) { + SLSI_WARN(sdev, "Mib Data length is Zero\n"); + return -EINVAL; + } + r = slsi_mlme_set(sdev, NULL, mib_data.data, mib_data.dataLength); + if (r) + SLSI_ERR(sdev, "Err setting Randomized mac mask= %d\n", r); + kfree(mib_data.data); + return r; +} +#endif /* Set the new country code and read the regulatory parameters of updated country. */ int slsi_set_country_update_regd(struct slsi_dev *sdev, const char *alpha2_code, int size) { @@ -4630,46 +5000,51 @@ static void slsi_hs2_unsync_vif_delete_work(struct work_struct *work) SLSI_MUTEX_LOCK(ndev_vif->vif_mutex); SLSI_NET_DBG1(ndev_vif->wdev.netdev, SLSI_CFG80211, "Delete HS vif duration expired - Deactivate unsync vif\n"); - slsi_hs2_vif_deactivate(ndev_vif->sdev, ndev_vif->wdev.netdev, true); + slsi_wlan_unsync_vif_deactivate(ndev_vif->sdev, ndev_vif->wdev.netdev, true); SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex); } -int slsi_hs2_vif_activate(struct slsi_dev *sdev, struct net_device *dev, struct ieee80211_channel *chan, u16 wait) +int slsi_wlan_unsync_vif_activate(struct slsi_dev *sdev, struct net_device *dev, + struct ieee80211_channel *chan, u16 wait) { struct netdev_vif *ndev_vif = netdev_priv(dev); int r = 0; u8 device_address[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + u32 action_frame_bmap; - SLSI_DBG1(sdev, SLSI_INIT_DEINIT, "Activate HS unsync vif\n"); + SLSI_DBG1(sdev, SLSI_INIT_DEINIT, "Activate wlan unsync vif\n"); WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex)); ndev_vif->vif_type = FAPI_VIFTYPE_UNSYNCHRONISED; - /* Avoid suspend when HS2 unsync VIF is active */ + /* Avoid suspend when wlan unsync VIF is active */ slsi_wakelock(&sdev->wlan_wl); /* Interface address and device address are same for unsync vif */ if (slsi_mlme_add_vif(sdev, dev, dev->dev_addr, device_address) != 0) { - SLSI_NET_ERR(dev, "add vif failed for HS unsync vif\n"); + SLSI_NET_ERR(dev, "add vif failed for wlan unsync vif\n"); goto exit_with_error; } if (slsi_vif_activated(sdev, dev) != 0) { - SLSI_NET_ERR(dev, "vif activate failed for HS unsync vif\n"); + SLSI_NET_ERR(dev, "vif activate failed for wlan unsync vif\n"); slsi_mlme_del_vif(sdev, dev); goto exit_with_error; } - sdev->hs2_state = HS2_VIF_ACTIVE; + sdev->wlan_unsync_vif_state = WLAN_UNSYNC_VIF_ACTIVE; INIT_DELAYED_WORK(&ndev_vif->unsync.hs2_del_vif_work, slsi_hs2_unsync_vif_delete_work); + action_frame_bmap = SLSI_ACTION_FRAME_PUBLIC | SLSI_ACTION_FRAME_RADIO_MEASUREMENT; - if (slsi_mlme_register_action_frame(sdev, dev, SLSI_ACTION_FRAME_PUBLIC, SLSI_ACTION_FRAME_PUBLIC) != 0) { - SLSI_NET_ERR(dev, "Action frame registration failed for HS unsync vif\n"); + r = slsi_mlme_register_action_frame(sdev, dev, action_frame_bmap, action_frame_bmap); + if (r != 0) { + SLSI_NET_ERR(dev, "slsi_mlme_register_action_frame failed: resultcode = %d, action_frame_bmap:%d\n", + r, action_frame_bmap); goto exit_with_vif; } if (slsi_mlme_set_channel(sdev, dev, chan, SLSI_FW_CHANNEL_DURATION_UNSPECIFIED, 0, 0) != 0) { - SLSI_NET_ERR(dev, "Set channel failed for HS unsync vif\n"); + SLSI_NET_ERR(dev, "Set channel failed for wlan unsync vif\n"); goto exit_with_vif; } ndev_vif->chan = chan; @@ -4677,23 +5052,23 @@ int slsi_hs2_vif_activate(struct slsi_dev *sdev, struct net_device *dev, struct return r; exit_with_vif: - slsi_hs2_vif_deactivate(sdev, dev, true); + slsi_wlan_unsync_vif_deactivate(sdev, dev, true); exit_with_error: slsi_wakeunlock(&sdev->wlan_wl); return -EINVAL; } /* Delete unsync vif - DON'T update the vif type */ -void slsi_hs2_vif_deactivate(struct slsi_dev *sdev, struct net_device *dev, bool hw_available) +void slsi_wlan_unsync_vif_deactivate(struct slsi_dev *sdev, struct net_device *dev, bool hw_available) { struct netdev_vif *ndev_vif = netdev_priv(dev); - SLSI_NET_DBG1(dev, SLSI_INIT_DEINIT, "De-activate HS unsync vif\n"); + SLSI_NET_DBG1(dev, SLSI_INIT_DEINIT, "De-activate wlan unsync vif\n"); WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex)); - if (sdev->hs2_state == HS2_NO_VIF) { - SLSI_NET_DBG1(dev, SLSI_INIT_DEINIT, "HS unsync vif already deactivated\n"); + if (sdev->wlan_unsync_vif_state == WLAN_UNSYNC_NO_VIF) { + SLSI_NET_DBG1(dev, SLSI_INIT_DEINIT, "wlan unsync vif already deactivated\n"); return; } @@ -4707,7 +5082,7 @@ void slsi_hs2_vif_deactivate(struct slsi_dev *sdev, struct net_device *dev, bool slsi_wakeunlock(&sdev->wlan_wl); - sdev->hs2_state = HS2_NO_VIF; + sdev->wlan_unsync_vif_state = WLAN_UNSYNC_NO_VIF; ndev_vif->activated = false; ndev_vif->chan = NULL; @@ -4740,16 +5115,20 @@ void slsi_update_supported_channels_regd_flags(struct slsi_dev *sdev) struct wiphy *wiphy = sdev->wiphy; struct ieee80211_channel *chan; + /* If all channels are supported by chip no need disable any channel + * So return + */ if (sdev->enabled_channel_count == 39) return; - - for (i = 0; i < ARRAY_SIZE(sdev->supported_2g_channels); i++) { - if (sdev->supported_2g_channels[i] == 0) { - chan = &wiphy->bands[0]->channels[i]; - chan->flags |= IEEE80211_CHAN_DISABLED; + if (wiphy->bands[0]) { + for (i = 0; i < ARRAY_SIZE(sdev->supported_2g_channels); i++) { + if (sdev->supported_2g_channels[i] == 0) { + chan = &wiphy->bands[0]->channels[i]; + chan->flags |= IEEE80211_CHAN_DISABLED; + } } } - if (sdev->band_5g_supported) { + if (sdev->band_5g_supported && wiphy->bands[1]) { for (i = 0; i < ARRAY_SIZE(sdev->supported_5g_channels); i++) { if (sdev->supported_5g_channels[i] == 0) { chan = &wiphy->bands[1]->channels[i]; diff --git a/drivers/net/wireless/scsc/mgt.h b/drivers/net/wireless/scsc/mgt.h index dab85bd399d8..99bf2e5a29b8 100755 --- a/drivers/net/wireless/scsc/mgt.h +++ b/drivers/net/wireless/scsc/mgt.h @@ -113,6 +113,10 @@ #define SLSI_PA_GAS_COMEBACK_REQ (12) #define SLSI_PA_GAS_COMEBACK_RSP (13) +/*Radio Measurement action frames types */ +#define SLSI_RM_NEIGH_REP_REQ (4) +#define SLSI_RM_NEIGH_REP_RSP (5) + /* For service discovery action frames dummy subtype is used by setting the 7th bit */ #define SLSI_PA_GAS_DUMMY_SUBTYPE_MASK 0x80 #define SLSI_PA_GAS_INITIAL_REQ_SUBTYPE (SLSI_PA_GAS_INITIAL_REQ | SLSI_PA_GAS_DUMMY_SUBTYPE_MASK) @@ -452,10 +456,14 @@ int slsi_read_unifi_countrylist(struct slsi_dev *sdev, u16 psid); int slsi_read_default_country(struct slsi_dev *sdev, u8 *alpha2, u16 index); int slsi_read_disconnect_ind_timeout(struct slsi_dev *sdev, u16 psid); int slsi_read_regulatory_rules(struct slsi_dev *sdev, struct slsi_802_11d_reg_domain *domain_info, const char *alpha2); +#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION +int slsi_set_mac_randomisation_mask(struct slsi_dev *sdev, u8 *mac_address_mask); +#endif int slsi_set_country_update_regd(struct slsi_dev *sdev, const char *alpha2_code, int size); void slsi_clear_offchannel_data(struct slsi_dev *sdev, bool acquire_lock); -int slsi_hs2_vif_activate(struct slsi_dev *sdev, struct net_device *dev, struct ieee80211_channel *chan, u16 duration); -void slsi_hs2_vif_deactivate(struct slsi_dev *sdev, struct net_device *devbool, bool hw_available); +int slsi_wlan_unsync_vif_activate(struct slsi_dev *sdev, struct net_device *dev, + struct ieee80211_channel *chan, u16 duration); +void slsi_wlan_unsync_vif_deactivate(struct slsi_dev *sdev, struct net_device *devbool, bool hw_available); int slsi_is_wes_action_frame(const struct ieee80211_mgmt *mgmt); void slsi_scan_ind_timeout_handle(struct work_struct *work); void slsi_vif_cleanup(struct slsi_dev *sdev, struct net_device *dev, bool hw_available); @@ -466,6 +474,11 @@ void slsi_update_supported_channels_regd_flags(struct slsi_dev *sdev); #ifdef CONFIG_SCSC_WLAN_HANG_TEST int slsi_test_send_hanged_vendor_event(struct net_device *dev); #endif -void slsi_hs2_dump_public_action_subtype(struct ieee80211_mgmt *mgmt, bool tx); +void slsi_wlan_dump_public_action_subtype(struct ieee80211_mgmt *mgmt, bool tx); void slsi_reset_channel_flags(struct slsi_dev *sdev); + +/* Sysfs based mac address override */ +void slsi_create_sysfs_macaddr(void); +void slsi_destroy_sysfs_macaddr(void); + #endif /*__SLSI_MGT_H__*/ diff --git a/drivers/net/wireless/scsc/mib.c b/drivers/net/wireless/scsc/mib.c index fa671912d4b6..10d16a4ac493 100755 --- a/drivers/net/wireless/scsc/mib.c +++ b/drivers/net/wireless/scsc/mib.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd and its Licensors. + * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd and its Licensors. * All rights reserved. * *****************************************************************************/ @@ -148,6 +148,27 @@ size_t slsi_mib_decode_uint32(u8 *buffer, u32 *value) return 1 + length; } +size_t slsi_mib_decodeUint64(u8 *buffer, u64 *value) +{ + size_t i; + u64 v = 0; + size_t length = buffer[0] & SLSI_MIB_LENGTH_MASK; + + if (!(buffer[0] & SLSI_MIB_MORE_MASK)) { + *value = buffer[0] & 0x7F; + return 1; + } + + for (i = 0; i < length; i++) { + v = (v << 8); + v |= buffer[1 + i]; + } + + *value = v; + + return 1 + length; +} + size_t slsi_mib_decodeInt32(u8 *buffer, s32 *value) { size_t i; @@ -173,6 +194,31 @@ size_t slsi_mib_decodeInt32(u8 *buffer, s32 *value) return 1 + length; } +size_t slsi_mib_decodeInt64(u8 *buffer, s64 *value) +{ + size_t i; + u64 v = 0xFFFFFFFFFFFFFFFFULL; + size_t length = buffer[0] & SLSI_MIB_LENGTH_MASK; + + if (!(buffer[0] & SLSI_MIB_SIGN_MASK)) + /* just use the Unsigned Decoder */ + return slsi_mib_decodeUint64(buffer, (u64 *)value); + + if (!(buffer[0] & SLSI_MIB_MORE_MASK)) { + *value = (s64)(0xFFFFFFFFFFFFFF80ULL | buffer[0]); + return 1; + } + + for (i = 0; i < length; i++) { + v = (v << 8); + v |= buffer[1 + i]; + } + + *value = (s64)v; + + return 1 + length; +} + /* Just references the oid in the existing buffer. No new memory is allcated */ size_t slsi_mib_decode_octet_str(u8 *buffer, struct slsi_mib_data *octet_value) { diff --git a/drivers/net/wireless/scsc/mib.h b/drivers/net/wireless/scsc/mib.h old mode 100755 new mode 100644 index d4f05009120a..2200988c2e69 --- a/drivers/net/wireless/scsc/mib.h +++ b/drivers/net/wireless/scsc/mib.h @@ -200,6 +200,8 @@ size_t slsi_mib_encode_octet_str(u8 *buffer, struct slsi_mib_data *octetValue); size_t slsi_mib_decodeUint32(u8 *buffer, u32 *value); size_t slsi_mib_decodeInt32(u8 *buffer, s32 *value); +size_t slsi_mib_decodeUint64(u8 *buffer, u64 *value); +size_t slsi_mib_decodeInt64(u8 *buffer, s64 *value); size_t slsi_mib_decode_octet_str(u8 *buffer, struct slsi_mib_data *octetValue); /******************************************************************************* @@ -238,8 +240,8 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 65535 * DEFAULT : 1 * DESCRIPTION : - * The minimum time that needs to pass after the most recent TPU SP, before - * a RAME_TPU_SP indication can be sent to MLME + * The minimum time after the last TPU SP, before a RAME_TPU_SP indication + * can be issued. *******************************************************************************/ #define SLSI_PSID_DOT11_TDLS_PEER_UAPSD_INDICATION_WINDOW 0x0035 @@ -304,11 +306,11 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * NAME : Dot11RtsThreshold * PSID : 121 (0x0079) * PER INTERFACE?: NO - * TYPE : SlsiUint16 + * TYPE : SlsiUint32 * UNITS : octet * MIN : 0 * MAX : 65536 - * DEFAULT : 9000 + * DEFAULT : 65536 * DESCRIPTION : * Size of an MPDU, below which an RTS/CTS handshake shall not be performed, * except as RTS/CTS is used as a cross modulation protection mechanism as @@ -578,15 +580,11 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * PSID : 2000 (0x07D0) * PER INTERFACE?: NO * TYPE : SlsiUint16 - * UNITS : milliseconds * MIN : 0 * MAX : 65535 - * DEFAULT : 3000 + * DEFAULT : * DESCRIPTION : - * Firmware waits for unifiMLMEConnectionTimeOut of no successful Tx/Rx - * (including beacon) to/from AP before it disconnects from AP.For STA case - * - Setting it to less than 3 seconds may result in frequent disconnection - * with the AP + * Depricated *******************************************************************************/ #define SLSI_PSID_UNIFI_MLME_CONNECTION_TIMEOUT 0x07D0 @@ -637,13 +635,11 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * PSID : 2007 (0x07D7) * PER INTERFACE?: NO * TYPE : SlsiUint16 - * UNITS : TU * MIN : 0 * MAX : 65535 - * DEFAULT : 70 + * DEFAULT : * DESCRIPTION : - * Time between transmissions of broadcast probe requests on a given channel - * when performing an active scan. + * Deprecated. *******************************************************************************/ #define SLSI_PSID_UNIFI_MLME_SCAN_PROBE_INTERVAL 0x07D7 @@ -684,7 +680,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 65535 * DEFAULT : * DESCRIPTION : - * Depricate + * Depricated *******************************************************************************/ #define SLSI_PSID_UNIFI_MLME_SCAN_MAXIMUM_AGE 0x07DE @@ -695,7 +691,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint16 * MIN : 0 * MAX : 65535 - * DEFAULT : 40 + * DEFAULT : 100 * DESCRIPTION : * Max number of scan results (for all scans) which will be stored before * the oldest result is discarded, irrespective of its age. The value 0 @@ -716,6 +712,20 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_MLME_AUTONOMOUS_SCAN_NOISY 0x07E0 +/******************************************************************************* + * NAME : UnifiChannelBusyThreshold + * PSID : 2018 (0x07E2) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 1 + * MAX : 100 + * DEFAULT : 30 + * DESCRIPTION : + * The threshold in percentage of CCA busy time when a channel would be + * considered busy + *******************************************************************************/ +#define SLSI_PSID_UNIFI_CHANNEL_BUSY_THRESHOLD 0x07E2 + /******************************************************************************* * NAME : UnifiFirmwareBuildId * PSID : 2021 (0x07E5) @@ -800,7 +810,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint8 * MIN : 21 * MAX : 21 - * DEFAULT : { 0X6F, 0X01, 0X17, 0XFF, 0X00, 0X00, 0X00, 0X01, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00 } + * DEFAULT : { 0XEF, 0X0A, 0X17, 0XFF, 0XFF, 0X00, 0X00, 0X01, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00 } * DESCRIPTION : * HT capabilities of the chip. See SC-503520-SP for further details. NOTE: * Greenfield has been disabled due to interoperability issues wuth SGI. @@ -816,7 +826,8 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 1 * DEFAULT : FALSE * DESCRIPTION : - * Enables 40Mz wide channels in the 2.4G band + * Enables 40Mz wide channels in the 2.4G band for STA. Our AP does not + * support this. *******************************************************************************/ #define SLSI_PSID_UNIFI24_G40_MHZ_CHANNELS 0x07F3 @@ -871,7 +882,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint8 * MIN : 5 * MAX : 5 - * DEFAULT : { 0X71, 0X00, 0X00, 0X00, 0X00 } + * DEFAULT : { 0X71, 0X00, 0X00, 0X00, 0X04 } * DESCRIPTION : * RM Enabled capabilities of the chip. See SC-503520-SP for further * details. @@ -904,6 +915,20 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_HT_ACTIVATED 0x07FE +/******************************************************************************* + * NAME : UnifiEnableTwoSimultaneousActiveScansSameBand + * PSID : 2047 (0x07FF) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * Enable two active scans to be simultaneously scheduled on two distinct + * channels on the same. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_ENABLE_TWO_SIMULTANEOUS_ACTIVE_SCANS_SAME_BAND 0x07FF + /******************************************************************************* * NAME : UnifiRoamingEnabled * PSID : 2049 (0x0801) @@ -1163,6 +1188,20 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_AP_OLBC_INTERVAL 0x081D +/******************************************************************************* + * NAME : UnifiOffchannelScheduleTimeout + * PSID : 2079 (0x081F) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 1000 + * DESCRIPTION : + * Maximum timeout in ms the Offchannel FSM will wait until the complete + * dwell time is scheduled + *******************************************************************************/ +#define SLSI_PSID_UNIFI_OFFCHANNEL_SCHEDULE_TIMEOUT 0x081F + /******************************************************************************* * NAME : UnifiFrameResponseTimeout * PSID : 2080 (0x0820) @@ -1300,6 +1339,20 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_MLME_SCAN_STOP_IF_LESS_THAN_XFRAMES 0x0828 +/******************************************************************************* + * NAME : UnifiApAssociationTimeout + * PSID : 2089 (0x0829) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 2000 + * DESCRIPTION : + * SoftAP: Permitted time for a station to complete associatation with FW + * acting as AP in milliseconds. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_AP_ASSOCIATION_TIMEOUT 0x0829 + /******************************************************************************* * NAME : UnifiPeerBandwidth * PSID : 2094 (0x082E) @@ -1385,6 +1438,20 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_MLME_CLI_INACTIVITY_TIMEOUT 0x0833 +/******************************************************************************* + * NAME : UnifiMlmeStationInitialKickTimeout + * PSID : 2100 (0x0834) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * UNITS : millisecond + * MIN : 0 + * MAX : 65535 + * DEFAULT : 50 + * DESCRIPTION : + * Timeout for sending the AP a NULL frame to kick off the EAPOL exchange. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_MLME_STATION_INITIAL_KICK_TIMEOUT 0x0834 + /******************************************************************************* * NAME : UnifiUartConfigure * PSID : 2110 (0x083E) @@ -1466,21 +1533,6 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_ENABLE_DORM 0x085E -/******************************************************************************* - * NAME : UnifiDisableDormWhenBtOn - * PSID : 2143 (0x085F) - * PER INTERFACE?: NO - * TYPE : SlsiBool - * MIN : 0 - * MAX : 1 - * DEFAULT : FALSE - * DESCRIPTION : - * Dorm/deep sleep would be dynamically disabled when BT is turned ON if the - * value is TRUE, even though unifiEnableDorm is TRUE. For more details, - * take a look at SSB-17864. - *******************************************************************************/ -#define SLSI_PSID_UNIFI_DISABLE_DORM_WHEN_BT_ON 0x085F - /******************************************************************************* * NAME : UnifiExternalClockDetect * PSID : 2146 (0x0862) @@ -1543,19 +1595,19 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * PSID : 2154 (0x086A) * PER INTERFACE?: NO * TYPE : SlsiUint8 - * MIN : 20 - * MAX : 20 + * MIN : 18 + * MAX : 18 * DEFAULT : * DESCRIPTION : * Scan parameters. Each row of the table contains 2 entries for a scan: * first entry when there is 0 registered VIFs, second - when there is 1 or * more registered VIFs. Entry has the following structure: octet 0 - Scan - * priority (uint8_t) octet 1 - Enable Early Channel Exit (uint8_t as bool) - * octet 2 ~ 3 - Probe Interval in Time Units (uint16_t) octet 4 ~ 5 - Max - * Active Channel Time in Time Units (uint16_t) octet 6 ~ 7 - Max Passive - * Channel Time in Time Units (uint16_t) octet 8 ~ 9 - Scan Policy - * (uint16_t) Size of each entry is 10 octets, row size is 20 octets. A Time - * Units value specifies a time interval as a multiple of TU (1024 us). + * priority (uint8) octet 1 - Enable Early Channel Exit (uint8 as bool) + * octet 2 ~ 3 - Probe Interval in Time Units (uint16) octet 4 ~ 5 - Max + * Active Channel Time in Time Units (uint16) octet 6 ~ 7 - Max Passive + * Channel Time in Time Units (uint16) octet 8 - Scan Policy (uint8) Size of + * each entry is 9 octets, row size is 18 octets. A Time Units value + * specifies a time interval as a multiple of TU (1024 us). *******************************************************************************/ #define SLSI_PSID_UNIFI_SCAN_PARAMETERS 0x086A @@ -1850,6 +1902,20 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_CURRENT_TSF_TIME 0x08AA +/******************************************************************************* + * NAME : UnifiBaRxEnableTid + * PSID : 2219 (0x08AB) + * PER INTERFACE?: NO + * TYPE : SlsiUint32 + * MIN : 0 + * MAX : 4294967295 + * DEFAULT : 0X1555 + * DESCRIPTION : + * Configure Block Ack RX on a per-TID basis. Bit mask is two bits per TID + * (B1 = Not Used, B0 = enable). + *******************************************************************************/ +#define SLSI_PSID_UNIFI_BA_RX_ENABLE_TID 0x08AB + /******************************************************************************* * NAME : UnifiBaTxEnableTid * PSID : 2221 (0x08AD) @@ -1897,8 +1963,8 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 1 - * MAX : 5 - * DEFAULT : 1 + * MAX : 4 + * DEFAULT : 2 * DESCRIPTION : * Defines the maximum number of A-MSDU sub-frames per A-MSDU. A value of 1 * indicates A-MSDU aggregation has been disabled @@ -1915,11 +1981,23 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * DEFAULT : 0X3FFF01 * DESCRIPTION : * Block Ack Configuration. It is composed of A-MSDU supported, TX MPDU per - * A-MPDU, RX Buffer size, TX Buffer size and Block Ack Timeout. see - * init_mlme_ba() for more detail + * A-MPDU, RX Buffer size, TX Buffer size and Block Ack Timeout. *******************************************************************************/ #define SLSI_PSID_UNIFI_BA_CONFIG 0x08B1 +/******************************************************************************* + * NAME : UnifiBaTxMaxNumber + * PSID : 2226 (0x08B2) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 0X10 + * DESCRIPTION : + * Block Ack Configuration. Maximum number of BAs. Limited by HW. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_BA_TX_MAX_NUMBER 0x08B2 + /******************************************************************************* * NAME : UnifiBeaconReceived * PSID : 2228 (0x08B4) @@ -2155,7 +2233,10 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * DESCRIPTION : * is used to access throughput related counters that can help diagnose * throughput problems. The index of the MIB will access different counters, - * as described in SC-506328-DD. + * as described in SC-506328-DD. Setting any index for a VIF to any value, + * clears all DPLP debug stats for the MAC instance used by the VIF. This is + * useful mainly for debugging LAA or small scale throughput issues that + * require short term collection of the statistics. *******************************************************************************/ #define SLSI_PSID_UNIFI_THROUGHPUT_DEBUG 0x08CE @@ -2168,7 +2249,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 147 * DEFAULT : * DESCRIPTION : - * Write a static DPD LUT to the FW + * Write a static DPD LUT to the FW, read DPD LUT from hardware *******************************************************************************/ #define SLSI_PSID_UNIFI_LOAD_DPD_LUT 0x08CF @@ -2190,8 +2271,8 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * PSID : 2257 (0x08D1) * PER INTERFACE?: NO * TYPE : SlsiUint8 - * MIN : 13 - * MAX : 13 + * MIN : 14 + * MAX : 14 * DEFAULT : * DESCRIPTION : * DPD pre-distort gains. Takes a range of frequencies, where f_min <= @@ -2295,6 +2376,132 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_MAC_BEACON_TIMEOUT 0x08DE +/******************************************************************************* + * NAME : UnifiStaUsesOneAntennaWhenIdle + * PSID : 2274 (0x08E2) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : TRUE + * DESCRIPTION : + * Allow the platform to downgrade antenna usage for STA VIFs to 1 if the + * VIF is idle. Only valid for multi-radio platforms. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_STA_USES_ONE_ANTENNA_WHEN_IDLE 0x08E2 + +/******************************************************************************* + * NAME : UnifiStaUsesMultiAntennasDuringConnect + * PSID : 2275 (0x08E3) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : TRUE + * DESCRIPTION : + * Allow the platform to use multiple antennas for STA VIFs during the + * connect phase. Only valid for multi-radio platforms. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_STA_USES_MULTI_ANTENNAS_DURING_CONNECT 0x08E3 + +/******************************************************************************* + * NAME : UnifiApUsesOneAntennaWhenPeersIdle + * PSID : 2276 (0x08E4) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : TRUE + * DESCRIPTION : + * Allow the platform to downgrade antenna usage for AP VIFs when all + * connected peers are idle. Only valid for multi-radio platforms. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_AP_USES_ONE_ANTENNA_WHEN_PEERS_IDLE 0x08E4 + +/******************************************************************************* + * NAME : UnifiUpdateAntennaCapabilitiesWhenScanning + * PSID : 2277 (0x08E5) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * Specify whether antenna scan activities will be allowed to cause an + * update of VIF capability. Only valid for multi-radio platforms. WARNING: + * Changing this value after system start-up will have no effect. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_UPDATE_ANTENNA_CAPABILITIES_WHEN_SCANNING 0x08E5 + +/******************************************************************************* + * NAME : UnifiLoadDpdLutPerRadio + * PSID : 2280 (0x08E8) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 147 + * MAX : 147 + * DEFAULT : + * DESCRIPTION : + * Write a static DPD LUT to the FW, read DPD LUT from hardware (for devices + * that support multiple radios) + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LOAD_DPD_LUT_PER_RADIO 0x08E8 + +/******************************************************************************* + * NAME : UnifiOverrideDpdLutPerRadio + * PSID : 2281 (0x08E9) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 147 + * MAX : 147 + * DEFAULT : + * DESCRIPTION : + * Write a DPD LUT directly to the HW (for devices that support multiple + * radios) + *******************************************************************************/ +#define SLSI_PSID_UNIFI_OVERRIDE_DPD_LUT_PER_RADIO 0x08E9 + +/******************************************************************************* + * NAME : UnifiRoamDeauthReason + * PSID : 2294 (0x08F6) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 3 + * DESCRIPTION : + * A deauthentication reason for which the STA will trigger a roaming scan + * rather than disconnect directly. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_ROAM_DEAUTH_REASON 0x08F6 + +/******************************************************************************* + * NAME : UnifiCuRoamfactor + * PSID : 2295 (0x08F7) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Table allocating CUfactor to Channel Utilisation values range. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_CU_ROAMFACTOR 0x08F7 + +/******************************************************************************* + * NAME : UnifiRoamCuHighLowPoints + * PSID : 2296 (0x08F8) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Table allocating the high and low points for computing the linear + * CUfactor. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_ROAM_CU_HIGH_LOW_POINTS 0x08F8 + /******************************************************************************* * NAME : UnifiRoamRssiHighLowPoints * PSID : 2297 (0x08F9) @@ -2395,19 +2602,6 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_CU_ROAMWEIGHT 0x08FF -/******************************************************************************* - * NAME : UnifiCuRoamfactor - * PSID : 2304 (0x0900) - * PER INTERFACE?: NO - * TYPE : SlsiUint16 - * MIN : 0 - * MAX : 65535 - * DEFAULT : - * DESCRIPTION : - * Table allocating CUfactor to Channel Utilization values range. - *******************************************************************************/ -#define SLSI_PSID_UNIFI_CU_ROAMFACTOR 0x0900 - /******************************************************************************* * NAME : UnifiRssiRoamweight * PSID : 2305 (0x0901) @@ -2478,6 +2672,20 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_ROAM_BSS_LOAD_MONITORING_FREQUENCY 0x0905 +/******************************************************************************* + * NAME : UnifiRoamBlacklistSize + * PSID : 2310 (0x0906) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * UNITS : entries + * MIN : 0 + * MAX : 100 + * DEFAULT : 5 + * DESCRIPTION : + * Do not remove! Read by the host! And then passed up to the framework. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_ROAM_BLACKLIST_SIZE 0x0906 + /******************************************************************************* * NAME : UnifiCuMeasurementInterval * PSID : 2311 (0x0907) @@ -2519,7 +2727,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf #define SLSI_PSID_UNIFI_AP_MIMO_USED 0x0909 /******************************************************************************* - * NAME : UnifiRoamOffloaded4wshkTimeout + * NAME : UnifiRoamEapolTimeout * PSID : 2314 (0x090A) * PER INTERFACE?: NO * TYPE : SlsiUint16 @@ -2528,10 +2736,9 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 100 * DEFAULT : 10 * DESCRIPTION : - * Maximum time allowed before an attempt to do an offloaded 4 way handshake - * is considered failed? + * Maximum time allowed for an offloaded Eapol (4 way handshake). *******************************************************************************/ -#define SLSI_PSID_UNIFI_ROAM_OFFLOADED4WSHK_TIMEOUT 0x090A +#define SLSI_PSID_UNIFI_ROAM_EAPOL_TIMEOUT 0x090A /******************************************************************************* * NAME : UnifiRoamingCount @@ -2614,128 +2821,241 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 1 * DEFAULT : FALSE * DESCRIPTION : - * Enable reporting of the fate of the TX packets sent by the host + * Enable reporting of the fate of the TX packets sent by the host.This mib + * value will be updated if "unifiRameUpdateMibs" mib is toggled *******************************************************************************/ #define SLSI_PSID_UNIFI_MA_PACKET_FATE_ENABLED 0x0911 /******************************************************************************* - * NAME : UnifiCsrOnlyEifsDuration - * PSID : 2362 (0x093A) + * NAME : UnifiLaaNssSpeculationIntervalSlotTime + * PSID : 2330 (0x091A) * PER INTERFACE?: NO * TYPE : SlsiUint16 - * UNITS : microseconds * MIN : 0 * MAX : 65535 - * DEFAULT : 12 + * DEFAULT : 300 * DESCRIPTION : - * Specifies time that is used for EIFS. A value of 0 causes the build in - * value to be used. + * For Link Adaptation Algorithm. It defines the repeatable amount of time, + * in ms, that firmware will start to send speculation frames for spatial + * streams. *******************************************************************************/ -#define SLSI_PSID_UNIFI_CSR_ONLY_EIFS_DURATION 0x093A +#define SLSI_PSID_UNIFI_LAA_NSS_SPECULATION_INTERVAL_SLOT_TIME 0x091A /******************************************************************************* - * NAME : UnifiOverrideDefaultBetxopForHt - * PSID : 2364 (0x093C) + * NAME : UnifiLaaNssSpeculationIntervalSlotMaxNum + * PSID : 2331 (0x091B) * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 * MAX : 65535 - * DEFAULT : 171 + * DEFAULT : 5 * DESCRIPTION : - * When set to non-zero value then this will override the BE TXOP for 11n - * and higher modulations (in 32 usec units) to the value specified here. + * For Link Adaptation Algorithm. It defines the maximum number of + * speculation time slot for spatial stream. *******************************************************************************/ -#define SLSI_PSID_UNIFI_OVERRIDE_DEFAULT_BETXOP_FOR_HT 0x093C +#define SLSI_PSID_UNIFI_LAA_NSS_SPECULATION_INTERVAL_SLOT_MAX_NUM 0x091B /******************************************************************************* - * NAME : UnifiOverrideDefaultBetxop - * PSID : 2365 (0x093D) + * NAME : UnifiLaaBwSpeculationIntervalSlotTime + * PSID : 2332 (0x091C) * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 * MAX : 65535 - * DEFAULT : 78 + * DEFAULT : 300 * DESCRIPTION : - * When set to non-zero value then this will override the BE TXOP for 11g - * (in 32 usec units) to the value specified here. + * For Link Adaptation Algorithm. It defines the repeatable amount of time, + * in ms, that firmware will start to send speculation frames for bandwidth. *******************************************************************************/ -#define SLSI_PSID_UNIFI_OVERRIDE_DEFAULT_BETXOP 0x093D +#define SLSI_PSID_UNIFI_LAA_BW_SPECULATION_INTERVAL_SLOT_TIME 0x091C /******************************************************************************* - * NAME : UnifiRxabbTrimSettings - * PSID : 2366 (0x093E) + * NAME : UnifiLaaBwSpeculationIntervalSlotMaxNum + * PSID : 2333 (0x091D) * PER INTERFACE?: NO - * TYPE : SlsiUint32 + * TYPE : SlsiUint16 * MIN : 0 - * MAX : 4294967295 - * DEFAULT : + * MAX : 65535 + * DEFAULT : 8 * DESCRIPTION : - * Various settings to change RX ABB filter trim behavior. + * For Link Adaptation Algorithm. It defines the maximum number of + * speculation time slot for bandwidth. *******************************************************************************/ -#define SLSI_PSID_UNIFI_RXABB_TRIM_SETTINGS 0x093E +#define SLSI_PSID_UNIFI_LAA_BW_SPECULATION_INTERVAL_SLOT_MAX_NUM 0x091D /******************************************************************************* - * NAME : UnifiRadioTrimsEnable - * PSID : 2367 (0x093F) + * NAME : UnifiLaaMcsSpeculationIntervalSlotTime + * PSID : 2334 (0x091E) * PER INTERFACE?: NO - * TYPE : SlsiUint32 + * TYPE : SlsiUint16 * MIN : 0 - * MAX : 4294967295 - * DEFAULT : 0X0FF5 + * MAX : 65535 + * DEFAULT : 100 * DESCRIPTION : - * A bitmap for enabling/disabling trims at runtime. Check unifiEnabledTrims - * enum for description of the possible values. + * For Link Adaptation Algorithm. It defines the repeatable amount of time, + * in ms, that firmware will start to send speculation frames for MCS or + * rate index. *******************************************************************************/ -#define SLSI_PSID_UNIFI_RADIO_TRIMS_ENABLE 0x093F +#define SLSI_PSID_UNIFI_LAA_MCS_SPECULATION_INTERVAL_SLOT_TIME 0x091E /******************************************************************************* - * NAME : UnifiRadioCcaThresholds - * PSID : 2368 (0x0940) + * NAME : UnifiLaaMcsSpeculationIntervalSlotMaxNum + * PSID : 2335 (0x091F) * PER INTERFACE?: NO - * TYPE : SlsiUint32 + * TYPE : SlsiUint16 * MIN : 0 - * MAX : 4294967295 - * DEFAULT : 0X16301630 + * MAX : 65535 + * DEFAULT : 10 * DESCRIPTION : - * The CCA thresholds so that the CCA-ED triggers at the regulatory value of - * -62 dBm. The least significant 16bit word contains thresholds for - * standard operation and the most significant 16bit word contains - * thresholds for operation with any (external) FEM LNA disabled. For each - * 16bit word, gain threshold in the lower octet and RSSI threshold in the - * higher octet. + * For Link Adaptation Algorithm. It defines the maximum number of + * speculation time slot for MCS or rate index. *******************************************************************************/ -#define SLSI_PSID_UNIFI_RADIO_CCA_THRESHOLDS 0x0940 +#define SLSI_PSID_UNIFI_LAA_MCS_SPECULATION_INTERVAL_SLOT_MAX_NUM 0x091F /******************************************************************************* - * NAME : UnifiHardwarePlatform - * PSID : 2369 (0x0941) + * NAME : UnifiLaaGiSpeculationIntervalSlotTime + * PSID : 2336 (0x0920) * PER INTERFACE?: NO - * TYPE : unifiHardwarePlatform + * TYPE : SlsiUint16 * MIN : 0 - * MAX : 255 - * DEFAULT : + * MAX : 65535 + * DEFAULT : 100 * DESCRIPTION : - * Hardware platform. This is necessary so we can apply tweaks to specific - * revisions, even though they might be running the same baseband and RF - * chip combination. Check unifiHardwarePlatform enum for description of the - * possible values. + * For Link Adaptation Algorithm. It defines the repeatable amount of time, + * in ms, that firmware will start to send speculation frames for guard + * interval. *******************************************************************************/ -#define SLSI_PSID_UNIFI_HARDWARE_PLATFORM 0x0941 +#define SLSI_PSID_UNIFI_LAA_GI_SPECULATION_INTERVAL_SLOT_TIME 0x0920 /******************************************************************************* - * NAME : UnifiForceChannelBw - * PSID : 2370 (0x0942) + * NAME : UnifiLaaGiSpeculationIntervalSlotMaxNum + * PSID : 2337 (0x0921) * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 * MAX : 65535 - * DEFAULT : + * DEFAULT : 50 * DESCRIPTION : - * Test/debug Mib to force channel bandwidth to specified value. This can + * For Link Adaptation Algorithm. It defines the maximum number of + * speculation time slot for guard interval. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LAA_GI_SPECULATION_INTERVAL_SLOT_MAX_NUM 0x0921 + +/******************************************************************************* + * NAME : UnifiCsrOnlyEifsDuration + * PSID : 2362 (0x093A) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * UNITS : microseconds + * MIN : 0 + * MAX : 65535 + * DEFAULT : 12 + * DESCRIPTION : + * Specifies time that is used for EIFS. A value of 0 causes the build in + * value to be used. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_CSR_ONLY_EIFS_DURATION 0x093A + +/******************************************************************************* + * NAME : UnifiOverrideDefaultBetxopForHt + * PSID : 2364 (0x093C) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 171 + * DESCRIPTION : + * When set to non-zero value then this will override the BE TXOP for 11n + * and higher modulations (in 32 usec units) to the value specified here. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_OVERRIDE_DEFAULT_BETXOP_FOR_HT 0x093C + +/******************************************************************************* + * NAME : UnifiOverrideDefaultBetxop + * PSID : 2365 (0x093D) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 78 + * DESCRIPTION : + * When set to non-zero value then this will override the BE TXOP for 11g + * (in 32 usec units) to the value specified here. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_OVERRIDE_DEFAULT_BETXOP 0x093D + +/******************************************************************************* + * NAME : UnifiRxabbTrimSettings + * PSID : 2366 (0x093E) + * PER INTERFACE?: NO + * TYPE : SlsiUint32 + * MIN : 0 + * MAX : 4294967295 + * DEFAULT : + * DESCRIPTION : + * Various settings to change RX ABB filter trim behavior. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_RXABB_TRIM_SETTINGS 0x093E + +/******************************************************************************* + * NAME : UnifiRadioTrimsEnable + * PSID : 2367 (0x093F) + * PER INTERFACE?: NO + * TYPE : SlsiUint32 + * MIN : 0 + * MAX : 4294967295 + * DEFAULT : 0X0FF5 + * DESCRIPTION : + * A bitmap for enabling/disabling trims at runtime. Check unifiEnabledTrims + * enum for description of the possible values. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_RADIO_TRIMS_ENABLE 0x093F + +/******************************************************************************* + * NAME : UnifiRadioCcaThresholds + * PSID : 2368 (0x0940) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 0 + * MAX : 255 + * DEFAULT : + * DESCRIPTION : + * The wideband CCA ED thresholds so that the CCA-ED triggers at the + * regulatory value of -62 dBm. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_RADIO_CCA_THRESHOLDS 0x0940 + +/******************************************************************************* + * NAME : UnifiHardwarePlatform + * PSID : 2369 (0x0941) + * PER INTERFACE?: NO + * TYPE : unifiHardwarePlatform + * MIN : 0 + * MAX : 255 + * DEFAULT : + * DESCRIPTION : + * Hardware platform. This is necessary so we can apply tweaks to specific + * revisions, even though they might be running the same baseband and RF + * chip combination. Check unifiHardwarePlatform enum for description of the + * possible values. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_HARDWARE_PLATFORM 0x0941 + +/******************************************************************************* + * NAME : UnifiForceChannelBw + * PSID : 2370 (0x0942) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Test/debug Mib to force channel bandwidth to specified value. This can * also be used to allow emulator/silicon back to back connection to * communicate at bandwidth other than default (20 MHz) Setting it to 0 uses * the default bandwidth as selected by firmware channel_bw_20_mhz = 20, - * channel_bw_40_mhz = 40, channel_bw_80_mhz = 80 + * channel_bw_40_mhz = 40, channel_bw_80_mhz = 80 This mib value will be + * updated if "unifiRameUpdateMibs" mib is toggled *******************************************************************************/ #define SLSI_PSID_UNIFI_FORCE_CHANNEL_BW 0x0942 @@ -2788,6 +3108,19 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_DPD_TRAIN_PACKET_CONFIG 0x0945 +/******************************************************************************* + * NAME : UnifiTxPowerTrimCommonConfig + * PSID : 2374 (0x0946) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 3 + * MAX : 255 + * DEFAULT : + * DESCRIPTION : + * Common transmitter power trim settings + *******************************************************************************/ +#define SLSI_PSID_UNIFI_TX_POWER_TRIM_COMMON_CONFIG 0x0946 + /******************************************************************************* * NAME : UnifiCoexDebugOverrideBt * PSID : 2425 (0x0979) @@ -2801,6 +3134,219 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_COEX_DEBUG_OVERRIDE_BT 0x0979 +/******************************************************************************* + * NAME : UnifiLteMailbox + * PSID : 2430 (0x097E) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 36 + * MAX : 40 + * DEFAULT : + * DESCRIPTION : + * Set modem status to simulate lte status updates. See SC-505775-SP for API + * description. Defined as array of uint32 represented by the octet string + * FOR TEST PURPOSES ONLY + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_MAILBOX 0x097E + +/******************************************************************************* + * NAME : UnifiLteMwsSignal + * PSID : 2431 (0x097F) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Set modem status to simulate lte status updates. See SC-505775-SP for API + * description. See unifiLteSignalsBitField for enum bitmap. FOR TEST + * PURPOSES ONLY + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_MWS_SIGNAL 0x097F + +/******************************************************************************* + * NAME : UnifiLteEnableChannelAvoidance + * PSID : 2432 (0x0980) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : TRUE + * DESCRIPTION : + * Enables channel avoidance scheme for LTE Coex + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_ENABLE_CHANNEL_AVOIDANCE 0x0980 + +/******************************************************************************* + * NAME : UnifiLteEnablePowerBackoff + * PSID : 2433 (0x0981) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : TRUE + * DESCRIPTION : + * Enables power backoff scheme for LTE Coex + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_ENABLE_POWER_BACKOFF 0x0981 + +/******************************************************************************* + * NAME : UnifiLteEnableTimeDomain + * PSID : 2434 (0x0982) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : TRUE + * DESCRIPTION : + * Enables TDD scheme for LTE Coex + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_ENABLE_TIME_DOMAIN 0x0982 + +/******************************************************************************* + * NAME : UnifiLteEnableLteCoex + * PSID : 2435 (0x0983) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : TRUE + * DESCRIPTION : + * Enables LTE Coex support + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_ENABLE_LTE_COEX 0x0983 + +/******************************************************************************* + * NAME : UnifiLteBand40PowerBackoffChannelMask + * PSID : 2436 (0x0984) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 3 + * DESCRIPTION : + * Channel Mask defining channels on which to apply power backoff when LTE + * operating on Band40. Defined as a 16 bit bitmask, as only 2G4 channels + * are impacted by this feature. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_BAND40_POWER_BACKOFF_CHANNEL_MASK 0x0984 + +/******************************************************************************* + * NAME : UnifiLteBand40PowerBackoffRsrpLow + * PSID : 2437 (0x0985) + * PER INTERFACE?: NO + * TYPE : SlsiInt16 + * UNITS : dBm + * MIN : -140 + * MAX : -77 + * DEFAULT : -100 + * DESCRIPTION : + * WLAN Power Reduction shall be applied when RSRP of LTE operating on band + * 40 falls below this level + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_BAND40_POWER_BACKOFF_RSRP_LOW 0x0985 + +/******************************************************************************* + * NAME : UnifiLteBand40PowerBackoffRsrpHigh + * PSID : 2438 (0x0986) + * PER INTERFACE?: NO + * TYPE : SlsiInt16 + * UNITS : dBm + * MIN : -140 + * MAX : -77 + * DEFAULT : -95 + * DESCRIPTION : + * WLAN Power Reduction shall be restored when RSRP of LTE operating on band + * 40 climbs above this level + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_BAND40_POWER_BACKOFF_RSRP_HIGH 0x0986 + +/******************************************************************************* + * NAME : UnifiLteBand40PowerBackoffRsrpAveragingAlpha + * PSID : 2439 (0x0987) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * UNITS : percentage + * MIN : 0 + * MAX : 65535 + * DEFAULT : 50 + * DESCRIPTION : + * Weighting applied when calculaing the average RSRP when considering Power + * Back Off Specifies the percentage weighting (alpha) to give to the most + * recent value when calculating the moving average. ma_new = alpha * + * new_sample + (1-alpha) * ma_old. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_BAND40_POWER_BACKOFF_RSRP_AVERAGING_ALPHA 0x0987 + +/******************************************************************************* + * NAME : UnifiLteSetChannel + * PSID : 2440 (0x0988) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Enables LTE Coex support + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_SET_CHANNEL 0x0988 + +/******************************************************************************* + * NAME : UnifiLteSetPowerBackoff + * PSID : 2441 (0x0989) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * MIB to force WLAN Power Backoff for LTE COEX testing purposes + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_SET_POWER_BACKOFF 0x0989 + +/******************************************************************************* + * NAME : UnifiLteSetTddDebugMode + * PSID : 2442 (0x098A) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * MIB to enable LTE TDD COEX simulation for testing purposes + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_SET_TDD_DEBUG_MODE 0x098A + +/******************************************************************************* + * NAME : UnifiApScanAbsenceDuration + * PSID : 2480 (0x09B0) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * UNITS : beacon intervals + * MIN : 0 + * MAX : 65535 + * DEFAULT : 7 + * DESCRIPTION : + * Duration of the Absence time to use when protecting AP VIFs from scan + * operations. A value of 0 disables the feature. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_AP_SCAN_ABSENCE_DURATION 0x09B0 + +/******************************************************************************* + * NAME : UnifiApScanAbsencePeriod + * PSID : 2481 (0x09B1) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * UNITS : beacon intervals + * MIN : 0 + * MAX : 65535 + * DEFAULT : 14 + * DESCRIPTION : + * Period of the Absence/Presence times cycles to use when protecting AP + * VIFs from scan operations. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_AP_SCAN_ABSENCE_PERIOD 0x09B1 + /******************************************************************************* * NAME : UnifiFastPowerSaveTimeout * PSID : 2500 (0x09C4) @@ -3018,6 +3564,19 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_STATION_ACTIVITY_IDLE_TIME 0x09D0 +/******************************************************************************* + * NAME : UnifiDmsEnabled + * PSID : 2513 (0x09D1) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : TRUE + * DESCRIPTION : + * Enables Directed Multicast Service (DMS) + *******************************************************************************/ +#define SLSI_PSID_UNIFI_DMS_ENABLED 0x09D1 + /******************************************************************************* * NAME : UnifiPowerManagementDelayTimeout * PSID : 2514 (0x09D2) @@ -3113,7 +3672,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * UNITS : DTIM intervals * MIN : 0 * MAX : 4294967295 - * DEFAULT : 0X000A89AA + * DEFAULT : 0X00054645 * DESCRIPTION : * Listen interval of beacons when in single-vif power saving mode and * receiving DTIMs is enabled. No DTIMs are skipped during MVIF operation. A @@ -3136,7 +3695,8 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 100 * DEFAULT : 10 * DESCRIPTION : - * Beacon Listen Interval + * Association request listen interval parameter. Not used for any other + * purpose. *******************************************************************************/ #define SLSI_PSID_UNIFI_LISTEN_INTERVAL 0x09D7 @@ -3161,7 +3721,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint32 * MIN : 0 * MAX : 4294967295 - * DEFAULT : 0X01010103 + * DEFAULT : 0X00010103 * DESCRIPTION : * Control beacon skipping behaviour within firmware with bit flags. 1 * defines enabled, with 0 showing the case disabled. If beacon skipping is @@ -3171,10 +3731,10 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * LCD on bit 3: station skipping with multivif bit 4: station skipping with * BT active. bit 8: station skip dtim on host suspend bit 9: station skip * dtim on host awake bit 10: station skip dtim on LCD on bit 11: station - * skip dtim on multivif bit 12: station skip dtim with BT active bit 15: - * p2p-gc skipping on host suspend bit 16: p2p-gc skipping on host awake bit - * 17: p2p-gc skipping on LCD on bit 18: p2p-gc skipping with multivif bit - * 19: p2p-gc skipping with BT active bit 24: p2p-gc skip dtim on host + * skip dtim on multivif bit 12: station skip dtim with BT active bit 16: + * p2p-gc skipping on host suspend bit 17: p2p-gc skipping on host awake bit + * 18: p2p-gc skipping on LCD on bit 19: p2p-gc skipping with multivif bit + * 20: p2p-gc skipping with BT active bit 24: p2p-gc skip dtim on host * suspend bit 25: p2p-gc skip dtim on host awake bit 26: p2p-gc skip dtim * on LCD on bit 27: p2p-gc skip dtim on multivif bit 28: p2p-gc skip dtim * with BT active @@ -3250,11 +3810,12 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiBool * MIN : 0 * MAX : 1 - * DEFAULT : TRUE + * DEFAULT : FALSE * DESCRIPTION : * Enables Idle Mode Lite, if softAP is active, and there has been no * activity for a time. Idle mode lite should not be active if host has sent - * a command to change key. + * a command to change key. This mib value will be runtime (post-wlan + * enable) applied only if "unifiRameUpdateMibs" mib is toggled *******************************************************************************/ #define SLSI_PSID_UNIFI_IDLE_MODE_LITE_ENABLED 0x09DE @@ -3265,10 +3826,11 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiBool * MIN : 0 * MAX : 1 - * DEFAULT : TRUE + * DEFAULT : FALSE * DESCRIPTION : - * Enables Idle Mode, if single vif station is active, and there has been no - * activity for a time. + * Enables Idle Mode, if single vif station is active or there is no vif, + * and there has been no activity for a time. This mib value will be runtime + * (post-wlan enable) applied if only "unifiRameUpdateMibs" mib is toggled *******************************************************************************/ #define SLSI_PSID_UNIFI_IDLE_MODE_ENABLED 0x09DF @@ -3302,7 +3864,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint16 * UNITS : TU * MIN : 0 - * MAX : 65536 + * MAX : 65535 * DEFAULT : 1000 * DESCRIPTION : * Maximum number length of time, in Time Units (1TU = 1024us), that can be @@ -3355,7 +3917,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * UNITS : ms * MIN : 0 * MAX : 65535 - * DEFAULT : 500 + * DEFAULT : 100 * DESCRIPTION : * Lifetime of proberesponse frame in unit of ms. *******************************************************************************/ @@ -3434,7 +3996,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf #define SLSI_PSID_UNIFI_ACTIVE_TIME_AFTER_MORE_BIT 0x09E9 /******************************************************************************* - * NAME : UnifiForcedScheduleDuration + * NAME : UnifiDefaultDwellTime * PSID : 2538 (0x09EA) * PER INTERFACE?: NO * TYPE : SlsiUint16 @@ -3443,12 +4005,10 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 65535 * DEFAULT : 50 * DESCRIPTION : - * Defines the time to keep a VIF scheduled after an outgoing packet is - * queued, if the "Immediate_Response_Expected" bit is set in the Tx_Control - * associated with a frame transmission request. The firmware may choose to - * override this value based on internal logic. + * Defines the dwell time for frames that need a response but have no dwell + * time associated *******************************************************************************/ -#define SLSI_PSID_UNIFI_FORCED_SCHEDULE_DURATION 0x09EA +#define SLSI_PSID_UNIFI_DEFAULT_DWELL_TIME 0x09EA /******************************************************************************* * NAME : UnifiVhtCapabilities @@ -3457,7 +4017,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint8 * MIN : 12 * MAX : 12 - * DEFAULT : { 0X30, 0X78, 0X90, 0X01, 0XFA, 0XFF, 0X00, 0X00, 0XFA, 0XFF, 0X00, 0X00 } + * DEFAULT : { 0XB1, 0X7A, 0X11, 0X03, 0XFA, 0XFF, 0X00, 0X00, 0XFA, 0XFF, 0X00, 0X00 } * DESCRIPTION : * VHT capabilities of the chip. see SC-503520-SP. *******************************************************************************/ @@ -3541,7 +4101,36 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf #define SLSI_PSID_UNIFI_DEBUG_KEEP_RADIO_ON 0x09F1 /******************************************************************************* - * NAME : UnifiScanAbsenceDuration + * NAME : UnifiForceFixedDurationSchedule + * PSID : 2546 (0x09F2) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * UNITS : TU + * MIN : 0 + * MAX : 65535 + * DEFAULT : 100 + * DESCRIPTION : + * For schedules with fixed duration e.g. scan, unsync VIF, the schedule + * will be forced after this time to avoid VIF starving + *******************************************************************************/ +#define SLSI_PSID_UNIFI_FORCE_FIXED_DURATION_SCHEDULE 0x09F2 + +/******************************************************************************* + * NAME : UnifiRameUpdateMibs + * PSID : 2547 (0x09F3) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * When this mib is called/toggled MACRAME mibs will be read and compared + * with mib values in ramedata.mibs and updated if the value changes + *******************************************************************************/ +#define SLSI_PSID_UNIFI_RAME_UPDATE_MIBS 0x09F3 + +/******************************************************************************* + * NAME : UnifiGoScanAbsenceDuration * PSID : 2548 (0x09F4) * PER INTERFACE?: NO * TYPE : SlsiUint16 @@ -3553,10 +4142,10 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * Duration of the Absence time to use when protecting P2PGO VIFs from scan * operations. A value of 0 disables the feature. *******************************************************************************/ -#define SLSI_PSID_UNIFI_SCAN_ABSENCE_DURATION 0x09F4 +#define SLSI_PSID_UNIFI_GO_SCAN_ABSENCE_DURATION 0x09F4 /******************************************************************************* - * NAME : UnifiScanAbsencePeriod + * NAME : UnifiGoScanAbsencePeriod * PSID : 2549 (0x09F5) * PER INTERFACE?: NO * TYPE : SlsiUint16 @@ -3568,7 +4157,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * Period of the Absence/Presence times cycles to use when protecting P2PGO * VIFs from scan operations. *******************************************************************************/ -#define SLSI_PSID_UNIFI_SCAN_ABSENCE_PERIOD 0x09F5 +#define SLSI_PSID_UNIFI_GO_SCAN_ABSENCE_PERIOD 0x09F5 /******************************************************************************* * NAME : UnifiMaxClient @@ -3592,7 +4181,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 1 * DEFAULT : TRUE * DESCRIPTION : - * Use TDLS in P2P mode. + * Enable TDLS in P2P. *******************************************************************************/ #define SLSI_PSID_UNIFI_TDLS_IN_P2P_ACTIVATED 0x09FC @@ -3605,7 +4194,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 1 * DEFAULT : TRUE * DESCRIPTION : - * Use TDLS mode. + * Enable TDLS. *******************************************************************************/ #define SLSI_PSID_UNIFI_TDLS_ACTIVATED 0x09FE @@ -3618,9 +4207,8 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 4294967295 * DEFAULT : 100 * DESCRIPTION : - * Used for the argument "throughput_threshold_pktsecs" of - * RAME-MLME-ENABLE-PEER-TRAFFIC-REPORTING.request signal defined in - * SC-505422-DD. + * Used for "throughput_threshold_pktsecs" of + * RAME-MLME-ENABLE-PEER-TRAFFIC-REPORTING.request. *******************************************************************************/ #define SLSI_PSID_UNIFI_TDLS_TP_THRESHOLD_PKT_SECS 0x09FF @@ -3633,9 +4221,9 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 32767 * DEFAULT : -75 * DESCRIPTION : - * Used for the FW initiated TDLS Discovery/Setup procedure. If the RSSI of - * a received TDLS Discovery Response frame is greater than this value,the - * TDLS FSM shall initiate the TDLS Setup procedure. + * FW initiated TDLS Discovery/Setup procedure. If the RSSI of a received + * TDLS Discovery Response frame is greater than this value, initiate the + * TDLS Setup procedure. *******************************************************************************/ #define SLSI_PSID_UNIFI_TDLS_RSSI_THRESHOLD 0x0A00 @@ -3648,9 +4236,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 65535 * DEFAULT : 3 * DESCRIPTION : - * Transmission of a TDLS Action frame or a TDLS Discovery Response Public - * Action frame shall be retried unifiTdlsMaximumRetry times until the frame - * is transmitted successfully. + * Deprecated. *******************************************************************************/ #define SLSI_PSID_UNIFI_TDLS_MAXIMUM_RETRY 0x0A01 @@ -3663,7 +4249,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 65535 * DEFAULT : 10 * DESCRIPTION : - * The measurement period for recording the number of packets sent to a peer + * Measurement period for recording the number of packets sent to a peer * over a TDLS link. *******************************************************************************/ #define SLSI_PSID_UNIFI_TDLS_TP_MONITOR_SECS 0x0A02 @@ -3675,10 +4261,9 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint8 * MIN : 16 * MAX : 16 - * DEFAULT : { 0XFF, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00 } + * DEFAULT : * DESCRIPTION : - * The default Basic HT MCS SET used on a TDLS Link. Used to build the HT - * Operation element in TDLS Setup frames. + * Deprecated. *******************************************************************************/ #define SLSI_PSID_UNIFI_TDLS_BASIC_HT_MCS_SET 0x0A03 @@ -3689,9 +4274,9 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint8 * MIN : 2 * MAX : 2 - * DEFAULT : { 0XFE, 0XFF } + * DEFAULT : * DESCRIPTION : - * Used to build the VHT Operation element in the TDLS Setup Confirm frame + * Deprecated *******************************************************************************/ #define SLSI_PSID_UNIFI_TDLS_BASIC_VHT_MCS_SET 0x0A04 @@ -3704,9 +4289,8 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 4294967295 * DEFAULT : 10 * DESCRIPTION : - * TDLS shall not transmit the TDLS Discovery Request frame within - * dot11TDLSDiscoveryRequestWindow DTIM intervals after transmitting TDLS - * Discovery Request frame. + * Time to gate Discovery Request frame (in DTIM intervals) after + * transmitting a Discovery Request frame. *******************************************************************************/ #define SLSI_PSID_DOT11_TDLS_DISCOVERY_REQUEST_WINDOW 0x0A05 @@ -3719,10 +4303,9 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 4294967295 * DEFAULT : 5 * DESCRIPTION : - * If no TDLS Setup Response frame is received within - * dot11TDLSResponseTimeout (seconds), or if a TDLS Setup Response frame is - * received with a nonzero status code, the TDLS initiator STA shall - * terminate the setup procedure and discard the TDLS Setup Response frame. + * If a valid Setup Response frame is not received within (seconds), the + * initiator STA shall terminate the setup procedure and discard any Setup + * Response frames. *******************************************************************************/ #define SLSI_PSID_DOT11_TDLS_RESPONSE_TIMEOUT 0x0A06 @@ -3735,8 +4318,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 1 * DEFAULT : FALSE * DESCRIPTION : - * When true, indicates that the STA implementation is capable of supporting - * TDLS Channel Switching. + * Deprecated. *******************************************************************************/ #define SLSI_PSID_DOT11_TDLS_CHANNEL_SWITCH_ACTIVATED 0x0A07 @@ -3749,7 +4331,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 4294967295 * DEFAULT : 0X00000000 * DESCRIPTION : - * Set TDLS design for test mode + * Deprecated *******************************************************************************/ #define SLSI_PSID_UNIFI_TDLS_DESIGN_FOR_TEST_MODE 0x0A08 @@ -3762,7 +4344,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 1 * DEFAULT : FALSE * DESCRIPTION : - * When true, TDLS wider bandwidth selection is prohibited. + * Wider bandwidth prohibited flag. *******************************************************************************/ #define SLSI_PSID_UNIFI_TDLS_WIDER_BANDWIDTH_PROHIBITED 0x0A09 @@ -3788,8 +4370,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 65535 * DEFAULT : 500 * DESCRIPTION : - * Allowed time in milliseconds for a TDLS Teardown frame to be trasmitted - * over the air + * Allowed time in milliseconds for a Teardown frame to be transmitted. *******************************************************************************/ #define SLSI_PSID_UNIFI_TDLS_TEARDOWN_FRAME_TX_TIMEOUT 0x0A12 @@ -3800,25 +4381,12 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiBool * MIN : 0 * MAX : 1 - * DEFAULT : FALSE + * DEFAULT : TRUE * DESCRIPTION : * Enables WiFi Sharing feature *******************************************************************************/ #define SLSI_PSID_UNIFI_WIFI_SHARING_ENABLED 0x0A14 -/******************************************************************************* - * NAME : UnifiWiFiSharing5GHzAllowed - * PSID : 2581 (0x0A15) - * PER INTERFACE?: NO - * TYPE : SlsiBool - * MIN : 0 - * MAX : 1 - * DEFAULT : FALSE - * DESCRIPTION : - * Whether usage of 5GHz band is allowed for WiFi Sharing - *******************************************************************************/ -#define SLSI_PSID_UNIFI_WI_FI_SHARING5_GHZ_ALLOWED 0x0A15 - /******************************************************************************* * NAME : UnifiWiFiSharing5GHzChannel * PSID : 2582 (0x0A16) @@ -3826,12 +4394,12 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint8 * MIN : 8 * MAX : 8 - * DEFAULT : { 0X00, 0X00, 0X00, 0X00, 0X20, 0X00, 0X00, 0X00 } + * DEFAULT : { 0X00, 0XC0, 0XFF, 0XFF, 0X7F, 0X00, 0X00, 0X00 } * DESCRIPTION : - * 5GHz Primary Channels applicable. Defined in a uint64 represented by the - * octet string. First byte of the octet string maps to LSB. Bits 0-13 are - * always set to 0 (don't care). Mapping defined in - * mlme_regulatory_freq_list[]; i.e. Bit 14 maps to channel 36. + * Applicable 5GHz Primary Channels mask. Defined in a uint64 represented by + * the octet string. First byte of the octet string maps to LSB. Bits 0-13 + * representing 2.4G channels are always set to 0. Mapping defined in + * ChannelisationRules; i.e. Bit 14 maps to channel 36. *******************************************************************************/ #define SLSI_PSID_UNIFI_WI_FI_SHARING5_GHZ_CHANNEL 0x0A16 @@ -3887,7 +4455,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 65535 * DEFAULT : 0X00000000 * DESCRIPTION : - * Virtual router advertisement packet is only used for the test purpose, + * Virtual router advertisement packet. is only used for the test purpose, * specified in chapter '6.2 Forward Received RA frame to Host' in * SC-506393-TE *******************************************************************************/ @@ -3902,11 +4470,89 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 1 * DEFAULT : TRUE * DESCRIPTION : - * Indicate that the STA implementation is capable of supporting TDLS peer - * U-APSD. + * Enable TDLS peer U-APSD. *******************************************************************************/ #define SLSI_PSID_DOT11_TDLS_PEER_UAPSD_BUFFER_STA_ACTIVATED 0x0A1B +/******************************************************************************* + * NAME : UnifiProbeResponseLifetimeP2p + * PSID : 2600 (0x0A28) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * UNITS : ms + * MIN : 0 + * MAX : 65535 + * DEFAULT : 500 + * DESCRIPTION : + * Lifetime of proberesponse frame in unit of ms for P2P. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_PROBE_RESPONSE_LIFETIME_P2P 0x0A28 + +/******************************************************************************* + * NAME : UnifiStaChannelSwitchSlowApActivated + * PSID : 2601 (0x0A29) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * ChanelSwitch: Enable waiting for a slow AP. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_STA_CHANNEL_SWITCH_SLOW_AP_ACTIVATED 0x0A29 + +/******************************************************************************* + * NAME : UnifiStaChannelSwitchSlowApMaxTime + * PSID : 2604 (0x0A2C) + * PER INTERFACE?: NO + * TYPE : SlsiUint32 + * MIN : 0 + * MAX : 4294967295 + * DEFAULT : 70 + * DESCRIPTION : + * ChannelSwitch delay for Slow APs. In Seconds. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_STA_CHANNEL_SWITCH_SLOW_AP_MAX_TIME 0x0A2C + +/******************************************************************************* + * NAME : UnifiStaChannelSwitchSlowApPollInterval + * PSID : 2605 (0x0A2D) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 1 + * DESCRIPTION : + * ChannelSwitch polling interval for Slow APs. In Seconds. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_STA_CHANNEL_SWITCH_SLOW_AP_POLL_INTERVAL 0x0A2D + +/******************************************************************************* + * NAME : UnifiStaChannelSwitchSlowApProcedureTimeoutIncrement + * PSID : 2606 (0x0A2E) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 10 + * DESCRIPTION : + * ChannelSwitch procedure timeout increment for Slow APs. In Seconds. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_STA_CHANNEL_SWITCH_SLOW_AP_PROCEDURE_TIMEOUT_INCREMENT 0x0A2E + +/******************************************************************************* + * NAME : UnifiMlmeScanMaxAerials + * PSID : 2607 (0x0A2F) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 1 + * MAX : 65535 + * DEFAULT : 1 + * DESCRIPTION : + * Limits the number of Aerials that Scan can use. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_MLME_SCAN_MAX_AERIALS 0x0A2F + /******************************************************************************* * NAME : UnifiCsrOnlyMibShield * PSID : 4001 (0x0FA1) @@ -4048,24 +4694,11 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 65535 * DEFAULT : 15 * DESCRIPTION : - * Forces the WAPI encryption hardware use the QoS mask specified. + * Forces the WAPI encryption hardware use the QoS mask specified.This mib + * value will be updated if "unifiRameUpdateMibs" mib is toggled *******************************************************************************/ #define SLSI_PSID_UNIFI_WAPI_QOS_MASK 0x1022 -/******************************************************************************* - * NAME : UnifiRaaMaxSpecTimerMultiplier - * PSID : 4138 (0x102A) - * PER INTERFACE?: NO - * TYPE : SlsiUint16 - * MIN : 0 - * MAX : 65535 - * DEFAULT : 8 - * DESCRIPTION : - * For Rate Adaptation Algorithm. It defines the max number to be multiplied - * to the speculation timer, which usually is 100 ms. - *******************************************************************************/ -#define SLSI_PSID_UNIFI_RAA_MAX_SPEC_TIMER_MULTIPLIER 0x102A - /******************************************************************************* * NAME : UnifiWmmStallEnable * PSID : 4139 (0x102B) @@ -4080,117 +4713,6 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_WMM_STALL_ENABLE 0x102B -/******************************************************************************* - * NAME : UnifiRaaSpeculationInterval - * PSID : 4140 (0x102C) - * PER INTERFACE?: NO - * TYPE : SlsiUint16 - * MIN : 0 - * MAX : 65535 - * DEFAULT : 100 - * DESCRIPTION : - * For Rate Adaptation Algorithm. It defines the repeatable amount of time, - * in ms, that firmware will start to send speculation frames. - *******************************************************************************/ -#define SLSI_PSID_UNIFI_RAA_SPECULATION_INTERVAL 0x102C - -/******************************************************************************* - * NAME : UnifiRaaSpeculationPeriod - * PSID : 4141 (0x102D) - * PER INTERFACE?: NO - * TYPE : SlsiUint16 - * MIN : 0 - * MAX : 65535 - * DEFAULT : 10 - * DESCRIPTION : - * For Rate Adaptation Algorithm. It defines the max amount of time, in ms, - * that firmware will use for sending speculation frames - *******************************************************************************/ -#define SLSI_PSID_UNIFI_RAA_SPECULATION_PERIOD 0x102D - -/******************************************************************************* - * NAME : UnifiRaaNumbSpeculationFrames - * PSID : 4142 (0x102E) - * PER INTERFACE?: NO - * TYPE : SlsiUint16 - * MIN : 0 - * MAX : 65535 - * DEFAULT : 10 - * DESCRIPTION : - * For Rate Adaptation Algorithm. It defines the max amount of speculation - * frames that firmware is allowed to send. - *******************************************************************************/ -#define SLSI_PSID_UNIFI_RAA_NUMB_SPECULATION_FRAMES 0x102E - -/******************************************************************************* - * NAME : UnifiRaaTxSuccessesCount - * PSID : 4143 (0x102F) - * PER INTERFACE?: NO - * TYPE : SlsiUint16 - * MIN : 0 - * MAX : 65535 - * DEFAULT : - * DESCRIPTION : - * For Rate Adaptation Algorithm. It represents the number of transmitted - * frames that were acked at a given rate. - *******************************************************************************/ -#define SLSI_PSID_UNIFI_RAA_TX_SUCCESSES_COUNT 0x102F - -/******************************************************************************* - * NAME : UnifiRaaTxFailuresCount - * PSID : 4144 (0x1030) - * PER INTERFACE?: NO - * TYPE : SlsiUint16 - * MIN : 0 - * MAX : 65535 - * DEFAULT : - * DESCRIPTION : - * For Rate Adaptation Algorithm. It represents the number of transmitted - * frames that were NOT acked at a given rate. - *******************************************************************************/ -#define SLSI_PSID_UNIFI_RAA_TX_FAILURES_COUNT 0x1030 - -/******************************************************************************* - * NAME : UnifiRaaTxPer - * PSID : 4145 (0x1031) - * PER INTERFACE?: NO - * TYPE : SlsiUint16 - * MIN : 0 - * MAX : 65535 - * DEFAULT : - * DESCRIPTION : - * For Rate Adaptation Algorithm. It represents the Packet Error Rate for a - * given rate on the RAA rate stats. - *******************************************************************************/ -#define SLSI_PSID_UNIFI_RAA_TX_PER 0x1031 - -/******************************************************************************* - * NAME : UnifiRaaResetStats - * PSID : 4146 (0x1032) - * PER INTERFACE?: NO - * TYPE : SlsiUint16 - * MIN : 0 - * MAX : 65535 - * DEFAULT : - * DESCRIPTION : - * For Rate Adaptation Algorithm. It Resets the stats table used by the RAA. - *******************************************************************************/ -#define SLSI_PSID_UNIFI_RAA_RESET_STATS 0x1032 - -/******************************************************************************* - * NAME : UnifiRaaTxMtPer - * PSID : 4147 (0x1033) - * PER INTERFACE?: NO - * TYPE : SlsiUint16 - * MIN : 0 - * MAX : 65535 - * DEFAULT : - * DESCRIPTION : - * For Rate Adaptation Algorithm. It represents the Maximum Tolerable Packet - * Error Rate for each rate. - *******************************************************************************/ -#define SLSI_PSID_UNIFI_RAA_TX_MT_PER 0x1033 - /******************************************************************************* * NAME : UnifiRaaTxHostRate * PSID : 4148 (0x1034) @@ -4210,24 +4732,52 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * PSID : 4149 (0x1035) * PER INTERFACE?: NO * TYPE : SlsiUint8 - * MIN : 5 + * MIN : 6 * MAX : 5 - * DEFAULT : {0X03, 0X02, 0X01, 0X00, 0X00} + * DEFAULT : {0X3, 0X2, 0X2, 0X2, 0X1, 0X0} * DESCRIPTION : * Configure the retry distribution for fallback for short frames octet 0 - * Number of retries for starting rate. octet 1 - Number of retries for next * rate. octet 2 - Number of retries for next rate. octet 3 - Number of - * retries for next rate. octet 4 - Number of retries for last rate. If 0 is - * written to an entry then the retries for that rate will be the short - * retry limit minus the sum of the retries for each rate above that entry - * (e.g. 15 - 5). Therefore, this should always be the value for octet 4. - * Also, when the starting rate has short guard enabled, the number of - * retries in octet 1 will be used and for the next rate in the fallback - * table (same MCS value, but with sgi disabled) octet 0 number of retries - * will be used. + * retries for next rate. octet 4 - Number of retries for next rate. octet 5 + * - Number of retries for last rate. If 0 is written to an entry then the + * retries for that rate will be the short retry limit minus the sum of the + * retries for each rate above that entry (e.g. 15 - 5). Therefore, this + * should always be the value for octet 4. Also, when the starting rate has + * short guard enabled, the number of retries in octet 1 will be used and + * for the next rate in the fallback table (same MCS value, but with sgi + * disabled) octet 0 number of retries will be used. *******************************************************************************/ #define SLSI_PSID_UNIFI_FALLBACK_SHORT_FRAME_RETRY_DISTRIBUTION 0x1035 +/******************************************************************************* + * NAME : UnifiRxthroughputlow + * PSID : 4150 (0x1036) + * PER INTERFACE?: NO + * TYPE : SlsiUint32 + * MIN : 0 + * MAX : 4294967295 + * DEFAULT : 100 + * DESCRIPTION : + * Lower threshold for total number of frames received in the system which + * is considered as low load + *******************************************************************************/ +#define SLSI_PSID_UNIFI_RXTHROUGHPUTLOW 0x1036 + +/******************************************************************************* + * NAME : UnifiRxthroughputhigh + * PSID : 4151 (0x1037) + * PER INTERFACE?: NO + * TYPE : SlsiUint32 + * MIN : 0 + * MAX : 4294967295 + * DEFAULT : 1000 + * DESCRIPTION : + * Upper threshold for total number of frames received in the system which + * is considered as high load + *******************************************************************************/ +#define SLSI_PSID_UNIFI_RXTHROUGHPUTHIGH 0x1037 + /******************************************************************************* * NAME : UnifiSetFixedAmpduAggregationSize * PSID : 4152 (0x1038) @@ -4297,6 +4847,71 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_PS_POLL_THRESHOLD 0x1053 +/******************************************************************************* + * NAME : UnifiDebugSvcModeStackHighWaterMark + * PSID : 5010 (0x1392) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Read the SVC mode stack high water mark in bytes + *******************************************************************************/ +#define SLSI_PSID_UNIFI_DEBUG_SVC_MODE_STACK_HIGH_WATER_MARK 0x1392 + +/******************************************************************************* + * NAME : UnifiDebugPreferred2G4Radio + * PSID : 5020 (0x139C) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Specify the preferred radio/MAC/BBBmodem to use for 2G4 operation. Only + * valid for multi-radio platforms. Only used for SISO connections. WARNING: + * Changing this value after system start-up will have no effect. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_DEBUG_PREFERRED2_G4_RADIO 0x139C + +/******************************************************************************* + * NAME : UnifiDebugPreferred5GRadio + * PSID : 5021 (0x139D) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 1 + * DESCRIPTION : + * Specify the preferred radio/MAC/BBBmodem to use for 5G operation. Only + * valid for multi-radio platforms. Only used for SISO connections. WARNING: + * Changing this value after system start-up will have no effect. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_DEBUG_PREFERRED5_GRADIO 0x139D + +/******************************************************************************* + * NAME : UnifiPanicSubSystemControl + * PSID : 5026 (0x13A2) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * PANIC levels for WLAN SubSystems. Panic level is used to filter Panic + * sent to the host. 4 levels of Panic per subsystem are available + * (FAILURE_LEVEL_T): a. 0 FATAL - Always reported to host b. 1 ERROR c. 2 + * WARNING d. 3 DEBUG NOTE: If Panic level of a subsystem is configured to + * FATAL, all the Panics within that subsystem configured to FATAL will be + * effective, panics with ERROR, WARNING and Debug level will be converted + * to faults. If Panic level of a subsystem is configured to WARNING, all + * the panics within that subsystem configured to FATAL, ERROR and WARNING + * will be issued to host, panics with Debug level will be converted to + * faults. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_PANIC_SUB_SYSTEM_CONTROL 0x13A2 + /******************************************************************************* * NAME : UnifiFaultEnable * PSID : 5027 (0x13A3) @@ -4319,17 +4934,18 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 65535 * DEFAULT : * DESCRIPTION : - * Fault Module levels for all SubSystems. Fault level is used to filter - * faults sent to the host. 4 levels of faults per subsystem are available: - * a. 0 ERROR b. 1 WARNING c. 2 INFO_1 d. 3 INFO_2 Modifying Fault Levels at - * run time: 1. Set the fault level for the desired subsystem in - * unifiFaultConfigTable 2. Set unifiFaultEnable NOTE: If fault level of a - * subsystem is configured to ERROR, all the faults within that subsystem - * configured to ERROR will only be issued to host, faults with WARNING, - * INFO_1 and INFO_2 level will be converted to debug message If fault level - * of a subsystem is configured to WARNING, all the faults within that - * subsystem configured to ERROR and WARNING will be issued to host, faults - * with INFO_1 and INFO_2 level will be converted to debug message + * Fault levels for WLAN SubSystems. Fault level is used to filter faults + * sent to the host. 4 levels of faults per subsystem are available + * (FAILURE_LEVEL_T): a. 0 ERROR b. 1 WARNING c. 2 INFO_1 d. 3 INFO_2 + * Modifying Fault Levels at run time: 1. Set the fault level for the + * subsystems in unifiFaultConfigTable 2. Set unifiFaultEnable NOTE: If + * fault level of a subsystem is configured to ERROR, all the faults within + * that subsystem configured to ERROR will only be issued to host, faults + * with WARNING, INFO_1 and INFO_2 level will be converted to debug message + * If fault level of a subsystem is configured to WARNING, all the faults + * within that subsystem configured to ERROR and WARNING will be issued to + * host, faults with INFO_1 and INFO_2 level will be converted to debug + * message *******************************************************************************/ #define SLSI_PSID_UNIFI_FAULT_SUB_SYSTEM_CONTROL 0x13A4 @@ -4351,9 +4967,9 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * time required. Only used in emergency debugging. Additional control for * FSM transition and FSM signals logging is provided. Debug module level * and 2 boolean flags are encoded within a uint16: Function | Is sending - * FSM signals | Is sending FSM transitions | Reseved | Module level (signed - * int) - * -_-_-_-_-_+-_-_-_-_-_-_-_-_-_-_-_-_-_+-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_+-_-_-_-_-_-+-_-_-_-_-_-_-_-_-_-_-_-_-_-_ Bits | 15 | 14 | 13 - 8 | 7 - 0 Note: 0x00FF disables any debug for a module 0xC004 enables all debug for a module + * FSM signals | Is sending FSM transitions | Is sending FSM Timers | + * Reserved | Module level (signed int) + * -_-_-_-_-_+-_-_-_-_-_-_-_-_-_-_-_-_-_+-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_+-_-_-_-_-_-_-_-_-_-_-_-_-_+-_-_-_-_-_-_+-_-_-_-_-_-_-_-_-_-_-_-_-_- Bits | 15 | 14 | 13 | 12 - 8 | 7 - 0 Note: 0x00FF disables any debug for a module 0xE004 enables all debug for a module *******************************************************************************/ #define SLSI_PSID_UNIFI_DEBUG_MODULE_CONTROL 0x13A5 @@ -4544,7 +5160,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf #define SLSI_PSID_UNIFI_TX_SG_I160_ENABLED 0x13B3 /******************************************************************************* - * NAME : UnifiMacAddressRandomisation + * NAME : UnifiMacAddressRandomisationActivated * PSID : 5044 (0x13B4) * PER INTERFACE?: NO * TYPE : SlsiBool @@ -4554,37 +5170,23 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * DESCRIPTION : * Mac Address Randomisation should be applied for Probe Requests. *******************************************************************************/ -#define SLSI_PSID_UNIFI_MAC_ADDRESS_RANDOMISATION 0x13B4 +#define SLSI_PSID_UNIFI_MAC_ADDRESS_RANDOMISATION_ACTIVATED 0x13B4 +/* TDB: Auto generate to add this */ +#define SLSI_PSID_UNIFI_MAC_ADDRESS_RANDOMISATION_MASK 0x13B7 /******************************************************************************* - * NAME : UnifiSuBeamformerEnabled - * PSID : 5045 (0x13B5) + * NAME : UnifiRfTestModeEnabled + * PSID : 5054 (0x13BE) * PER INTERFACE?: NO * TYPE : SlsiBool * MIN : 0 * MAX : 1 * DEFAULT : FALSE * DESCRIPTION : - * SU Beamformer will be used, for transmit only. If disabled, chip will not - * use SU Beamformer even if peer supports it. To advertise SU Beamformee - * capability, enable bit 12 of unifiVhtCapabilities. + * Set to true when running in RF Test mode. Setting this MIB key to true + * prevents setting mandatory HT MCS Rates. *******************************************************************************/ -#define SLSI_PSID_UNIFI_SU_BEAMFORMER_ENABLED 0x13B5 - -/******************************************************************************* - * NAME : UnifiMuBeamformerEnabled - * PSID : 5046 (0x13B6) - * PER INTERFACE?: NO - * TYPE : SlsiBool - * MIN : 0 - * MAX : 1 - * DEFAULT : FALSE - * DESCRIPTION : - * MU Beamformer will be used, for transmit only. If disabled, chip will not - * use MU Beamformer even if peer supports it. To advertise MU Beamformee - * capability, enable bit 20 of unifiVhtCapabilities. - *******************************************************************************/ -#define SLSI_PSID_UNIFI_MU_BEAMFORMER_ENABLED 0x13B6 +#define SLSI_PSID_UNIFI_RF_TEST_MODE_ENABLED 0x13BE /******************************************************************************* * NAME : UnifiTxPowerDetectorResponse @@ -4692,296 +5294,561 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 32767 * DEFAULT : * DESCRIPTION : - * Read the chip temperature as seen by WLAN radio firmware. + * Read the chip temperature as seen by WLAN radio firmware. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_CHIP_TEMPERATURE 0x13C6 + +/******************************************************************************* + * NAME : UnifiBatteryVoltage + * PSID : 5063 (0x13C7) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * UNITS : millivolt + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Battery voltage + *******************************************************************************/ +#define SLSI_PSID_UNIFI_BATTERY_VOLTAGE 0x13C7 + +/******************************************************************************* + * NAME : UnifiTxOobConstraints + * PSID : 5064 (0x13C8) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 0 + * MAX : 255 + * DEFAULT : + * DESCRIPTION : + * OOB constraints table. | octects | description | + * |-_-_-_-_-+-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-| | 0 | DPD applicability bitmask: 0 = no DPD, 1 = dynamic DPD, 2 = static DPD, 3 = applies to both static and dynamic DPD | | 1-2 | Bitmask indicating which regulatory domains this rule applies to FCC=bit0, ETSI=bit1, JAPAN=bit2 | | 3-4 | Bitmask indicating which band edges this rule applies to RICE_BAND_EDGE_ISM_24G_LOWER = bit 0, RICE_BAND_EDGE_ISM_24G_UPPER = bit 1, RICE_BAND_EDGE_U_NII_1_LOWER = bit 2, RICE_BAND_EDGE_U_NII_1_UPPER = bit 3, RICE_BAND_EDGE_U_NII_2_LOWER = bit 4, RICE_BAND_EDGE_U_NII_2_UPPER = bit 5, RICE_BAND_EDGE_U_NII_2E_LOWER = bit 6, RICE_BAND_EDGE_U_NII_2E_UPPER = bit 7, RICE_BAND_EDGE_U_NII_3_LOWER = bit 8, RICE_BAND_EDGE_U_NII_3_UPPER = bit 9 | | 5 | Bitmask indicating which modulation types this rule applies to (LSB/b0=DSSS/CCK, b1= OFDM0 modulation group, b2= OFDM1 modulation group) | | 6 | Bitmask indicating which channel bandwidths this rule applies to (LSB/b0=20MHz, b1=40MHz, b2=80MHz) | | 7 | Minimum distance to nearest band edge in 500 kHz units for which this constraint becomes is applicable. | | 8 | Maximum power (EIRP) for this particular constraint - specified in units of quarter dBm. | | 9-32 | Spectral shaping configuration to be used for this particular constraint. The value is specific to the radio hardware and should only be altered under advice from the IC supplier. | | 33-56| Tx DPD Spectral shaping configuration to be used for this particular constraint. The value is specific to the radio hardware and should only be altered under advice from the IC supplier. | | + *******************************************************************************/ +#define SLSI_PSID_UNIFI_TX_OOB_CONSTRAINTS 0x13C8 + +/******************************************************************************* + * NAME : UnifiTxPaGainDpdTemperatureCompensation + * PSID : 5066 (0x13CA) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 0 + * MAX : 255 + * DEFAULT : + * DESCRIPTION : + * Hardware specific transmitter PA gain for DPD temperature compensation + * settings. 2G settings before 5G. Increasing order within band. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_TX_PA_GAIN_DPD_TEMPERATURE_COMPENSATION 0x13CA + +/******************************************************************************* + * NAME : UnifiTxPaGainDpdFrequencyCompensation + * PSID : 5067 (0x13CB) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 0 + * MAX : 255 + * DEFAULT : + * DESCRIPTION : + * Hardware specific transmitter PA gain for DPD frequency compensation + * settings. 2G settings before 5G. Increasing order within band. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_TX_PA_GAIN_DPD_FREQUENCY_COMPENSATION 0x13CB + +/******************************************************************************* + * NAME : UnifiTxPowerTrimConfig + * PSID : 5072 (0x13D0) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 25 + * MAX : 25 + * DEFAULT : + * DESCRIPTION : + * Hardware specific transmitter power trim settings + *******************************************************************************/ +#define SLSI_PSID_UNIFI_TX_POWER_TRIM_CONFIG 0x13D0 + +/******************************************************************************* + * NAME : UnifiForceShortSlotTime + * PSID : 5080 (0x13D8) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * If set to true, forces FW to use short slot times for all VIFs. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_FORCE_SHORT_SLOT_TIME 0x13D8 + +/******************************************************************************* + * NAME : UnifiTxGainStepSettings + * PSID : 5081 (0x13D9) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 0 + * MAX : 255 + * DEFAULT : + * DESCRIPTION : + * Hardware specific transmitter gain step settings. 2G settings before 5G. + * Increasing order within band. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_TX_GAIN_STEP_SETTINGS 0x13D9 + +/******************************************************************************* + * NAME : UnifiDebugDisableRadioNannyActions + * PSID : 5082 (0x13DA) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Bitmap to disable the radio nanny actions. B0==radio 0, B1==radio 1 + *******************************************************************************/ +#define SLSI_PSID_UNIFI_DEBUG_DISABLE_RADIO_NANNY_ACTIONS 0x13DA + +/******************************************************************************* + * NAME : UnifiRxCckModemSensitivity + * PSID : 5083 (0x13DB) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 6 + * MAX : 6 + * DEFAULT : + * DESCRIPTION : + * Specify values of CCK modem sensitivity for scan, normal and low + * sensitivity. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_RX_CCK_MODEM_SENSITIVITY 0x13DB + +/******************************************************************************* + * NAME : UnifiDpdPerBandwidth + * PSID : 5084 (0x13DC) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 63 + * DESCRIPTION : + * Bitmask to enable Digital Pre-Distortion per bandwidth + *******************************************************************************/ +#define SLSI_PSID_UNIFI_DPD_PER_BANDWIDTH 0x13DC + +/******************************************************************************* + * NAME : UnifiBbVersion + * PSID : 5085 (0x13DD) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Baseband chip version number determined by reading BBIC version + *******************************************************************************/ +#define SLSI_PSID_UNIFI_BB_VERSION 0x13DD + +/******************************************************************************* + * NAME : UnifiRfVersion + * PSID : 5086 (0x13DE) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * RF chip version number determined by reading RFIC version + *******************************************************************************/ +#define SLSI_PSID_UNIFI_RF_VERSION 0x13DE + +/******************************************************************************* + * NAME : UnifiReadHardwareCounter + * PSID : 5087 (0x13DF) + * PER INTERFACE?: NO + * TYPE : SlsiUint32 + * MIN : 0 + * MAX : 4294967295 + * DEFAULT : + * DESCRIPTION : + * Read a value from a hardware packet counter for a specific radio_id and + * return it. The firmware will convert the radio_id to the associated + * mac_instance. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_READ_HARDWARE_COUNTER 0x13DF + +/******************************************************************************* + * NAME : UnifiClearRadioTrimCache + * PSID : 5088 (0x13E0) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Clears the radio trim cache. The parameter is ignored. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_CLEAR_RADIO_TRIM_CACHE 0x13E0 + +/******************************************************************************* + * NAME : UnifiRadioTxSettingsRead + * PSID : 5089 (0x13E1) + * PER INTERFACE?: NO + * TYPE : SlsiUint32 + * MIN : 0 + * MAX : 4294967295 + * DEFAULT : + * DESCRIPTION : + * Read value from Tx settings. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_RADIO_TX_SETTINGS_READ 0x13E1 + +/******************************************************************************* + * NAME : UnifiModemSgiOffset + * PSID : 5090 (0x13E2) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Overwrite SGI sampling offset. Indexed by Band and Bandwidth. Defaults + * currently defined in fw. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_MODEM_SGI_OFFSET 0x13E2 + +/******************************************************************************* + * NAME : UnifiRadioTxPowerOverride + * PSID : 5091 (0x13E3) + * PER INTERFACE?: NO + * TYPE : SlsiInt16 + * MIN : -128 + * MAX : 127 + * DEFAULT : + * DESCRIPTION : + * Option in radio code to override the power requested by the upper layer + *******************************************************************************/ +#define SLSI_PSID_UNIFI_RADIO_TX_POWER_OVERRIDE 0x13E3 + +/******************************************************************************* + * NAME : UnifiRxRadioCsMode + * PSID : 5092 (0x13E4) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * OBSOLETE. Configures RX Radio CS detection for 80MHz bandwidth. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_RX_RADIO_CS_MODE 0x13E4 + +/******************************************************************************* + * NAME : UnifiRxPriEnergyDetThreshold + * PSID : 5093 (0x13E5) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * OBSOLETE. Energy detection threshold for primary 20MHz channel. *******************************************************************************/ -#define SLSI_PSID_UNIFI_CHIP_TEMPERATURE 0x13C6 +#define SLSI_PSID_UNIFI_RX_PRI_ENERGY_DET_THRESHOLD 0x13E5 /******************************************************************************* - * NAME : UnifiBatteryVoltage - * PSID : 5063 (0x13C7) + * NAME : UnifiRxSecEnergyDetThreshold + * PSID : 5094 (0x13E6) * PER INTERFACE?: NO * TYPE : SlsiUint16 - * UNITS : millivolt * MIN : 0 * MAX : 65535 * DEFAULT : * DESCRIPTION : - * Battery voltage + * OBSOLETE. Energy detection threshold for secondary 20MHz channel. *******************************************************************************/ -#define SLSI_PSID_UNIFI_BATTERY_VOLTAGE 0x13C7 +#define SLSI_PSID_UNIFI_RX_SEC_ENERGY_DET_THRESHOLD 0x13E6 /******************************************************************************* - * NAME : UnifiTxOobConstraints - * PSID : 5064 (0x13C8) + * NAME : UnifiAgcThresholds + * PSID : 5095 (0x13E7) * PER INTERFACE?: NO * TYPE : SlsiUint8 * MIN : 0 * MAX : 255 * DEFAULT : * DESCRIPTION : - * OOB constraints table. | octects | description | - * |-_-_-_-_-+-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-| | 0 | DPD applicability bitmask: 0 = no DPD, 1 = dynamic DPD, 2 = static DPD, 3 = applies to both static and dynamic DPD | | 1-2 | Bitmask indicating which regulatory domains this rule applies to FCC=bit0, ETSI=bit1, JAPAN=bit2 | | 3-4 | Bitmask indicating which band edges this rule applies to RICE_BAND_EDGE_ISM_24G_LOWER = bit 0, RICE_BAND_EDGE_ISM_24G_UPPER = bit 1, RICE_BAND_EDGE_U_NII_1_LOWER = bit 2, RICE_BAND_EDGE_U_NII_1_UPPER = bit 3, RICE_BAND_EDGE_U_NII_2_LOWER = bit 4, RICE_BAND_EDGE_U_NII_2_UPPER = bit 5, RICE_BAND_EDGE_U_NII_2E_LOWER = bit 6, RICE_BAND_EDGE_U_NII_2E_UPPER = bit 7, RICE_BAND_EDGE_U_NII_3_LOWER = bit 8, RICE_BAND_EDGE_U_NII_3_UPPER = bit 9 | | 5 | Bitmask indicating which modulation types this rule applies to (LSB/b0=DSSS/CCK, b1= OFDM0 modulation group, b2= OFDM1 modulation group) | | 6 | Bitmask indicating which channel bandwidths this rule applies to (LSB/b0=20MHz, b1=40MHz, b2=80MHz) | | 7 | Minimum distance to nearest band edge in 500 kHz units for which this constraint becomes is applicable. | | 8 | Maximum power (EIRP) for this particular constraint - specified in units of quarter dBm. | | 9-32 | Spectral shaping configuration to be used for this particular constraint. The value is specific to the radio hardware and should only be altered under advice from the IC supplier. | | + * AGC Thresholds settings *******************************************************************************/ -#define SLSI_PSID_UNIFI_TX_OOB_CONSTRAINTS 0x13C8 +#define SLSI_PSID_UNIFI_AGC_THRESHOLDS 0x13E7 /******************************************************************************* - * NAME : UnifiTxPaGainDpdTemperatureCompensation - * PSID : 5066 (0x13CA) + * NAME : UnifiRadioRxSettingsRead + * PSID : 5096 (0x13E8) * PER INTERFACE?: NO * TYPE : SlsiUint8 * MIN : 0 - * MAX : 255 + * MAX : 65535 * DEFAULT : * DESCRIPTION : - * Hardware specific transmitter PA gain for DPD temperature compensation - * settings. 2G settings before 5G. Increasing order within band. + * Read value from Rx settings. *******************************************************************************/ -#define SLSI_PSID_UNIFI_TX_PA_GAIN_DPD_TEMPERATURE_COMPENSATION 0x13CA +#define SLSI_PSID_UNIFI_RADIO_RX_SETTINGS_READ 0x13E8 /******************************************************************************* - * NAME : UnifiTxPaGainDpdFrequencyCompensation - * PSID : 5067 (0x13CB) + * NAME : UnifiStaticDpdGain + * PSID : 5097 (0x13E9) * PER INTERFACE?: NO * TYPE : SlsiUint8 - * MIN : 0 - * MAX : 255 + * MIN : 11 + * MAX : 27 * DEFAULT : * DESCRIPTION : - * Hardware specific transmitter PA gain for DPD frequency compensation - * settings. 2G settings before 5G. Increasing order within band. + * Specify modulation specifc gains for static dpd optimisation. *******************************************************************************/ -#define SLSI_PSID_UNIFI_TX_PA_GAIN_DPD_FREQUENCY_COMPENSATION 0x13CB +#define SLSI_PSID_UNIFI_STATIC_DPD_GAIN 0x13E9 /******************************************************************************* - * NAME : UnifiTxPowerTrimConfig - * PSID : 5072 (0x13D0) + * NAME : UnifiIqBufferSize + * PSID : 5098 (0x13EA) * PER INTERFACE?: NO - * TYPE : SlsiUint8 - * MIN : 21 - * MAX : 21 + * TYPE : SlsiUint32 + * MIN : 0 + * MAX : 4294967295 * DEFAULT : * DESCRIPTION : - * Configuration settings for the TX power trim. The format is [band, - * pcal_ofdm0_to_cck_mso, pcal_ofdm0_to_cck_lso, pcal_ofdm0_to_ofdm1_mso, - * pcal_ofdm0_to_ofdm1_lso, pcal_20_to_80_mso, pcal_20_to_80_lso, - * pcal_20_to_40_mso, pcal_20_to_40_lso, psat_v2i_gain, psat_mix_gain, - * psat_drv_gain, psat_pa_gain, psat_power_ref_mso, psat_power_ref_lso, - * psat_drv_bias, psat_pa_bias, max_adjust_up_mso, max_adjust_up_lso, - * max_adjust_down_mso, max_adjust_down_lso]. + * Buffer Size for IQ capture to allow CATs to read it. *******************************************************************************/ -#define SLSI_PSID_UNIFI_TX_POWER_TRIM_CONFIG 0x13D0 +#define SLSI_PSID_UNIFI_IQ_BUFFER_SIZE 0x13EA /******************************************************************************* - * NAME : UnifiForceShortSlotTime - * PSID : 5080 (0x13D8) + * NAME : UnifiNarrowbandCcaThresholds + * PSID : 5099 (0x13EB) * PER INTERFACE?: NO - * TYPE : SlsiBool + * TYPE : SlsiUint8 * MIN : 0 - * MAX : 1 - * DEFAULT : FALSE + * MAX : 255 + * DEFAULT : * DESCRIPTION : - * If set to true, forces FW to use short slot times for all VIFs. + * The narrowband CCA ED thresholds so that the CCA-ED triggers at the + * regulatory value of -62 dBm. *******************************************************************************/ -#define SLSI_PSID_UNIFI_FORCE_SHORT_SLOT_TIME 0x13D8 +#define SLSI_PSID_UNIFI_NARROWBAND_CCA_THRESHOLDS 0x13EB /******************************************************************************* - * NAME : UnifiTxGainStepSettings - * PSID : 5081 (0x13D9) + * NAME : UnifiRadioCcaDebug + * PSID : 5100 (0x13EC) * PER INTERFACE?: NO - * TYPE : SlsiUint8 + * TYPE : SlsiUint32 * MIN : 0 - * MAX : 255 + * MAX : 4294967295 * DEFAULT : * DESCRIPTION : - * Hardware specific transmitter gain step settings. 2G settings before 5G. - * Increasing order within band. + * Read values from Radio CCA settings. *******************************************************************************/ -#define SLSI_PSID_UNIFI_TX_GAIN_STEP_SETTINGS 0x13D9 +#define SLSI_PSID_UNIFI_RADIO_CCA_DEBUG 0x13EC /******************************************************************************* - * NAME : UnifiDebugDisableRadioNannyActions - * PSID : 5082 (0x13DA) + * NAME : UnifiCcacsThresh + * PSID : 5101 (0x13ED) * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 * MAX : 65535 * DEFAULT : * DESCRIPTION : - * Bitmap to disable the radio nanny actions. B0==radio 0, B1==radio 1 + * Configures CCA CS thresholds. *******************************************************************************/ -#define SLSI_PSID_UNIFI_DEBUG_DISABLE_RADIO_NANNY_ACTIONS 0x13DA +#define SLSI_PSID_UNIFI_CCACS_THRESH 0x13ED /******************************************************************************* - * NAME : UnifiRxCckModemSensitivity - * PSID : 5083 (0x13DB) + * NAME : UnifiCcaMasterSwitch + * PSID : 5102 (0x13EE) * PER INTERFACE?: NO - * TYPE : SlsiUint8 - * MIN : 6 - * MAX : 6 + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 * DEFAULT : * DESCRIPTION : - * Specify values of CCK modem sensitivity for scan, normal and low - * sensitivity. + * Enables CCA *******************************************************************************/ -#define SLSI_PSID_UNIFI_RX_CCK_MODEM_SENSITIVITY 0x13DB +#define SLSI_PSID_UNIFI_CCA_MASTER_SWITCH 0x13EE /******************************************************************************* - * NAME : UnifiDpdPerBandwidth - * PSID : 5084 (0x13DC) + * NAME : UnifiRxSyncCcaCfg + * PSID : 5103 (0x13EF) * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 * MAX : 65535 - * DEFAULT : 63 + * DEFAULT : * DESCRIPTION : - * Bitmask to enable Digital Pre-Distortion per bandwidth + * Configures CCA per 20 MHz sub-band. *******************************************************************************/ -#define SLSI_PSID_UNIFI_DPD_PER_BANDWIDTH 0x13DC +#define SLSI_PSID_UNIFI_RX_SYNC_CCA_CFG 0x13EF /******************************************************************************* - * NAME : UnifiBbVersion - * PSID : 5085 (0x13DD) + * NAME : UnifiMacCcaBusyTime + * PSID : 5104 (0x13F0) * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 * MAX : 65535 * DEFAULT : * DESCRIPTION : - * Baseband chip version number determined by reading BBIC version + * Counts the time CCA indicates busy *******************************************************************************/ -#define SLSI_PSID_UNIFI_BB_VERSION 0x13DD +#define SLSI_PSID_UNIFI_MAC_CCA_BUSY_TIME 0x13F0 /******************************************************************************* - * NAME : UnifiRfVersion - * PSID : 5086 (0x13DE) + * NAME : UnifiMacSecChanClearTime + * PSID : 5105 (0x13F1) * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 * MAX : 65535 * DEFAULT : * DESCRIPTION : - * RF chip version number determined by reading RFIC version + * Configures PIFS *******************************************************************************/ -#define SLSI_PSID_UNIFI_RF_VERSION 0x13DE +#define SLSI_PSID_UNIFI_MAC_SEC_CHAN_CLEAR_TIME 0x13F1 /******************************************************************************* - * NAME : UnifiReadHardwareCounter - * PSID : 5087 (0x13DF) + * NAME : UnifiDpdDebug + * PSID : 5106 (0x13F2) * PER INTERFACE?: NO * TYPE : SlsiUint32 * MIN : 0 * MAX : 4294967295 * DEFAULT : * DESCRIPTION : - * Read a value from a hardware packet counter in a specific mac instance - * and return it. + * Debug MIBs for DPD *******************************************************************************/ -#define SLSI_PSID_UNIFI_READ_HARDWARE_COUNTER 0x13DF +#define SLSI_PSID_UNIFI_DPD_DEBUG 0x13F2 /******************************************************************************* - * NAME : UnifiClearRadioTrimCache - * PSID : 5088 (0x13E0) + * NAME : UnifiNarrowbandCcaDebug + * PSID : 5107 (0x13F3) * PER INTERFACE?: NO - * TYPE : SlsiUint16 + * TYPE : SlsiUint32 * MIN : 0 - * MAX : 65535 + * MAX : 4294967295 * DEFAULT : * DESCRIPTION : - * Clears the radio trim cache. The parameter is ignored. + * Read values from Radio CCA settings. *******************************************************************************/ -#define SLSI_PSID_UNIFI_CLEAR_RADIO_TRIM_CACHE 0x13E0 +#define SLSI_PSID_UNIFI_NARROWBAND_CCA_DEBUG 0x13F3 /******************************************************************************* - * NAME : UnifiRadioTxSettingsRead - * PSID : 5089 (0x13E1) + * NAME : UnifiRttCapabilities + * PSID : 5300 (0x14B4) * PER INTERFACE?: NO - * TYPE : SlsiUint32 - * MIN : 0 - * MAX : 4294967295 - * DEFAULT : + * TYPE : SlsiUint8 + * MIN : 8 + * MAX : 8 + * DEFAULT : { 0X01, 0X01, 0X01, 0X01, 0X00, 0X07, 0X1C, 0X32 } * DESCRIPTION : - * Read value from Tx settings. + * RTT capabilities of the chip. see SC-506960-SW. *******************************************************************************/ -#define SLSI_PSID_UNIFI_RADIO_TX_SETTINGS_READ 0x13E1 +#define SLSI_PSID_UNIFI_RTT_CAPABILITIES 0x14B4 /******************************************************************************* - * NAME : UnifiModemSgiOffset - * PSID : 5090 (0x13E2) + * NAME : UnifiMinDeltaFtm + * PSID : 5301 (0x14B5) * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 * MAX : 65535 - * DEFAULT : + * DEFAULT : 5 * DESCRIPTION : - * Overwrite SGI sampling offset. Indexed by Band and Bandwidth. Defaults - * currently defined in fw. + * Indicates the default minimum time between consecutive FTM frames in + * units of 100 us *******************************************************************************/ -#define SLSI_PSID_UNIFI_MODEM_SGI_OFFSET 0x13E2 +#define SLSI_PSID_UNIFI_MIN_DELTA_FTM 0x14B5 /******************************************************************************* - * NAME : UnifiRadioTxPowerOverride - * PSID : 5091 (0x13E3) + * NAME : UnifiFtmPerBurst + * PSID : 5302 (0x14B6) * PER INTERFACE?: NO - * TYPE : SlsiInt16 - * MIN : -128 - * MAX : 127 - * DEFAULT : + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 4 * DESCRIPTION : - * Option in radio code to override the power requested by the upper layer + * indicates how many successfully transmitted FTM frames are requested per + * burst instance *******************************************************************************/ -#define SLSI_PSID_UNIFI_RADIO_TX_POWER_OVERRIDE 0x13E3 +#define SLSI_PSID_UNIFI_FTM_PER_BURST 0x14B6 /******************************************************************************* - * NAME : UnifiRxRadioCsMode - * PSID : 5092 (0x13E4) + * NAME : UnifiFtmBurstDuration + * PSID : 5303 (0x14B7) * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 * MAX : 65535 - * DEFAULT : + * DEFAULT : 6 * DESCRIPTION : - * Configures RX Radio CS detection for 80MHz bandwidth. + * indicates the duration of a burst instance, values 0, 1, 12-14 are + * reserved, [2..11], the burst duration is defined as (250 x 2)^(N-2), and + * 15 means "no preference" *******************************************************************************/ -#define SLSI_PSID_UNIFI_RX_RADIO_CS_MODE 0x13E4 +#define SLSI_PSID_UNIFI_FTM_BURST_DURATION 0x14B7 /******************************************************************************* - * NAME : UnifiRxPriEnergyDetThreshold - * PSID : 5093 (0x13E5) + * NAME : UnifiNumOfBurstsExponent + * PSID : 5304 (0x14B8) * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 * MAX : 65535 * DEFAULT : * DESCRIPTION : - * Energy detection threshold for primary 20MHz channel. + * the number of burst instances is 2^(Number of Bursts Exponent), value 15 + * means "no preference" *******************************************************************************/ -#define SLSI_PSID_UNIFI_RX_PRI_ENERGY_DET_THRESHOLD 0x13E5 +#define SLSI_PSID_UNIFI_NUM_OF_BURSTS_EXPONENT 0x14B8 /******************************************************************************* - * NAME : UnifiRxSecEnergyDetThreshold - * PSID : 5094 (0x13E6) + * NAME : UnifiAsapModeEnabled + * PSID : 5305 (0x14B9) * PER INTERFACE?: NO - * TYPE : SlsiUint16 + * TYPE : SlsiBool * MIN : 0 - * MAX : 65535 - * DEFAULT : + * MAX : 1 + * DEFAULT : 1 * DESCRIPTION : - * Energy detection threshold for secondary 20MHz channel. + * Enable support for ASAP mode in FTM *******************************************************************************/ -#define SLSI_PSID_UNIFI_RX_SEC_ENERGY_DET_THRESHOLD 0x13E6 +#define SLSI_PSID_UNIFI_ASAP_MODE_ENABLED 0x14B9 /******************************************************************************* - * NAME : UnifiAgcThresholds - * PSID : 5095 (0x13E7) + * NAME : UnifiTpcMinPower2Gmimo + * PSID : 6011 (0x177B) * PER INTERFACE?: NO - * TYPE : SlsiUint8 - * MIN : 0 - * MAX : 255 - * DEFAULT : + * TYPE : SlsiInt16 + * MIN : -32768 + * MAX : 32767 + * DEFAULT : 52 * DESCRIPTION : - * AGC Thresholds settings + * Minimum power for 2.4GHz MIMO interface when RSSI is above + * unifiTPCMinPowerRSSIThreshold (quarter dbm). Should be greater than + * dot11PowerCapabilityMinImplemented. *******************************************************************************/ -#define SLSI_PSID_UNIFI_AGC_THRESHOLDS 0x13E7 +#define SLSI_PSID_UNIFI_TPC_MIN_POWER2_GMIMO 0x177B + +/******************************************************************************* + * NAME : UnifiTpcMinPower5Gmimo + * PSID : 6012 (0x177C) + * PER INTERFACE?: NO + * TYPE : SlsiInt16 + * MIN : -32768 + * MAX : 32767 + * DEFAULT : 52 + * DESCRIPTION : + * Minimum power for 5 GHz MIMO interface when RSSI is above + * unifiTPCMinPowerRSSIThreshold (quarter dbm). Should be greater than + * dot11PowerCapabilityMinImplemented. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_TPC_MIN_POWER5_GMIMO 0x177C /******************************************************************************* * NAME : UnifiLnaControlEnabled @@ -5106,7 +5973,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 32767 * DEFAULT : 52 * DESCRIPTION : - * Minimum power for 2.4GHz interface when RSSI is above + * Minimum power for 2.4GHz SISO interface when RSSI is above * unifiTPCMinPowerRSSIThreshold (quarter dbm). Should be greater than * dot11PowerCapabilityMinImplemented. *******************************************************************************/ @@ -5121,7 +5988,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 32767 * DEFAULT : 40 * DESCRIPTION : - * Minimum power for 5 GHz interface when RSSI is above + * Minimum power for 5 GHz SISO interface when RSSI is above * unifiTPCMinPowerRSSIThreshold (quarter dbm). Should be greater than * dot11PowerCapabilityMinImplemented. *******************************************************************************/ @@ -5136,10 +6003,25 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 32767 * DEFAULT : * DESCRIPTION : - * Max power values per Band (quarter dBm). + * Max power values per band per index(quarter dBm). *******************************************************************************/ #define SLSI_PSID_UNIFI_SAR_BACKOFF 0x178A +/******************************************************************************* + * NAME : UnifiTpcUseAfterConnectRsp + * PSID : 6027 (0x178B) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : TRUE + * DESCRIPTION : + * Use TPC only after MlmeConnect_Rsp has been received from the Host i.e. + * not during initial connection exchanges (EAPOL/DHCP operation) as RSSI + * readings might be inaccurate. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_TPC_USE_AFTER_CONNECT_RSP 0x178B + /******************************************************************************* * NAME : UnifiRadioLpRxRssiThresholdLower * PSID : 6028 (0x178C) @@ -5175,31 +6057,61 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf #define SLSI_PSID_UNIFI_RADIO_LP_RX_RSSI_THRESHOLD_UPPER 0x178D /******************************************************************************* - * NAME : UnifiGripCap - * PSID : 6031 (0x178F) + * NAME : UnifiTestTxPowerEnable + * PSID : 6032 (0x1790) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 0XFFFF + * DESCRIPTION : + * Bitfield to enable Control Plane Tx Power processing. MLME/Macrame use + * only. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_TEST_TX_POWER_ENABLE 0x1790 + +/******************************************************************************* + * NAME : UnifiLteCoexMaxPowerRssiThreshold + * PSID : 6033 (0x1791) * PER INTERFACE?: NO * TYPE : SlsiInt16 * MIN : -32768 * MAX : 32767 - * DEFAULT : + * DEFAULT : -55 * DESCRIPTION : - * Max power values per Band (quarter dBm). + * Below this (dBm) threshold, switch to max power allowed by regulatory. If + * it has been previously reduced due to unifiTPCMinPowerRSSIThreshold. *******************************************************************************/ -#define SLSI_PSID_UNIFI_GRIP_CAP 0x178F +#define SLSI_PSID_UNIFI_LTE_COEX_MAX_POWER_RSSI_THRESHOLD 0x1791 /******************************************************************************* - * NAME : UnifiTestTxPowerEnable - * PSID : 6032 (0x1790) + * NAME : UnifiLteCoexMinPowerRssiThreshold + * PSID : 6034 (0x1792) + * PER INTERFACE?: NO + * TYPE : SlsiInt16 + * MIN : -32768 + * MAX : 32767 + * DEFAULT : -45 + * DESCRIPTION : + * Above this(dBm) threshold, switch to minimum hardware supported - capped + * by unifiTPCMinPower2G/unifiTPCMinPower5G. A Zero value reverts the power + * to a default state. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LTE_COEX_MIN_POWER_RSSI_THRESHOLD 0x1792 + +/******************************************************************************* + * NAME : UnifiLteCoexPowerReduction + * PSID : 6035 (0x1793) * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 - * MAX : 65535 - * DEFAULT : 0XFF + * MAX : 127 + * DEFAULT : 24 * DESCRIPTION : - * Bitfield to enable Control Plane Tx Power processing. MLME/Macrame use - * only. + * When LTE Coex Power Reduction provisions are met, impose a power cap of + * the regulatory domain less the amount specified by this MIB (quarter dB) *******************************************************************************/ -#define SLSI_PSID_UNIFI_TEST_TX_POWER_ENABLE 0x1790 +#define SLSI_PSID_UNIFI_LTE_COEX_POWER_REDUCTION 0x1793 /******************************************************************************* * NAME : UnifiPmfAssociationComebackTimeDelta @@ -5275,7 +6187,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint32 * MIN : 0 * MAX : 4294967295 - * DEFAULT : 0X3 + * DEFAULT : 0X03 * DESCRIPTION : * Bit mask for turning on individual debug entities in the data_plane that * if enabled effect throughput. See DPLP_DEBUG_ENTITIES_T in @@ -5284,6 +6196,21 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_DPLANE_DEBUG 0x17B9 +/******************************************************************************* + * NAME : UnifiDebugForceSiso + * PSID : 6074 (0x17BA) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * Force the platform to only use one radio even if multiple radios are + * supported. WARNING: Changing this value after system start-up will have + * no effect. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_DEBUG_FORCE_SISO 0x17BA + /******************************************************************************* * NAME : UnifiNanEnabled * PSID : 6080 (0x17C0) @@ -5478,7 +6405,8 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * DESCRIPTION : * Enables low power radio RX for idle STA and AP VIFs respectively. * Setting/clearing bit 0 enables/disabled LP RX for (all) STA/Cli VIFs. - * Setting/clearing bit 1 enables/disabled LP RX for AP/GO VIFs. + * Setting/clearing bit 1 enables/disabled LP RX for AP/GO VIFs.This mib + * value will be updated if "unifiRameUpdateMibs" mib is toggled *******************************************************************************/ #define SLSI_PSID_RESERVED_FOR_NAN 0x17CE @@ -5793,7 +6721,8 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 1 * DEFAULT : FALSE * DESCRIPTION : - * Identify whether the chip supports dualband concurrency or not. + * Identify whether the chip supports dualband concurrency or not (RSDB vs. + * VSDB). Set in the respective platform htf file. *******************************************************************************/ #define SLSI_PSID_UNIFI_DUAL_BAND_CONCURRENCY 0x17EB @@ -5840,8 +6769,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 3 * DEFAULT : {0X30, 0X30, 0X20} * DESCRIPTION : - * Hosts only sets the default Code (index 1). Each VIF updates its Code for - * the Host to read (index 2-4). + * Hosts sets the Default Code. *******************************************************************************/ #define SLSI_PSID_UNIFI_DEFAULT_COUNTRY 0x1F4D @@ -5874,6 +6802,19 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_OPERATING_CLASS_PARAMTERS 0x1F4F +/******************************************************************************* + * NAME : UnifiVifCountry + * PSID : 8016 (0x1F50) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Per VIf: Each VIF updates its Country Code for the Host to read + *******************************************************************************/ +#define SLSI_PSID_UNIFI_VIF_COUNTRY 0x1F50 + /******************************************************************************* * NAME : UnifiNoCellMaxPower * PSID : 8017 (0x1F51) @@ -5898,10 +6839,37 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * DESCRIPTION : * Channels applicable. Defined in a uint64 represented by the octet string. * First byte of the octet string maps to LSB. Bit 0 maps to channel 1. - * Mapping defined in mlme_regulatory_freq_list[]. + * Mapping defined in ChannelisationRules. *******************************************************************************/ #define SLSI_PSID_UNIFI_NO_CELL_INCLUDED_CHANNELS 0x1F52 +/******************************************************************************* + * NAME : UnifiRegDomVersion + * PSID : 8019 (0x1F53) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * Regulatory domain version encoded into 2 bytes, major version as MSB and + * minor version as LSB + *******************************************************************************/ +#define SLSI_PSID_UNIFI_REG_DOM_VERSION 0x1F53 + +/******************************************************************************* + * NAME : UnifiDefaultCountryWithoutCH12CH13 + * PSID : 8020 (0x1F54) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * Update the default country code to ensure CH12 and CH13 are not used. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_DEFAULT_COUNTRY_WITHOUT_CH12_CH13 0x1F54 + /******************************************************************************* * NAME : UnifiReadReg * PSID : 8051 (0x1F73) diff --git a/drivers/net/wireless/scsc/mlme.c b/drivers/net/wireless/scsc/mlme.c index a080891016f7..9d58aaf6936a 100755 --- a/drivers/net/wireless/scsc/mlme.c +++ b/drivers/net/wireless/scsc/mlme.c @@ -22,24 +22,6 @@ #define SLSI_SCAN_CHANNEL_DESCRIPTOR_SIZE 3 #define SLSI_CHANN_INFO_HT_SCB 0x0100 -#define SLSI_FW_API_RATE_HT_SELECTOR_FIELD 0xc000 -#define SLSI_FW_API_RATE_NON_HT_SELECTED 0x4000 -#define SLSI_FW_API_RATE_HT_SELECTED 0x8000 -#define SLSI_FW_API_RATE_VHT_SELECTED 0xc000 - -#define SLSI_FW_API_RATE_VHT_MCS_FIELD 0x000F -#define SLSI_FW_API_RATE_HT_MCS_FIELD 0x003F -#define SLSI_FW_API_RATE_INDEX_FIELD 0x1fff -#define SLSI_FW_API_RATE_VHT_NSS_FIELD 0x0070 -#define SLSI_FW_API_RATE_HT_NSS_FIELD 0x0040 - -#define SLSI_FW_API_RATE_BW_FIELD 0x0600 -#define SLSI_FW_API_RATE_BW_40MHZ 0x0200 -#define SLSI_FW_API_RATE_BW_20MHZ 0x0000 - -#define SLSI_FW_API_RATE_SGI 0x0100 -#define SLSI_FW_API_RATE_GF 0x0080 - #ifdef CONFIG_SCSC_WLAN_GSCAN_ENABLE #define SLSI_FW_MAX_BSSID_PER_TRACKING_IE (20) #define SLSI_FW_BSSID_DESCRIPTOR_BSS_SIZE (10) @@ -90,39 +72,6 @@ static bool missing_cfm_ind_panic = true; module_param(missing_cfm_ind_panic, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(missing_cfm_ind_panic, "Panic on missing confirm or indication from the chip"); -/* indices: 3= BW20->idx_0, BW40->idx_1, BW80->idx_2. - * 2= noSGI->idx_0, SGI->idx_1 - * 10= mcs index - * rate units 100kbps - * This table for single stream Nss=1and does not include 160MHz BW and 80+80MHz BW. - */ -static const u16 slsi_rates_table[3][2][10] = { - { /* BW20 */ - { /* no SGI */ - 65, 130, 195, 260, 390, 520, 585, 650, 780, 0 - }, - { /* SGI */ - 72, 144, 217, 289, 433, 578, 650, 722, 867, 0 - } - }, - { /* BW40 */ - { /* no SGI */ - 135, 270, 405, 540, 810, 1080, 1215, 1350, 1620, 1800 - }, - { /* SGI */ - 150, 300, 450, 600, 900, 1200, 1350, 1500, 1800, 2000 - } - }, - { /* BW80 */ - { /* no SGI */ - 293, 585, 878, 1170, 1755, 2340, 2633, 2925, 3510, 3900 - }, - { /* SGI */ - 325, 650, 975, 1300, 1950, 2600, 2925, 3250, 3900, 4333 - } - } -}; - struct slsi_mlme_rsse { u8 group_cs_count; const u8 *group_cs; @@ -444,50 +393,67 @@ static struct ieee80211_reg_rule *slsi_get_reg_rule(u32 center_freq, struct slsi return NULL; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) -u16 slsi_get_chann_info(struct slsi_dev *sdev, struct cfg80211_chan_def *chandef) +u16 slsi_compute_chann_info(struct slsi_dev *sdev, u16 width, u16 center_freq0, u16 channel_freq) { u16 chann_info; u16 prim_chan_pos = 0; - SLSI_UNUSED_PARAMETER(sdev); - - switch (chandef->width) { + SLSI_DBG3(sdev, SLSI_MLME, "compute channel info\n"); + switch (width) { case NL80211_CHAN_WIDTH_20: - case NL80211_CHAN_WIDTH_20_NOHT: chann_info = 20; break; case NL80211_CHAN_WIDTH_40: chann_info = 40; /* Check HT Minus */ - if (chandef->chan && chandef->center_freq1 < chandef->chan->center_freq) + if (center_freq0 < channel_freq) chann_info |= SLSI_CHANN_INFO_HT_SCB; break; case NL80211_CHAN_WIDTH_80: /* F = { F1-30, ... F1+30 } => { 0x0000, ... 0x0300} */ - prim_chan_pos = ((30 + chandef->chan->center_freq - chandef->center_freq1) / 20); + prim_chan_pos = ((30 + channel_freq - center_freq0) / 20); if (prim_chan_pos > 3) { - SLSI_ERR(sdev, "Invalid center_freq1 in chandef : %u, primary channel = %u, primary chan pos calculated = %d\n", chandef->center_freq1, chandef->chan->center_freq, prim_chan_pos); + SLSI_ERR(sdev, "Invalid center_freq0 in chandef : %u, primary channel = %u," + "primary chan pos calculated = %d\n", center_freq0, channel_freq, prim_chan_pos); prim_chan_pos = 0; } prim_chan_pos = 0xFFFF & (prim_chan_pos << 8); chann_info = 80 | prim_chan_pos; break; default: - SLSI_WARN(sdev, "Invalid chandef.width(0x%x)\n", chandef->width); + SLSI_WARN(sdev, "Invalid chandef.width(0x%x)\n", width); chann_info = 0; break; } - SLSI_DBG3(sdev, SLSI_MLME, "channel_width:%u, chann_info:0x%x\n", chandef->width, chann_info); + SLSI_DBG3(sdev, SLSI_MLME, "channel_width:%u, chann_info:0x%x\n", width, chann_info); return chann_info; } -int slsi_check_channelization(struct slsi_dev *sdev, struct cfg80211_chan_def *chandef) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) +u16 slsi_get_chann_info(struct slsi_dev *sdev, struct cfg80211_chan_def *chandef) +{ + u16 chann_info = 0; + + SLSI_UNUSED_PARAMETER(sdev); + + if (chandef->width == NL80211_CHAN_WIDTH_20 || chandef->width == NL80211_CHAN_WIDTH_20_NOHT) { + chann_info = 20; + SLSI_DBG3(sdev, SLSI_MLME, "channel_width:%u, chann_info:0x%x\n", chandef->width, chann_info); + } else if (chandef->chan) { + chann_info = slsi_compute_chann_info(sdev, chandef->width, chandef->center_freq1, + chandef->chan->center_freq); + } + return chann_info; +} + +int slsi_check_channelization(struct slsi_dev *sdev, struct cfg80211_chan_def *chandef, + int wifi_sharing_channel_switched) { u8 width; struct ieee80211_reg_rule *rule = NULL; struct ieee80211_channel *channel = NULL; + u32 ref_flags; switch (chandef->width) { case NL80211_CHAN_WIDTH_20: @@ -509,16 +475,27 @@ int slsi_check_channelization(struct slsi_dev *sdev, struct cfg80211_chan_def *c if (!channel) { SLSI_ERR(sdev, "Invalid channel %d used to start AP. Channel not found\n", chandef->chan->center_freq); return -EINVAL; - } else if (channel->flags & (IEEE80211_CHAN_DISABLED | - IEEE80211_CHAN_RADAR + } + + if (wifi_sharing_channel_switched == 1) { + ref_flags = IEEE80211_CHAN_DISABLED #if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 10, 13) - | IEEE80211_CHAN_PASSIVE_SCAN + | IEEE80211_CHAN_PASSIVE_SCAN #endif - )) { + ; + } else { + ref_flags = IEEE80211_CHAN_DISABLED | + IEEE80211_CHAN_RADAR +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 10, 13) + | IEEE80211_CHAN_PASSIVE_SCAN +#endif + ; + } + + if (channel->flags & ref_flags) { SLSI_ERR(sdev, "Invalid channel %d used to start AP\n", chandef->chan->center_freq); return -EINVAL; } - rule = slsi_get_reg_rule(MHZ_TO_KHZ(chandef->center_freq1), &sdev->device_config.domain_info); if (!rule) { SLSI_ERR(sdev, "Invalid channel %d used to start AP. No reg rule found for this channel\n", chandef->chan->center_freq); @@ -1229,7 +1206,7 @@ static int slsi_mlme_append_channel_list(struct slsi_dev *sde freq_fw_unit = cpu_to_le16(freq_fw_unit); memcpy(p, &freq_fw_unit, sizeof(freq_fw_unit)); - if (passive_scan) + if (passive_scan && (scan_type != FAPI_SCANTYPE_AP_AUTO_CHANNEL_SELECTION)) p[2] = FAPI_SCANPOLICY_PASSIVE; else p[2] = 0; @@ -1256,7 +1233,7 @@ static inline int slsi_set_scan_params( u8 *p = NULL; u8 i; struct cfg80211_ssid *pssid = ssids; -#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_OUI +#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION struct netdev_vif *netdev_vif = netdev_priv(dev); struct slsi_dev *sdev = netdev_vif->sdev; #endif @@ -1266,9 +1243,9 @@ static inline int slsi_set_scan_params( fapi_set_u16(req, u.mlme_add_scan_req.report_mode_bitmap, report_mode); -#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_OUI - if (scan_type == FAPI_SCANTYPE_GSCAN && sdev->scan_oui_active) - fapi_set_memcpy(req, u.mlme_add_scan_req.device_address, sdev->scan_oui); +#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION + if (sdev->scan_addr_set) + fapi_set_memcpy(req, u.mlme_add_scan_req.device_address, sdev->scan_mac_addr); else #endif fapi_set_memcpy(req, u.mlme_add_scan_req.device_address, dev->dev_addr); @@ -1452,8 +1429,8 @@ int slsi_mlme_add_scan( return -EINVAL; WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->scan_mutex)); - SLSI_NET_DBG3(dev, SLSI_MLME, "id:0x%x, n_channels:%d, n_ssids:%d\n", (ndev_vif->ifnum << 8 | SLSI_SCAN_HW_ID), - n_channels, n_ssids); + SLSI_INFO(sdev, "scan started for id:0x%x, n_channels:%d, n_ssids:%d, scan_type:%d\n", + (ndev_vif->ifnum << 8 | SLSI_SCAN_HW_ID), n_channels, n_ssids, scan_type); alloc_data_size += sizeof(scan_timing_ie) + ies_len + @@ -2596,7 +2573,6 @@ void slsi_fw_tx_rate_calc(u16 fw_rate, struct rate_info *tx_rate, unsigned long /* Calculate NSS --> bits 6 to 4*/ nss = ((SLSI_FW_API_RATE_VHT_NSS_FIELD & fw_rate) >> 4) + 1; mcs_idx = SLSI_FW_API_RATE_VHT_MCS_FIELD & fw_rate; - /* Bandwidth (BW): 0x0= 20 MHz, 0x1= 40 MHz, 0x2= 80 MHz, 0x3= 160/ 80+80 MHz. 0x3 is not supported */ if ((chan_bw_idx <= 2) && (mcs_idx <= 9)) { if (tx_rate) @@ -2621,7 +2597,14 @@ int slsi_mlme_get_sinfo_mib(struct slsi_dev *sdev, struct net_device *dev, static const struct slsi_mib_get_entry get_values[] = { { SLSI_PSID_UNIFI_TX_DATA_RATE, { 0, 0 } }, /* to get STATION_INFO_TX_BITRATE*/ { SLSI_PSID_UNIFI_RSSI, { 0, 0 } }, /* to get STATION_INFO_SIGNAL_AVG*/ + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 2, 0 } }, + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 3, 0 } }, + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 4, 0 } }, + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 24, 0 } }, + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 29, 0 } }, }; + int tx_counter = 0; + int rx_counter = 0; WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex)); @@ -2641,8 +2624,9 @@ int slsi_mlme_get_sinfo_mib(struct slsi_dev *sdev, struct net_device *dev, /* Fixed fields len (5) : 2 bytes(PSID) + 2 bytes (Len) + 1 byte (VLDATA header ) [10 for 2 PSIDs] * Data : 3 bytes for SLSI_PSID_UNIFI_TX_DATA_RATE , 1 byte for SLSI_PSID_UNIFI_RSSI + * 10*5 bytes for 5 Throughput Mib's */ - mibrsp.dataLength = 14; + mibrsp.dataLength = 64; mibrsp.data = kmalloc(mibrsp.dataLength, GFP_KERNEL); if (!mibrsp.data) { @@ -2691,6 +2675,30 @@ int slsi_mlme_get_sinfo_mib(struct slsi_dev *sdev, struct net_device *dev, SLSI_DBG3(sdev, SLSI_MLME, "SLSI_PSID_UNIFI_RSSI = %d\n", values[1].u.intValue); } + + if (values[2].type == SLSI_MIB_TYPE_UINT) + rx_counter += values[2].u.uintValue; /*bad_fcs_count*/ + else + SLSI_ERR(sdev, "invalid type. iter:%d", 2); + if (values[3].type == SLSI_MIB_TYPE_UINT) + tx_counter += values[3].u.uintValue; /*missed_ba_count*/ + else + SLSI_ERR(sdev, "invalid type. iter:%d", 3); + if (values[4].type == SLSI_MIB_TYPE_UINT) + tx_counter += values[4].u.uintValue; /*missed_ack_count*/ + else + SLSI_ERR(sdev, "invalid type. iter:%d", 4); + if (values[5].type == SLSI_MIB_TYPE_UINT) + rx_counter += values[5].u.uintValue; /*mac_bad_sig_count*/ + else + SLSI_ERR(sdev, "invalid type. iter:%d", 5); + if (values[6].type == SLSI_MIB_TYPE_UINT) + rx_counter += values[6].u.uintValue; /*rx_error_count*/ + else + SLSI_ERR(sdev, "invalid type. iter:%d", 6); + + peer->sinfo.tx_failed = tx_counter; + peer->sinfo.rx_dropped_misc = rx_counter; } else { SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_get_req failed(result:%u)\n", r); } @@ -3771,6 +3779,112 @@ int slsi_mlme_significant_change_set(struct slsi_dev *sdev, struct net_device *d return r; } +int slsi_mlme_add_range_req(struct slsi_dev *sdev, u8 count, + struct slsi_rtt_config *nl_rtt_params, u16 rtt_id, u16 vif_idx) +{ + struct sk_buff *req; + struct sk_buff *rx; + int r = 0, i; + size_t alloc_data_size = 0; + u8 fapi_ie_generic[] = { 0xdd, 0x24, 0x00, 0x16, 0x32, 0x0a, 0x01 }; + /* calculate data size */ + alloc_data_size += count * (fapi_ie_generic[1] + 2); + + req = fapi_alloc(mlme_add_range_req, MLME_ADD_RANGE_REQ, 0, alloc_data_size); + if (!req) { + SLSI_ERR(sdev, "failed to alloc %zd\n", alloc_data_size); + return -ENOMEM; + } + SLSI_DBG2(sdev, SLSI_MLME, "count-->%d allocated data size: %d\n", count, alloc_data_size); + /*fill the data */ + fapi_set_u16(req, u.mlme_add_range_req.vif, vif_idx); + fapi_set_u16(req, u.mlme_add_range_req.rtt_id, rtt_id); + for (i = 0; i < count; i++) { + fapi_append_data(req, fapi_ie_generic, sizeof(fapi_ie_generic)); + fapi_append_data(req, nl_rtt_params[i].source_addr, ETH_ALEN); + fapi_append_data(req, nl_rtt_params[i].peer_addr, ETH_ALEN); + fapi_append_data(req, (u8 *)&nl_rtt_params[i].type, 2); + fapi_append_data(req, (u8 *)&nl_rtt_params[i].channel_freq, 2); + fapi_append_data(req, (u8 *)&nl_rtt_params[i].channel_info, 2); + fapi_append_data(req, (u8 *)&nl_rtt_params[i].burst_period, 1); + fapi_append_data(req, (u8 *)&nl_rtt_params[i].num_burst, 1); + fapi_append_data(req, (u8 *)&nl_rtt_params[i].num_frames_per_burst, 1); + fapi_append_data(req, (u8 *)&nl_rtt_params[i].num_retries_per_ftmr, 1); + fapi_append_data(req, (u8 *)&nl_rtt_params[i].burst_duration, 1); + fapi_append_data(req, (u8 *)&nl_rtt_params[i].preamble, 2); + fapi_append_data(req, (u8 *)&nl_rtt_params[i].bw, 2); + fapi_append_data(req, (u8 *)&nl_rtt_params[i].LCI_request, 2); + fapi_append_data(req, (u8 *)&nl_rtt_params[i].LCR_request, 2); + } + rx = slsi_mlme_req_cfm(sdev, NULL, req, MLME_ADD_RANGE_CFM); + SLSI_DBG2(sdev, SLSI_MLME, "(After mlme req cfm for rtt config)\n"); + if (!rx) + return -EIO; + if (fapi_get_u16(rx, u.mlme_add_range_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { + SLSI_ERR(sdev, "mlme_add_range_cfm(ERROR:%x)", + fapi_get_u16(rx, u.mlme_add_range_cfm.result_code)); + r = -EINVAL; + } + + slsi_kfree_skb(rx); + return r; +} + +bool slsi_del_range_cfm_validate(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *cfm) +{ + int result = fapi_get_u16(cfm, u.mlme_del_range_cfm.result_code); + bool r = false; + + SLSI_UNUSED_PARAMETER(sdev); + + if (WARN_ON(!dev)) + goto exit; + + if (result == FAPI_RESULTCODE_SUCCESS) + r = true; + else + SLSI_NET_ERR(dev, "mlme_del_range_cfm(result:%u) ERROR\n", result); + +exit: + slsi_kfree_skb(cfm); + return r; +} + +int slsi_mlme_del_range_req(struct slsi_dev *sdev, struct net_device *dev, u16 count, + u8 *addr, u16 rtt_id) +{ + struct sk_buff *req; + struct sk_buff *rx; + u16 *rtt_vif_idx = sdev->rtt_vif; + int r = 0, i; + size_t alloc_data_size = 0; + + /* calculate data size-->2 bytes for vif */ + alloc_data_size += count * sizeof(ETH_ALEN); + /* Alloc data size */ + req = fapi_alloc(mlme_del_range_req, MLME_DEL_RANGE_REQ, 0, alloc_data_size); + if (!req) { + SLSI_ERR(sdev, "failed to alloc %zd\n", alloc_data_size); + return -ENOMEM; + } + /*fill the data */ + fapi_set_u16(req, u.mlme_del_range_req.vif, rtt_vif_idx[rtt_id]); + fapi_set_u16(req, u.mlme_del_range_req.rtt_id, rtt_id); + fapi_set_u16(req, u.mlme_del_range_req.entries, count); + for (i = 0; i < count; i++) + fapi_append_data(req, &addr[i * ETH_ALEN], ETH_ALEN); + + rx = slsi_mlme_req_cfm_ind(sdev, dev, req, MLME_DEL_RANGE_CFM, MLME_RANGE_IND, slsi_del_range_cfm_validate); + sdev->rtt_vif[rtt_id] = -1; + if (!rx) { + SLSI_NET_ERR(dev, "mlme_del_range_cfm() ERROR\n"); + slsi_kfree_skb(rx); + return -EINVAL; + } + slsi_kfree_skb(rx); + return r; +} + #define SLSI_FAPI_EPNO_NETWORK_MIN_SIZE (3) int slsi_mlme_set_pno_list(struct slsi_dev *sdev, int count, struct slsi_epno_param *epno_param, struct slsi_epno_hs2_param *epno_hs2_param) @@ -4675,3 +4789,76 @@ int slsi_mlme_nan_set_config(struct slsi_dev *sdev, struct net_device *dev, stru slsi_kfree_skb(cfm); return r; } + +#ifdef CONFIG_SCSC_WLAN_DEBUG +#define SLSI_TEST_CONFIG_MONITOR_MODE_DESCRIPTOR_SIZE (12) +int slsi_test_sap_configure_monitor_mode(struct slsi_dev *sdev, struct net_device *dev, struct cfg80211_chan_def *chandef) +{ + struct netdev_vif *ndev_vif = netdev_priv(dev); + struct sk_buff *req; + struct sk_buff *cfm; + u8 *p = NULL; + size_t alloc_data_size = 0; + u16 center_freq1; + u16 center_freq2; + u16 chan_info; + int r = 0; + + const u8 monitor_config_ie_header[] = { + 0xDD, /* Element ID: Vendor Specific */ + 0x11, /* Length */ + 0x00, 0x16, 0x32, /* OUI: Samsung Electronics Co. */ + 0x10, /* OUI Type: Monitor mode parameters */ + 0x01 /* OUI Subtype: configuration */ + }; + + if (slsi_is_test_mode_enabled()) { + SLSI_NET_WARN(dev, "WlanLite: NOT supported\n"); + return -EOPNOTSUPP; + } + + WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex)); + + chan_info = slsi_get_chann_info(sdev, chandef); + SLSI_NET_DBG2(dev, SLSI_MLME, "test_configure_monitor_mode_req(center_freq1:%u, chan_info:%u, center_freq2:%u)\n", + chandef->center_freq1, + chan_info, + chandef->center_freq2); + + center_freq1 = SLSI_FREQ_HOST_TO_FW(chandef->center_freq1); + center_freq1 = cpu_to_le16(center_freq1); + center_freq2 = SLSI_FREQ_HOST_TO_FW(chandef->center_freq2); + center_freq2 = cpu_to_le16(center_freq2); + + alloc_data_size = sizeof(monitor_config_ie_header) + SLSI_TEST_CONFIG_MONITOR_MODE_DESCRIPTOR_SIZE; + + req = fapi_alloc(test_configure_monitor_mode_req, TEST_CONFIGURE_MONITOR_MODE_REQ, ndev_vif->ifnum, alloc_data_size); + if (!req) { + SLSI_NET_ERR(dev, "failed to alloc Monitor mode request (len:%d)\n", alloc_data_size); + return -ENOMEM; + } + + fapi_append_data(req, monitor_config_ie_header, sizeof(monitor_config_ie_header)); + fapi_append_data(req, (const u8 *)¢er_freq1, 2); + fapi_append_data(req, (const u8 *)&chan_info, 2); + p = fapi_append_data(req, (const u8 *)¢er_freq2, 2); + + /* MAC address filtering is not supported yet; so fill in zeros */ + memset(p, 0, 6); + + cfm = slsi_mlme_req_cfm(sdev, dev, req, TEST_CONFIGURE_MONITOR_MODE_CFM); + if (!cfm) { + SLSI_NET_ERR(dev, "failed to receive Confirm\n"); + return -EIO; + } + + if (fapi_get_u16(cfm, u.mlme_set_channel_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { + SLSI_NET_ERR(dev, "test_configure_monitor_mode_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.test_configure_monitor_mode_cfm.result_code)); + r = -EINVAL; + } + + slsi_kfree_skb(cfm); + return r; +} + +#endif diff --git a/drivers/net/wireless/scsc/mlme.h b/drivers/net/wireless/scsc/mlme.h index 4fdcd8abd56a..7e2c2f781a91 100755 --- a/drivers/net/wireless/scsc/mlme.h +++ b/drivers/net/wireless/scsc/mlme.h @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ @@ -73,6 +73,8 @@ enum slsi_ac_index_wmm_pe { #define SLSI_ACTION_FRAME_WMM (1 << 17) #define SLSI_ACTION_FRAME_WNM (1 << 10) #define SLSI_ACTION_FRAME_QOS (1 << 1) +#define SLSI_ACTION_FRAME_PROTECTED_DUAL BIT(9) +#define SLSI_ACTION_FRAME_RADIO_MEASUREMENT BIT(5) /* Firmware transmit rates */ #define SLSI_TX_RATE_NON_HT_1MBPS 0x4001 @@ -129,7 +131,8 @@ struct slsi_mlme_pkt_filter_elem { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) u16 slsi_get_chann_info(struct slsi_dev *sdev, struct cfg80211_chan_def *chandef); -int slsi_check_channelization(struct slsi_dev *sdev, struct cfg80211_chan_def *chandef); +int slsi_check_channelization(struct slsi_dev *sdev, struct cfg80211_chan_def *chandef, + int wifi_sharing_channel_switched); #else u16 slsi_get_chann_info(struct slsi_dev *sdev, enum nl80211_channel_type channel_type); int slsi_check_channelization(struct slsi_dev *sdev, enum nl80211_channel_type channel_type); @@ -150,6 +153,7 @@ void slsi_ap_obss_scan_done_ind(struct net_device *dev, struct netdev_vif *ndev_ int slsi_mlme_spare_signal_1(struct slsi_dev *sdev, struct net_device *dev); +u16 slsi_compute_chann_info(struct slsi_dev *sdev, u16 width, u16 center_freq0, u16 channel_freq); /** * slsi_mlme_add_autonomous_scan() Returns: * 0 : Scan installed @@ -255,4 +259,6 @@ int slsi_mlme_set_ctwindow(struct slsi_dev *sdev, struct net_device *dev, unsign int slsi_mlme_set_p2p_noa(struct slsi_dev *sdev, struct net_device *dev, unsigned int noa_count, unsigned int interval, unsigned int duration); void slsi_fw_tx_rate_calc(u16 fw_rate, struct rate_info *tx_rate, unsigned long *data_rate_mbps); +int slsi_test_sap_configure_monitor_mode(struct slsi_dev *sdev, struct net_device *dev, struct cfg80211_chan_def *chandef); + #endif /*__SLSI_MLME_H__*/ diff --git a/drivers/net/wireless/scsc/netif.c b/drivers/net/wireless/scsc/netif.c index 27b5c5c1507c..ce22fb35b19d 100755 --- a/drivers/net/wireless/scsc/netif.c +++ b/drivers/net/wireless/scsc/netif.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "debug.h" #include "netif.h" @@ -119,7 +120,11 @@ static uint tcp_ack_suppression_rcv_window = 128; module_param(tcp_ack_suppression_rcv_window, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(tcp_ack_suppression_rcv_window, "Receive window size (in unit of Kbytes) that triggers Ack suppression"); +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +static void slsi_netif_tcp_ack_suppression_timeout(struct timer_list *t); +#else static void slsi_netif_tcp_ack_suppression_timeout(unsigned long data); +#endif static int slsi_netif_tcp_ack_suppression_start(struct net_device *dev); static int slsi_netif_tcp_ack_suppression_stop(struct net_device *dev); static struct sk_buff *slsi_netif_tcp_ack_suppression_pkt(struct net_device *dev, struct sk_buff *skb); @@ -490,6 +495,12 @@ static u16 slsi_net_select_queue(struct net_device *dev, struct sk_buff *skb) if (!skb_mac_header_was_set(skb)) skb_reset_mac_header(skb); + if (is_zero_ether_addr(ehdr->h_dest) || is_zero_ether_addr(ehdr->h_source)) { + SLSI_NET_WARN(dev, "invalid Ethernet addresses (dest:%pM,src:%pM)\n", ehdr->h_dest, ehdr->h_source); + SCSC_BIN_TAG_INFO(BINARY, skb->data, skb->len > 128 ? 128 : skb->len); + return SLSI_NETIF_Q_DISCARD; + } + proto = be16_to_cpu(eth_hdr(skb)->h_proto); switch (proto) { @@ -927,44 +938,15 @@ static netdev_features_t slsi_net_fix_features(struct net_device *dev, netdev_fe #endif #ifdef CONFIG_SCSC_WLAN_RX_NAPI_GRO - SLSI_NET_DBG1(dev, SLSI_RX, "napi rx gro enabled\n"); + SLSI_NET_DBG1(dev, SLSI_RX, "NAPI Rx GRO enabled\n"); features |= NETIF_F_GRO; #else - SLSI_NET_DBG1(dev, SLSI_RX, "napi rx gro enabled\n"); + SLSI_NET_DBG1(dev, SLSI_RX, "NAPI Rx GRO disabled\n"); features &= ~NETIF_F_GRO; #endif return features; } -#ifdef CONFIG_SCSC_WLAN_RX_NAPI -int slsi_net_rx_poll(struct napi_struct *napi, int budget) -{ - struct netdev_vif *ndev_vif = netdev_priv(napi->dev); - struct sk_buff *skb = slsi_skb_dequeue(&ndev_vif->napi.rx_data); - int npackets = 0; - - while (skb) { - npackets++; - slsi_dbg_untrack_skb(skb); -#ifdef CONFIG_SCSC_WLAN_RX_NAPI_GRO - napi_gro_receive(napi, skb); -#else - netif_receive_skb(skb); -#endif - if (npackets == budget) - break; - skb = slsi_skb_dequeue(&ndev_vif->napi.rx_data); - } - - if (npackets < budget) { - ndev_vif->napi.interrupt_enabled = true; - napi_complete(napi); - } - - return npackets; -} -#endif - static void slsi_set_multicast_list(struct net_device *dev) { struct netdev_vif *ndev_vif = netdev_priv(dev); @@ -1050,8 +1032,8 @@ static void slsi_if_setup(struct net_device *dev) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 9)) dev->needs_free_netdev = true; #else - dev->destructor = free_netdev; -#endif + dev->destructor = free_netdev; +#endif } int slsi_netif_add_locked(struct slsi_dev *sdev, const char *name, int ifnum) @@ -1141,7 +1123,7 @@ int slsi_netif_add_locked(struct slsi_dev *sdev, const char *name, int ifnum) /* For HS2 interface */ if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif)) - sdev->hs2_state = HS2_NO_VIF; + sdev->wlan_unsync_vif_state = WLAN_UNSYNC_NO_VIF; /* For p2p0 interface */ else if (SLSI_IS_VIF_INDEX_P2P(ndev_vif)) { @@ -1152,13 +1134,16 @@ int slsi_netif_add_locked(struct slsi_dev *sdev, const char *name, int ifnum) INIT_DELAYED_WORK(&ndev_vif->scan_timeout_work, slsi_scan_ind_timeout_handle); +#ifndef CONFIG_SCSC_WLAN_RX_NAPI ret = slsi_skb_work_init(sdev, dev, &ndev_vif->rx_data, "slsi_wlan_rx_data", slsi_rx_netdev_data_work); if (ret) goto exit_with_error; - +#endif ret = slsi_skb_work_init(sdev, dev, &ndev_vif->rx_mlme, "slsi_wlan_rx_mlme", slsi_rx_netdev_mlme_work); if (ret) { +#ifndef CONFIG_SCSC_WLAN_RX_NAPI slsi_skb_work_deinit(&ndev_vif->rx_data); +#endif goto exit_with_error; } @@ -1183,16 +1168,6 @@ int slsi_netif_add_locked(struct slsi_dev *sdev, const char *name, int ifnum) #endif SLSI_DBG1(sdev, SLSI_NETDEV, "Add:%pM\n", dev->dev_addr); rcu_assign_pointer(sdev->netdev[ifnum], dev); - -#ifdef CONFIG_SCSC_WLAN_RX_NAPI - SLSI_NET_DBG1(dev, SLSI_RX, "napi rx enabled\n"); - skb_queue_head_init(&ndev_vif->napi.rx_data); - slsi_spinlock_create(&ndev_vif->napi.lock); - ndev_vif->napi.interrupt_enabled = true; - /* TODO_HARDMAC: What weight should we use? 32 is just a Guess */ - netif_napi_add(dev, &ndev_vif->napi.napi, slsi_net_rx_poll, 32); - napi_enable(&ndev_vif->napi.napi); -#endif ndev_vif->delete_probe_req_ies = false; ndev_vif->probe_req_ies = NULL; ndev_vif->probe_req_ie_len = 0; @@ -1200,7 +1175,9 @@ int slsi_netif_add_locked(struct slsi_dev *sdev, const char *name, int ifnum) return 0; exit_with_error: + SLSI_MUTEX_LOCK(sdev->netdev_remove_mutex); free_netdev(dev); + SLSI_MUTEX_UNLOCK(sdev->netdev_remove_mutex); return ret; } @@ -1342,31 +1319,31 @@ static void slsi_netif_remove_locked(struct slsi_dev *sdev, struct net_device *d if (SLSI_IS_VIF_INDEX_P2P(ndev_vif)) { slsi_p2p_deinit(sdev, ndev_vif); } else if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif)) { - sdev->hs2_state = HS2_NO_VIF; + sdev->wlan_unsync_vif_state = WLAN_UNSYNC_NO_VIF; ndev_vif->vif_type = SLSI_VIFTYPE_UNSPECIFIED; } cancel_delayed_work(&ndev_vif->scan_timeout_work); ndev_vif->scan[SLSI_SCAN_HW_ID].requeue_timeout_work = false; +#ifndef CONFIG_SCSC_WLAN_RX_NAPI slsi_skb_work_deinit(&ndev_vif->rx_data); +#endif slsi_skb_work_deinit(&ndev_vif->rx_mlme); for (i = 0; i < SLSI_SCAN_MAX; i++) slsi_purge_scan_results(ndev_vif, i); slsi_kfree_skb(ndev_vif->sta.mlme_scan_ind_skb); slsi_roam_channel_cache_prune(dev, 0); - -#ifdef CONFIG_SCSC_WLAN_RX_NAPI - slsi_skb_queue_purge(&ndev_vif->napi.rx_data); -#endif kfree(ndev_vif->probe_req_ies); if (atomic_read(&ndev_vif->is_registered)) { atomic_set(&ndev_vif->is_registered, 0); unregister_netdevice(dev); } else { + SLSI_MUTEX_LOCK(sdev->netdev_remove_mutex); free_netdev(dev); + SLSI_MUTEX_UNLOCK(sdev->netdev_remove_mutex); } } @@ -1425,9 +1402,13 @@ static int slsi_netif_tcp_ack_suppression_start(struct net_device *dev) tcp_ack->max = 0; tcp_ack->age = 0; skb_queue_head_init(&tcp_ack->list); +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + timer_setup(&tcp_ack->timer, slsi_netif_tcp_ack_suppression_timeout, 0); +#else tcp_ack->timer.function = slsi_netif_tcp_ack_suppression_timeout; tcp_ack->timer.data = (unsigned long)tcp_ack; init_timer(&tcp_ack->timer); +#endif tcp_ack->state = 1; slsi_spinlock_create(&tcp_ack->lock); } @@ -1456,9 +1437,17 @@ static int slsi_netif_tcp_ack_suppression_stop(struct net_device *dev) return 0; } +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +static void slsi_netif_tcp_ack_suppression_timeout(struct timer_list *t) +#else static void slsi_netif_tcp_ack_suppression_timeout(unsigned long data) +#endif { +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + struct slsi_tcp_ack_s *tcp_ack = from_timer(tcp_ack, t, timer); +#else struct slsi_tcp_ack_s *tcp_ack = (struct slsi_tcp_ack_s *)data; +#endif struct sk_buff *skb; struct netdev_vif *ndev_vif; struct slsi_dev *sdev; @@ -1500,9 +1489,11 @@ static void slsi_netif_tcp_ack_suppression_timeout(unsigned long data) static int slsi_netif_tcp_ack_suppression_option(struct sk_buff *skb, u32 option) { unsigned char *options; - u32 optlen, len; + u32 optlen = 0, len = 0; + + if (tcp_hdr(skb)->doff > 5) + optlen = (tcp_hdr(skb)->doff - 5) * 4; - optlen = tcp_optlen(skb); options = ((u8 *)tcp_hdr(skb)) + TCP_ACK_SUPPRESSION_OPTIONS_OFFSET; while (optlen > 0) { @@ -1531,8 +1522,10 @@ static int slsi_netif_tcp_ack_suppression_option(struct sk_buff *skb, u32 option len = options[1]; break; } - /* if length field in TCP options is 0, then options are bogus; return here */ - if (len == 0) { + /* if length field in TCP options is 0, or greater than + * total options length, then options are incorrect; return here + */ + if ((len == 0) || (len > optlen)) { SLSI_DBG_HEX_NODEV(SLSI_TX, skb->data, skb->len < 128 ? skb->len : 128, "SKB:\n"); return 0; } @@ -1568,7 +1561,6 @@ static void slsi_netif_tcp_ack_suppression_syn(struct net_device *dev, struct sk tcp_ack->saddr = 0; tcp_ack->count = 0; tcp_ack->ack_seq = 0; - tcp_ack->tcp_sk = NULL; del_timer(&tcp_ack->timer); } } @@ -1599,7 +1591,6 @@ static void slsi_netif_tcp_ack_suppression_syn(struct net_device *dev, struct sk tcp_ack->num_bytes = 0; tcp_ack->hysteresis = 0; } - tcp_ack->tcp_sk = skb->sk; #ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING tcp_ack->stream_id = index; #endif @@ -1651,7 +1642,6 @@ static void slsi_netif_tcp_ack_suppression_fin(struct net_device *dev, struct sk #ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING tcp_ack->stream_id = 0; #endif - tcp_ack->tcp_sk = NULL; SCSC_HIP4_SAMPLER_TCP_FIN(ndev_vif->sdev->minor_prof, index); slsi_spinlock_unlock(&tcp_ack->lock); return; @@ -1716,6 +1706,7 @@ static struct sk_buff *slsi_netif_tcp_ack_suppression_pkt(struct net_device *dev return skb; } if ((tcp_ack->dport == tcp_hdr(skb)->dest) && + (tcp_ack->sport == tcp_hdr(skb)->source) && (tcp_ack->daddr == ip_hdr(skb)->daddr)) { found = 1; ndev_vif->tcp_ack_stats.tack_lastrecord++; @@ -1737,6 +1728,7 @@ static struct sk_buff *slsi_netif_tcp_ack_suppression_pkt(struct net_device *dev return skb; } if ((tcp_ack->dport == tcp_hdr(skb)->dest) && + (tcp_ack->sport == tcp_hdr(skb)->source) && (tcp_ack->daddr == ip_hdr(skb)->daddr)) { found = 1; ndev_vif->tcp_ack_stats.tack_searchrecord++; @@ -1767,7 +1759,7 @@ static struct sk_buff *slsi_netif_tcp_ack_suppression_pkt(struct net_device *dev /* Has data, forward straight away. */ if (be16_to_cpu(ip_hdr(skb)->tot_len) > ((ip_hdr(skb)->ihl * 4) + (tcp_hdr(skb)->doff * 4))) { SCSC_HIP4_SAMPLER_TCP_DATA(ndev_vif->sdev->minor_prof, tcp_ack->stream_id, be32_to_cpu(tcp_hdr(skb)->seq)); - SCSC_HIP4_SAMPLER_TCP_CWND(ndev_vif->sdev->minor_prof, tcp_ack->stream_id, tcp_ack->tcp_sk ? tcp_sk(tcp_ack->tcp_sk)->snd_cwnd : 0); + SCSC_HIP4_SAMPLER_TCP_CWND(ndev_vif->sdev->minor_prof, tcp_ack->stream_id, (skb->sk) ? tcp_sk(skb->sk)->snd_cwnd : 0); SCSC_HIP4_SAMPLER_TCP_SEND_BUF(ndev_vif->sdev->minor_prof, tcp_ack->stream_id, sysctl_tcp_wmem[2]); ndev_vif->tcp_ack_stats.tack_hasdata++; forward_now = 1; diff --git a/drivers/net/wireless/scsc/nl80211_vendor.c b/drivers/net/wireless/scsc/nl80211_vendor.c index 4e8369c589b9..fc7be8822547 100755 --- a/drivers/net/wireless/scsc/nl80211_vendor.c +++ b/drivers/net/wireless/scsc/nl80211_vendor.c @@ -81,6 +81,10 @@ char *slsi_print_event_name(int event_id) return "SLSI_NL80211_NAN_FOLLOWUP_EVENT"; case SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT: return "SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT"; + case SLSI_NL80211_RTT_RESULT_EVENT: + return "SLSI_NL80211_RTT_RESULT_EVENT"; + case SLSI_NL80211_RTT_COMPLETE_EVENT: + return "SLSI_NL80211_RTT_COMPLETE_EVENT"; default: return "UNKNOWN_EVENT"; } @@ -218,7 +222,7 @@ static int slsi_gscan_get_capabilities(struct wiphy *wiphy, int ret = 0; struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy); - SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_GET_CAPABILITIES\n"); + SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_GET_GSCAN_CAPABILITIES\n"); memset(&nl_cap, 0, sizeof(struct slsi_nl_gscan_capabilities)); @@ -1915,6 +1919,7 @@ static int slsi_start_keepalive_offload(struct wiphy *wiphy, struct wireless_dev } skb_reset_mac_header(skb); + skb_set_network_header(skb, sizeof(struct ethhdr)); /* Ethernet Header */ ehdr = (struct ethhdr *)skb_put(skb, sizeof(struct ethhdr)); @@ -2928,12 +2933,11 @@ static int slsi_gscan_set_oui(struct wiphy *wiphy, { int ret = 0; -#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_OUI +#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy); struct net_device *dev = wdev->netdev; struct netdev_vif *ndev_vif; - struct slsi_mib_data mib_data = { 0, NULL }; int temp; int type; const struct nlattr *attr; @@ -2948,7 +2952,7 @@ static int slsi_gscan_set_oui(struct wiphy *wiphy, ndev_vif = netdev_priv(dev); SLSI_MUTEX_LOCK(ndev_vif->scan_mutex); - sdev->scan_oui_active = 0; + sdev->scan_addr_set = 0; nla_for_each_attr(attr, data, len, temp) { type = nla_type(attr); @@ -2965,26 +2969,9 @@ static int slsi_gscan_set_oui(struct wiphy *wiphy, } } - ret = slsi_mib_encode_bool(&mib_data, SLSI_PSID_UNIFI_MAC_ADDRESS_RANDOMISATION, 1, 0); - if (ret != SLSI_MIB_STATUS_SUCCESS) { - SLSI_ERR(sdev, "GSCAN set_out Fail: no mem for MIB\n"); - ret = -ENOMEM; - goto exit; - } + memcpy(sdev->scan_mac_addr, scan_oui, 6); + sdev->scan_addr_set = 1; - ret = slsi_mlme_set(sdev, NULL, mib_data.data, mib_data.dataLength); - - kfree(mib_data.data); - - if (ret) { - SLSI_ERR(sdev, "Err setting unifiMacAddrRandomistaion MIB. error = %d\n", ret); - goto exit; - } - - memcpy(sdev->scan_oui, scan_oui, 6); - sdev->scan_oui_active = 1; - -exit: SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex); #endif return ret; @@ -2999,6 +2986,7 @@ static int slsi_get_feature_set(struct wiphy *wiphy, SLSI_DBG3_NODEV(SLSI_GSCAN, "\n"); feature_set |= SLSI_WIFI_HAL_FEATURE_RSSI_MONITOR; + feature_set |= SLSI_WIFI_HAL_FEATURE_CONTROL_ROAMING; #ifndef CONFIG_SCSC_WLAN_NAT_KEEPALIVE_DISABLE feature_set |= SLSI_WIFI_HAL_FEATURE_MKEEP_ALIVE; #endif @@ -3013,6 +3001,10 @@ static int slsi_get_feature_set(struct wiphy *wiphy, feature_set |= SLSI_WIFI_HAL_FEATURE_HAL_EPNO; if (slsi_dev_nan_supported(SDEV_FROM_WIPHY(wiphy))) feature_set |= SLSI_WIFI_HAL_FEATURE_NAN; + if (slsi_dev_rtt_supported()) { + feature_set |= SLSI_WIFI_HAL_FEATURE_D2D_RTT; + feature_set |= SLSI_WIFI_HAL_FEATURE_D2AP_RTT; + } ret = slsi_vendor_cmd_reply(wiphy, &feature_set, sizeof(feature_set)); @@ -3055,6 +3047,430 @@ static int slsi_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, return ret; } +static int slsi_rtt_get_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) +{ + struct slsi_rtt_capabilities rtt_cap; + int ret = 0; + struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy); + struct net_device *dev = wdev->netdev; + + SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_GET_RTT_CAPABILITIES\n"); + if (!slsi_dev_rtt_supported()) { + SLSI_WARN(sdev, "RTT not supported.\n"); + return -ENOTSUPP; + } + memset(&rtt_cap, 0, sizeof(struct slsi_rtt_capabilities)); + + ret = slsi_mib_get_rtt_cap(sdev, dev, &rtt_cap); + if (ret != 0) { + SLSI_ERR(sdev, "Failed to read mib\n"); + return ret; + } + ret = slsi_vendor_cmd_reply(wiphy, &rtt_cap, sizeof(struct slsi_rtt_capabilities)); + if (ret) + SLSI_ERR_NODEV("rtt_get_capabilities vendor cmd reply failed (err = %d)\n", ret); + return ret; +} + +static int slsi_rtt_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) +{ + int r, type, j = 0; + struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy); + struct net_device *dev = slsi_nan_get_netdev(sdev); + struct netdev_vif *ndev_vif; + struct slsi_rtt_config *nl_rtt_params; + const struct nlattr *iter, *outer, *inner; + int tmp, tmp1, tmp2; + u16 rtt_id = 0; + u8 num_devices = 0; + u16 rtt_peer = SLSI_RTT_PEER_AP; + u16 vif_idx = 0; + u16 center_freq0 = 0, center_freq1 = 0, channel_freq = 0, width = 0; + + SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_RTT_RANGE_START\n"); + if (!slsi_dev_rtt_supported()) { + SLSI_ERR(sdev, "RTT not supported.\n"); + return WIFI_HAL_ERROR_NOT_SUPPORTED; + } + nla_for_each_attr(iter, data, len, tmp) { + type = nla_type(iter); + switch (type) { + case SLSI_RTT_ATTRIBUTE_TARGET_CNT: + num_devices = nla_get_u8(iter); + SLSI_DBG1_NODEV(SLSI_GSCAN, "Target cnt %d\n", num_devices); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_ID: + rtt_id = nla_get_u16(iter); + SLSI_DBG1_NODEV(SLSI_GSCAN, "Target id %d\n", rtt_id); + break; + default: + SLSI_ERR_NODEV("Unexpected RTT attribute:type - %d\n", type); + break; + } + } + if (!num_devices) { + SLSI_ERR_NODEV("No device found for rtt configuration!\n"); + return -EINVAL; + } + /* Allocate memory for the received config params */ + nl_rtt_params = kcalloc(num_devices, sizeof(*nl_rtt_params), GFP_KERNEL); + if (!nl_rtt_params) { + SLSI_ERR_NODEV("Failed for allocate memory for config rtt_param\n"); + return -ENOMEM; + } + nla_for_each_attr(iter, data, len, tmp) { + type = nla_type(iter); + switch (type) { + case SLSI_RTT_ATTRIBUTE_TARGET_INFO: + nla_for_each_nested(outer, iter, tmp1) { + nla_for_each_nested(inner, outer, tmp2) { + switch (nla_type(inner)) { + case SLSI_RTT_ATTRIBUTE_TARGET_MAC: + memcpy(nl_rtt_params[j].peer_addr, nla_data(inner), ETH_ALEN); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_TYPE: + nl_rtt_params[j].type = nla_get_u16(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_PEER: + rtt_peer = nla_get_u16(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ: + channel_freq = nla_get_u16(inner); + nl_rtt_params[j].channel_freq = channel_freq * 2; + break; + case SLSI_RTT_ATTRIBUTE_TARGET_CHAN_WIDTH: + width = nla_get_u16(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ0: + center_freq0 = nla_get_u16(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ1: + center_freq1 = nla_get_u16(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_PERIOD: + nl_rtt_params[j].burst_period = nla_get_u8(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_NUM_BURST: + nl_rtt_params[j].num_burst = nla_get_u8(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST: + nl_rtt_params[j].num_frames_per_burst = nla_get_u8(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR: + nl_rtt_params[j].num_retries_per_ftmr = nla_get_u8(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_BURST_DURATION: + nl_rtt_params[j].burst_duration = nla_get_u8(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_PREAMBLE: + nl_rtt_params[j].preamble = nla_get_u16(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_BW: + nl_rtt_params[j].bw = nla_get_u16(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_LCI: + nl_rtt_params[j].LCI_request = nla_get_u16(inner); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_LCR: + nl_rtt_params[j].LCR_request = nla_get_u16(inner); + break; + default: + SLSI_ERR_NODEV("Unknown RTT INFO ATTRIBUTE type: %d\n", type); + break; + } + if (rtt_peer == SLSI_RTT_PEER_NAN) { +#if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4 + SLSI_ETHER_COPY(nl_rtt_params[j].source_addr, + sdev->netdev_addresses[SLSI_NET_INDEX_NAN]); +#else + SLSI_ERR(sdev, "NAN not supported(mib:%d)\n", sdev->nan_enabled); +#endif + } else { + SLSI_ETHER_COPY(nl_rtt_params[j].source_addr, + sdev->netdev_addresses[SLSI_NET_INDEX_WLAN]); + } + } + /* width+1:to match RTT width enum value with NL enums */ + nl_rtt_params[j].channel_info = slsi_compute_chann_info(sdev, width + 1, center_freq0, + channel_freq); + j++; + } + break; + default: + SLSI_ERR_NODEV("No ATTRIBUTE_Target cnt - %d\n", type); + break; + } + } + if (rtt_peer == SLSI_RTT_PEER_AP) { + vif_idx = 0; + } else if (rtt_peer == SLSI_RTT_PEER_NAN) { + if (!slsi_dev_nan_supported(sdev)) { + SLSI_ERR(sdev, "NAN not supported(mib:%d)\n", sdev->nan_enabled); + kfree(nl_rtt_params); + return WIFI_HAL_ERROR_NOT_SUPPORTED; + } + ndev_vif = netdev_priv(dev); + if (ndev_vif->activated) { + vif_idx = ndev_vif->vif_type; + } else { + SLSI_ERR(sdev, "NAN vif not activated\n"); + kfree(nl_rtt_params); + return -EINVAL; + } + } + r = slsi_mlme_add_range_req(sdev, num_devices, nl_rtt_params, rtt_id, vif_idx); + if (r) { + r = -EINVAL; + SLSI_ERR_NODEV("Failed to set rtt config\n"); + } else { + sdev->rtt_vif[rtt_id] = vif_idx; + SLSI_DBG1_NODEV(SLSI_GSCAN, "Successfully set rtt config\n"); + } + kfree(nl_rtt_params); + return r; +} + +int slsi_tx_rate_calc(struct sk_buff *nl_skb, u16 fw_rate, int res, bool tx_rate) +{ + u8 preamble; + const u32 fw_rate_idx_to_80211_rate[] = { 0, 10, 20, 55, 60, 90, 110, 120, 180, 240, 360, 480, 540 }; + u32 data_rate = 0; + u32 mcs = 0, nss = 0; + u32 chan_bw_idx = 0; + int gi_idx; + + preamble = (fw_rate & SLSI_FW_API_RATE_HT_SELECTOR_FIELD) >> 14; + if ((fw_rate & SLSI_FW_API_RATE_HT_SELECTOR_FIELD) == SLSI_FW_API_RATE_NON_HT_SELECTED) { + u16 fw_rate_idx = fw_rate & SLSI_FW_API_RATE_INDEX_FIELD; + + if (fw_rate > 0 && fw_rate_idx < ARRAY_SIZE(fw_rate_idx_to_80211_rate)) + data_rate = fw_rate_idx_to_80211_rate[fw_rate_idx]; + } else if ((fw_rate & SLSI_FW_API_RATE_HT_SELECTOR_FIELD) == SLSI_FW_API_RATE_HT_SELECTED) { + nss = (SLSI_FW_API_RATE_HT_NSS_FIELD & fw_rate) >> 6; + chan_bw_idx = (fw_rate & SLSI_FW_API_RATE_BW_FIELD) >> 9; + gi_idx = ((fw_rate & SLSI_FW_API_RATE_SGI) == SLSI_FW_API_RATE_SGI) ? 1 : 0; + mcs = SLSI_FW_API_RATE_HT_MCS_FIELD & fw_rate; + if ((chan_bw_idx < 2) && (mcs <= 7)) { + data_rate = (nss + 1) * slsi_rates_table[chan_bw_idx][gi_idx][mcs]; + } else if (mcs == 32 && chan_bw_idx == 1) { + if (gi_idx == 1) + data_rate = (nss + 1) * 67; + else + data_rate = (nss + 1) * 60; + } else { + SLSI_WARN_NODEV("FW DATA RATE decode error fw_rate:%x, bw:%x, mcs_idx:%x, nss : %d\n", + fw_rate, chan_bw_idx, mcs, nss); + } + } else if ((fw_rate & SLSI_FW_API_RATE_HT_SELECTOR_FIELD) == SLSI_FW_API_RATE_VHT_SELECTED) { + /* report vht rate in legacy units and not as mcs index. reason: upper layers may still be not + * updated with vht msc table. + */ + chan_bw_idx = (fw_rate & SLSI_FW_API_RATE_BW_FIELD) >> 9; + gi_idx = ((fw_rate & SLSI_FW_API_RATE_SGI) == SLSI_FW_API_RATE_SGI) ? 1 : 0; + /* Calculate NSS --> bits 6 to 4*/ + nss = (SLSI_FW_API_RATE_VHT_NSS_FIELD & fw_rate) >> 4; + mcs = SLSI_FW_API_RATE_VHT_MCS_FIELD & fw_rate; + /* Bandwidth (BW): 0x0= 20 MHz, 0x1= 40 MHz, 0x2= 80 MHz, 0x3= 160/ 80+80 MHz. 0x3 is not supported */ + if ((chan_bw_idx <= 2) && (mcs <= 9)) + data_rate = (nss + 1) * slsi_rates_table[chan_bw_idx][gi_idx][mcs]; + else + SLSI_WARN_NODEV("FW DATA RATE decode error fw_rate:%x, bw:%x, mcs_idx:%x,nss : %d\n", + fw_rate, chan_bw_idx, mcs, nss); + if (nss > 1) + nss += 1; + } + + if (tx_rate) { + res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_TX_PREAMBLE, preamble); + res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_TX_NSS, nss); + res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_TX_BW, chan_bw_idx); + res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_TX_MCS, mcs); + res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_TX_RATE, data_rate); + } else { + res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_RX_PREAMBLE, preamble); + res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_RX_NSS, nss); + res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_RX_BW, chan_bw_idx); + res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_RX_MCS, mcs); + res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_RX_RATE, data_rate); + } + return res; +} + +void slsi_rx_range_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb) +{ + struct netdev_vif *ndev_vif = netdev_priv(dev); + u32 i, tm; + u16 rtt_entry_count = fapi_get_u16(skb, u.mlme_range_ind.entries); + u16 rtt_id = fapi_get_u16(skb, u.mlme_range_ind.rtt_id); + u32 tmac = fapi_get_u32(skb, u.mlme_range_ind.spare_3); + int data_len = fapi_get_datalen(skb); + u8 *ip_ptr, *start_ptr; + u16 tx_data, rx_data; + struct sk_buff *nl_skb; + int res = 0; + struct nlattr *nlattr_nested; + struct timespec ts; + u64 tkernel; + u8 rep_cnt = 0; + + SLSI_MUTEX_LOCK(ndev_vif->vif_mutex); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, + SLSI_NL80211_RTT_RESULT_EVENT, GFP_KERNEL); +#else + nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, SLSI_NL80211_RTT_RESULT_EVENT, + GFP_KERNEL); +#endif + SLSI_DBG1_NODEV(SLSI_GSCAN, "Event: %s(%d)\n", + slsi_print_event_name(SLSI_NL80211_RTT_RESULT_EVENT), SLSI_NL80211_RTT_RESULT_EVENT); + + if (!nl_skb) { + SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n"); + goto exit; + } + + ip_ptr = fapi_get_data(skb); + start_ptr = fapi_get_data(skb); + res |= nla_put_u16(nl_skb, SLSI_RTT_ATTRIBUTE_RESULT_CNT, rtt_entry_count); + res |= nla_put_u16(nl_skb, SLSI_RTT_ATTRIBUTE_TARGET_ID, rtt_id); + res |= nla_put_u8(nl_skb, SLSI_RTT_ATTRIBUTE_RESULTS_PER_TARGET, 1); + for (i = 0; i < rtt_entry_count; i++) { + nlattr_nested = nla_nest_start(nl_skb, SLSI_RTT_ATTRIBUTE_RESULT); + if (!nlattr_nested) { + SLSI_ERR(sdev, "Error in nla_nest_start\n"); + /* Dont use slsi skb wrapper for this free */ + kfree_skb(nl_skb); + goto exit; + } + ip_ptr += 7; /*skip first 7 bytes for fapi_ie_generic */ + res |= nla_put(nl_skb, SLSI_RTT_EVENT_ATTR_ADDR, ETH_ALEN, ip_ptr); + ip_ptr += 6; + res |= nla_put_u8(nl_skb, SLSI_RTT_EVENT_ATTR_BURST_NUM, *ip_ptr++); + res |= nla_put_u8(nl_skb, SLSI_RTT_EVENT_ATTR_MEASUREMENT_NUM, *ip_ptr++); + res |= nla_put_u8(nl_skb, SLSI_RTT_EVENT_ATTR_SUCCESS_NUM, *ip_ptr++); + res |= nla_put_u8(nl_skb, SLSI_RTT_EVENT_ATTR_NUM_PER_BURST_PEER, *ip_ptr++); + res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_STATUS, *ip_ptr); + ip_ptr += 2; + res |= nla_put_u8(nl_skb, SLSI_RTT_EVENT_ATTR_RETRY_AFTER_DURATION, *ip_ptr++); + res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_TYPE, *ip_ptr); + ip_ptr += 2; + res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_RSSI, *ip_ptr); + ip_ptr += 2; + res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_RSSI_SPREAD, *ip_ptr); + ip_ptr += 2; + memcpy(&tx_data, ip_ptr, 2); + res = slsi_tx_rate_calc(nl_skb, tx_data, res, 1); + ip_ptr += 2; + memcpy(&rx_data, ip_ptr, 2); + res = slsi_tx_rate_calc(nl_skb, rx_data, res, 0); + ip_ptr += 2; + res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_RTT, *ip_ptr); + ip_ptr += 4; + res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_RTT_SD, *ip_ptr); + ip_ptr += 2; + res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_RTT_SPREAD, *ip_ptr); + ip_ptr += 2; + get_monotonic_boottime(&ts); + tkernel = (u64)TIMESPEC_TO_US(ts); + tm = *ip_ptr; + res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_TIMESTAMP_US, tkernel - (tmac - tm)); + ip_ptr += 4; + res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_BURST_DURATION_MSN, *ip_ptr); + ip_ptr += 2; + res |= nla_put_u8(nl_skb, SLSI_RTT_EVENT_ATTR_NEGOTIATED_BURST_NUM, *ip_ptr++); + for (rep_cnt = 0; rep_cnt < 2; rep_cnt++) { + if (ip_ptr - start_ptr < data_len && ip_ptr[0] == WLAN_EID_MEASURE_REPORT) { + if (ip_ptr[4] == 8) /*LCI Element*/ + res |= nla_put(nl_skb, SLSI_RTT_EVENT_ATTR_LCI, + ip_ptr[1] + 2, ip_ptr); + else if (ip_ptr[4] == 11) /*LCR element */ + res |= nla_put(nl_skb, SLSI_RTT_EVENT_ATTR_LCR, + ip_ptr[1] + 2, ip_ptr); + ip_ptr += ip_ptr[1] + 2; + } + } + nla_nest_end(nl_skb, nlattr_nested); + } + SLSI_DBG_HEX(sdev, SLSI_GSCAN, fapi_get_data(skb), fapi_get_datalen(skb), "range indication skb buffer:\n"); + if (res) { + SLSI_ERR(sdev, "Error in nla_put*:%x\n", res); + kfree_skb(nl_skb); + goto exit; + } + cfg80211_vendor_event(nl_skb, GFP_KERNEL); +exit: + slsi_kfree_skb(skb); + SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex); +} + +void slsi_rx_range_done_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb) +{ + struct netdev_vif *ndev_vif = netdev_priv(dev); + u16 rtt_id = fapi_get_u16(skb, u.mlme_range_ind.rtt_id); + SLSI_MUTEX_LOCK(ndev_vif->vif_mutex); + SLSI_DBG1_NODEV(SLSI_GSCAN, "Event: %s(%d)\n", + slsi_print_event_name(SLSI_NL80211_RTT_COMPLETE_EVENT), SLSI_NL80211_RTT_COMPLETE_EVENT); + slsi_vendor_event(sdev, SLSI_NL80211_RTT_COMPLETE_EVENT, &rtt_id, sizeof(rtt_id)); + slsi_kfree_skb(skb); + SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex); +} + +static int slsi_rtt_cancel_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) +{ + int temp, ret, r = 1, j = 0, type; + struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy); + struct net_device *dev = wdev->netdev; + u8 *addr; + const struct nlattr *iter; + u16 num_devices = 0, rtt_id = 0; + + SLSI_DBG1_NODEV(SLSI_GSCAN, "RTT_SUBCMD_CANCEL_CONFIG\n"); + if (!slsi_dev_rtt_supported()) { + SLSI_WARN(sdev, "RTT not supported.\n"); + return -ENOTSUPP; + } + nla_for_each_attr(iter, data, len, temp) { + type = nla_type(iter); + switch (type) { + case SLSI_RTT_ATTRIBUTE_TARGET_CNT: + num_devices = nla_get_u16(iter); + SLSI_DBG1_NODEV(SLSI_GSCAN, "Target cnt %d\n", num_devices); + break; + case SLSI_RTT_ATTRIBUTE_TARGET_ID: + rtt_id = nla_get_u16(iter); + SLSI_DBG1_NODEV(SLSI_GSCAN, "Target id %d\n", rtt_id); + break; + default: + SLSI_ERR_NODEV("No ATTRIBUTE_Target cnt - %d\n", type); + break; + } + } + /* Allocate memory for the received mac addresses */ + if (num_devices) { + addr = kzalloc(ETH_ALEN * num_devices, GFP_KERNEL); + if (!addr) { + SLSI_ERR_NODEV("Failed for allocate memory for mac addresses\n"); + ret = -ENOMEM; + return ret; + } + nla_for_each_attr(iter, data, len, temp) { + type = nla_type(iter); + if (type == SLSI_RTT_ATTRIBUTE_TARGET_MAC) { + memcpy(&addr[j], nla_data(iter), ETH_ALEN); + j++; + } else { + SLSI_ERR_NODEV("No ATTRIBUTE_MAC - %d\n", type); + } + } + + r = slsi_mlme_del_range_req(sdev, dev, num_devices, addr, rtt_id); + kfree(addr); + } + if (r) + SLSI_ERR_NODEV("Failed to cancel rtt config\n"); + return r; +} + static int slsi_nan_get_new_id(u32 id_map, int max_ids) { int i; @@ -4297,7 +4713,11 @@ void slsi_nan_event(struct slsi_dev *sdev, struct net_device *dev, struct sk_buf slsi_print_event_name(hal_event), hal_event); #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, hal_event, GFP_KERNEL); +#else + nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, hal_event, GFP_KERNEL); +#endif if (!nl_skb) { SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n"); return; @@ -4350,13 +4770,18 @@ void slsi_nan_followup_ind(struct slsi_dev *sdev, struct net_device *dev, struct u8 *fapi_data_p, *ptr; u8 followup_ie_header[] = {0xdd, 0, 0, 0x16, 0x32, 0x0b, 0x05}; int fapi_data_len; - struct slsi_hal_nan_followup_ind hal_evt; + struct slsi_hal_nan_followup_ind *hal_evt; struct sk_buff *nl_skb; int res; struct nlattr *nlattr_start; - hal_evt.publish_subscribe_id = fapi_get_u16(skb, u.mlme_nan_followup_ind.publish_subscribe_id); - hal_evt.requestor_instance_id = fapi_get_u16(skb, u.mlme_nan_followup_ind.requestor_instance_id); + hal_evt = kmalloc(sizeof(*hal_evt), GFP_KERNEL); + if (!hal_evt) { + SLSI_ERR(sdev, "No memory for service_ind\n"); + return; + } + hal_evt->publish_subscribe_id = fapi_get_u16(skb, u.mlme_nan_followup_ind.publish_subscribe_id); + hal_evt->requestor_instance_id = fapi_get_u16(skb, u.mlme_nan_followup_ind.requestor_instance_id); fapi_data_p = fapi_get_data(skb); fapi_data_len = fapi_get_datalen(skb); if (!fapi_data_len) { @@ -4386,10 +4811,10 @@ void slsi_nan_followup_ind(struct slsi_dev *sdev, struct net_device *dev, struct ptr += sizeof(followup_ie_header); - ether_addr_copy(hal_evt.addr, ptr); + ether_addr_copy(hal_evt->addr, ptr); ptr += ETH_ALEN; ptr += 1; /* skip priority */ - hal_evt.dw_or_faw = *ptr; + hal_evt->dw_or_faw = *ptr; ptr += 1; while (fapi_data_p[1] + 2 > (ptr - fapi_data_p) + 4) { tag_id = *(u16 *)ptr; @@ -4401,8 +4826,8 @@ void slsi_nan_followup_ind(struct slsi_dev *sdev, struct net_device *dev, struct return; } if (tag_id == SLSI_FAPI_NAN_SERVICE_SPECIFIC_INFO) { - hal_evt.service_specific_info_len = tag_len; - memcpy(hal_evt.service_specific_info, ptr, tag_len); + hal_evt->service_specific_info_len = tag_len; + memcpy(hal_evt->service_specific_info, ptr, tag_len); } ptr += tag_len; } @@ -4415,35 +4840,43 @@ void slsi_nan_followup_ind(struct slsi_dev *sdev, struct net_device *dev, struct SLSI_DBG1_NODEV(SLSI_GSCAN, "Event: %s(%d)\n", slsi_print_event_name(SLSI_NL80211_NAN_FOLLOWUP_EVENT), SLSI_NL80211_NAN_FOLLOWUP_EVENT); #endif - +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, SLSI_NL80211_NAN_FOLLOWUP_EVENT, GFP_KERNEL); +#else + nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, SLSI_NL80211_NAN_FOLLOWUP_EVENT, + GFP_KERNEL); +#endif + if (!nl_skb) { SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n"); + kfree(hal_evt); return; } nlattr_start = nla_nest_start(nl_skb, NL80211_ATTR_VENDOR_DATA); if (!nlattr_start) { SLSI_ERR(sdev, "failed to put NL80211_ATTR_VENDOR_DATA\n"); + kfree(hal_evt); /* Dont use slsi skb wrapper for this free */ kfree_skb(nl_skb); return; } res = nla_put_be16(nl_skb, NAN_EVT_ATTR_FOLLOWUP_PUBLISH_SUBSCRIBE_ID, - cpu_to_le16(hal_evt.publish_subscribe_id)); + cpu_to_le16(hal_evt->publish_subscribe_id)); res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_FOLLOWUP_REQUESTOR_INSTANCE_ID, - cpu_to_le16(hal_evt.requestor_instance_id)); - res |= nla_put(nl_skb, NAN_EVT_ATTR_FOLLOWUP_ADDR, ETH_ALEN, hal_evt.addr); - res |= nla_put_u8(nl_skb, NAN_EVT_ATTR_FOLLOWUP_DW_OR_FAW, hal_evt.dw_or_faw); - res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO_LEN, hal_evt.service_specific_info_len); - if (hal_evt.service_specific_info_len) - res |= nla_put(nl_skb, NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO, hal_evt.service_specific_info_len, - hal_evt.service_specific_info); + cpu_to_le16(hal_evt->requestor_instance_id)); + res |= nla_put(nl_skb, NAN_EVT_ATTR_FOLLOWUP_ADDR, ETH_ALEN, hal_evt->addr); + res |= nla_put_u8(nl_skb, NAN_EVT_ATTR_FOLLOWUP_DW_OR_FAW, hal_evt->dw_or_faw); + res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO_LEN, hal_evt->service_specific_info_len); + if (hal_evt->service_specific_info_len) + res |= nla_put(nl_skb, NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO, hal_evt->service_specific_info_len, + hal_evt->service_specific_info); if (res) { SLSI_ERR(sdev, "Error in nla_put*:%x\n", res); + kfree(hal_evt); /* Dont use slsi skb wrapper for this free */ kfree_skb(nl_skb); return; @@ -4452,6 +4885,7 @@ void slsi_nan_followup_ind(struct slsi_dev *sdev, struct net_device *dev, struct nla_nest_end(nl_skb, nlattr_start); cfg80211_vendor_event(nl_skb, GFP_KERNEL); + kfree(hal_evt); } void slsi_nan_service_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb) @@ -4580,9 +5014,12 @@ void slsi_nan_service_ind(struct slsi_dev *sdev, struct net_device *dev, struct SLSI_DBG1_NODEV(SLSI_GSCAN, "Event: %s(%d)\n", slsi_print_event_name(SLSI_NL80211_NAN_MATCH_EVENT), SLSI_NL80211_NAN_MATCH_EVENT); #endif - +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, SLSI_NL80211_NAN_MATCH_EVENT, GFP_KERNEL); +#else + nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, SLSI_NL80211_NAN_MATCH_EVENT, GFP_KERNEL); +#endif if (!nl_skb) { SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n"); kfree(hal_evt); @@ -4753,6 +5190,112 @@ exit: return ret; } +static int slsi_get_roaming_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) +{ + struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy); + struct net_device *dev = wdev->netdev; + struct netdev_vif *ndev_vif; + int ret = 0; + struct slsi_mib_value *values = NULL; + struct slsi_mib_data mibrsp = { 0, NULL }; + struct slsi_mib_get_entry get_values[] = {{ SLSI_PSID_UNIFI_ROAM_BLACKLIST_SIZE, { 0, 0 } } }; + u32 max_blacklist_size = 0; + u32 max_whitelist_size = 0; + struct sk_buff *nl_skb; + struct nlattr *nlattr_start; + + if (!dev) { + SLSI_ERR(sdev, "dev is NULL!!\n"); + return -EINVAL; + } + + ndev_vif = netdev_priv(dev); + + SLSI_MUTEX_LOCK(ndev_vif->vif_mutex); + + mibrsp.dataLength = 10; + mibrsp.data = kmalloc(mibrsp.dataLength, GFP_KERNEL); + if (!mibrsp.data) { + SLSI_ERR(sdev, "Cannot kmalloc %d bytes\n", mibrsp.dataLength); + ret = -ENOMEM; + goto exit; + } + values = slsi_read_mibs(sdev, NULL, get_values, ARRAY_SIZE(get_values), &mibrsp); + if (values && (values[0].type == SLSI_MIB_TYPE_UINT || values[0].type == SLSI_MIB_TYPE_INT)) + max_blacklist_size = values[0].u.uintValue; + nl_skb = cfg80211_vendor_cmd_alloc_reply_skb(sdev->wiphy, NLMSG_DEFAULT_SIZE); + if (!nl_skb) { + SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n"); + ret = -ENOMEM; + goto exit_with_mib_resp; + } + + nlattr_start = nla_nest_start(nl_skb, NL80211_ATTR_VENDOR_DATA); + if (!nlattr_start) { + SLSI_ERR(sdev, "failed to put NL80211_ATTR_VENDOR_DATA\n"); + /* Dont use slsi skb wrapper for this free */ + kfree_skb(nl_skb); + ret = -EINVAL; + goto exit_with_mib_resp; + } + + ret = nla_put_u32(nl_skb, SLSI_NL_ATTR_MAX_BLACKLIST_SIZE, max_blacklist_size); + ret |= nla_put_u32(nl_skb, SLSI_NL_ATTR_MAX_WHITELIST_SIZE, max_whitelist_size); + if (ret) { + SLSI_ERR(sdev, "Error in nla_put*:%x\n", ret); + /* Dont use slsi skb wrapper for this free */ + kfree_skb(nl_skb); + goto exit_with_mib_resp; + } + + ret = cfg80211_vendor_cmd_reply(nl_skb); + if (ret) + SLSI_ERR(sdev, "cfg80211_vendor_cmd_reply failed :%d\n", ret); +exit_with_mib_resp: + kfree(mibrsp.data); + kfree(values); +exit: + SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex); + return ret; +} + +static int slsi_set_roaming_state(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) +{ + struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy); + struct net_device *dev = wdev->netdev; + int temp = 0; + int type = 0; + const struct nlattr *attr; + int ret = 0; + int roam_state = 0; + + if (!dev) { + SLSI_WARN_NODEV("net_dev is NULL\n"); + return -EINVAL; + } + + nla_for_each_attr(attr, data, len, temp) { + type = nla_type(attr); + switch (type) { + case SLSI_NL_ATTR_ROAM_STATE: + roam_state = nla_get_u8(attr); + break; + default: + SLSI_ERR_NODEV("Unknown attribute: %d\n", type); + ret = -EINVAL; + goto exit; + } + } + + SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_SET_ROAMING_STATE roam_state = %d\n", roam_state); + ret = slsi_set_mib_roam(sdev, NULL, SLSI_PSID_UNIFI_ROAMING_ENABLED, roam_state); + if (ret < 0) + SLSI_ERR_NODEV("Failed to set roaming state\n"); + +exit: + return ret; +} + #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING static void slsi_on_ring_buffer_data(char *ring_name, char *buffer, int buffer_size, struct scsc_wifi_ring_buffer_status *buffer_status, void *ctx) @@ -5324,7 +5867,10 @@ void slsi_rx_event_log_indication(struct slsi_dev *sdev, struct net_device *dev, timestamp = fapi_get_u64(skb, u.mlme_event_log_ind.timestamp); SLSI_DBG3(sdev, SLSI_GSCAN, "slsi_rx_event_log_indication, event id = %d, timestamp = %d\n", event_id, timestamp); +#ifdef CONFIG_SCSC_WIFILOGGER SCSC_WLOG_FW_EVENT(WLOG_NORMAL, event_id, timestamp, fapi_get_data(skb), fapi_get_datalen(skb)); +#endif + slsi_kfree_skb(skb); SLSI_MUTEX_UNLOCK(sdev->logger_mutex); } @@ -5630,8 +6176,18 @@ static const struct nl80211_vendor_cmd_info slsi_vendor_events[] = { { OUI_GOOGLE, SLSI_NL80211_RSSI_REPORT_EVENT}, #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING { OUI_GOOGLE, SLSI_NL80211_LOGGER_RING_EVENT}, - { OUI_GOOGLE, SLSI_NL80211_LOGGER_FW_DUMP_EVENT} + { OUI_GOOGLE, SLSI_NL80211_LOGGER_FW_DUMP_EVENT}, #endif + { OUI_GOOGLE, SLSI_NL80211_NAN_RESPONSE_EVENT}, + { OUI_GOOGLE, SLSI_NL80211_NAN_PUBLISH_TERMINATED_EVENT}, + { OUI_GOOGLE, SLSI_NL80211_NAN_MATCH_EVENT}, + { OUI_GOOGLE, SLSI_NL80211_NAN_MATCH_EXPIRED_EVENT}, + { OUI_GOOGLE, SLSI_NL80211_NAN_SUBSCRIBE_TERMINATED_EVENT}, + { OUI_GOOGLE, SLSI_NL80211_NAN_FOLLOWUP_EVENT}, + { OUI_GOOGLE, SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT}, + { OUI_GOOGLE, SLSI_NL80211_NAN_DISABLED_EVENT}, + { OUI_GOOGLE, SLSI_NL80211_RTT_RESULT_EVENT}, + { OUI_GOOGLE, SLSI_NL80211_RTT_COMPLETE_EVENT} }; static const struct wiphy_vendor_command slsi_vendor_cmd[] = { @@ -6014,8 +6570,47 @@ static const struct wiphy_vendor_command slsi_vendor_cmd[] = { }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, .doit = slsi_nan_get_capabilities + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_ROAMING_CAPABILITIES + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = slsi_get_roaming_capabilities + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = SLSI_NL80211_VENDOR_SUBCMD_SET_ROAMING_STATE + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = slsi_set_roaming_state + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = SLSI_NL80211_VENDOR_SUBCMD_RTT_GET_CAPABILITIES + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = slsi_rtt_get_capabilities + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_START + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = slsi_rtt_set_config + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_CANCEL + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = slsi_rtt_cancel_config } - }; void slsi_nl80211_vendor_deinit(struct slsi_dev *sdev) @@ -6051,5 +6646,4 @@ void slsi_nl80211_vendor_init(struct slsi_dev *sdev) sdev->gscan_hash_table[i] = NULL; INIT_LIST_HEAD(&sdev->hotlist_results); - } diff --git a/drivers/net/wireless/scsc/nl80211_vendor.h b/drivers/net/wireless/scsc/nl80211_vendor.h index f604887f7ee7..68c841c11a5a 100755 --- a/drivers/net/wireless/scsc/nl80211_vendor.h +++ b/drivers/net/wireless/scsc/nl80211_vendor.h @@ -12,6 +12,7 @@ #define SLSI_NL80211_GSCAN_EVENT_RANGE_START 0x01 #define SLSI_NL80211_LOGGING_SUBCMD_RANGE_START 0x1400 #define SLSI_NL80211_NAN_SUBCMD_RANGE_START 0x1500 +#define SLSI_NL80211_RTT_SUBCMD_RANGE_START 0x1100 #define SLSI_GSCAN_SCAN_ID_START 0x410 #define SLSI_GSCAN_SCAN_ID_END 0x500 @@ -82,12 +83,19 @@ #define SLSI_WIFI_HAL_FEATURE_HAL_EPNO 0x040000 /* WiFi PNO enhanced */ #define SLSI_WIFI_HAL_FEATURE_RSSI_MONITOR 0x080000 /* RSSI Monitor */ #define SLSI_WIFI_HAL_FEATURE_MKEEP_ALIVE 0x100000 /* WiFi mkeep_alive */ +#define SLSI_WIFI_HAL_FEATURE_CONTROL_ROAMING 0x800000 /* Enable/Disable firmware roaming macro */ enum slsi_wifi_attr { SLSI_NL_ATTRIBUTE_ND_OFFLOAD_VALUE = 0, SLSI_NL_ATTRIBUTE_PNO_RANDOM_MAC_OUI }; +enum SLSI_ROAM_ATTRIBUTES { + SLSI_NL_ATTR_MAX_BLACKLIST_SIZE, + SLSI_NL_ATTR_MAX_WHITELIST_SIZE, + SLSI_NL_ATTR_ROAM_STATE +}; + enum SLSI_NAN_REPLY_ATTRIBUTES { NAN_REPLY_ATTR_STATUS_TYPE, NAN_REPLY_ATTR_VALUE, @@ -451,6 +459,8 @@ enum slsi_hal_vendor_subcmds { SLSI_NL80211_VENDOR_SUBCMD_GET_FEATURE_SET, SLSI_NL80211_VENDOR_SUBCMD_SET_COUNTRY_CODE, SLSI_NL80211_VENDOR_SUBCMD_CONFIGURE_ND_OFFLOAD, + SLSI_NL80211_VENDOR_SUBCMD_GET_ROAMING_CAPABILITIES, + SLSI_NL80211_VENDOR_SUBCMD_SET_ROAMING_STATE, SLSI_NL80211_VENDOR_SUBCMD_START_LOGGING = SLSI_NL80211_LOGGING_SUBCMD_RANGE_START, SLSI_NL80211_VENDOR_SUBCMD_TRIGGER_FW_MEM_DUMP, SLSI_NL80211_VENDOR_SUBCMD_GET_FW_MEM_DUMP, @@ -473,7 +483,10 @@ enum slsi_hal_vendor_subcmds { SLSI_NL80211_VENDOR_SUBCMD_NAN_SUBSCRIBECANCEL, SLSI_NL80211_VENDOR_SUBCMD_NAN_TXFOLLOWUP, SLSI_NL80211_VENDOR_SUBCMD_NAN_CONFIG, - SLSI_NL80211_VENDOR_SUBCMD_NAN_CAPABILITIES + SLSI_NL80211_VENDOR_SUBCMD_NAN_CAPABILITIES, + SLSI_NL80211_VENDOR_SUBCMD_RTT_GET_CAPABILITIES = SLSI_NL80211_RTT_SUBCMD_RANGE_START, + SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_START, + SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_CANCEL }; enum slsi_supp_vendor_subcmds { @@ -501,7 +514,10 @@ enum slsi_vendor_event_values { SLSI_NL80211_NAN_MATCH_EXPIRED_EVENT, SLSI_NL80211_NAN_SUBSCRIBE_TERMINATED_EVENT, SLSI_NL80211_NAN_FOLLOWUP_EVENT, - SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT + SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT, + SLSI_NL80211_NAN_DISABLED_EVENT, + SLSI_NL80211_RTT_RESULT_EVENT, + SLSI_NL80211_RTT_COMPLETE_EVENT }; enum slsi_lls_interface_mode { @@ -601,6 +617,127 @@ enum slsi_enhanced_logging_attributes { SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_OTHER_RX_MULTICAST_CNT, }; +enum slsi_rtt_event_attributes { + SLSI_RTT_EVENT_ATTR_ADDR = 0, + SLSI_RTT_EVENT_ATTR_BURST_NUM, + SLSI_RTT_EVENT_ATTR_MEASUREMENT_NUM, + SLSI_RTT_EVENT_ATTR_SUCCESS_NUM, + SLSI_RTT_EVENT_ATTR_NUM_PER_BURST_PEER, + SLSI_RTT_EVENT_ATTR_STATUS, + SLSI_RTT_EVENT_ATTR_RETRY_AFTER_DURATION, + SLSI_RTT_EVENT_ATTR_TYPE, + SLSI_RTT_EVENT_ATTR_RSSI, + SLSI_RTT_EVENT_ATTR_RSSI_SPREAD, + SLSI_RTT_EVENT_ATTR_TX_PREAMBLE, + SLSI_RTT_EVENT_ATTR_TX_NSS, + SLSI_RTT_EVENT_ATTR_TX_BW, + SLSI_RTT_EVENT_ATTR_TX_MCS, + SLSI_RTT_EVENT_ATTR_TX_RATE, + SLSI_RTT_EVENT_ATTR_RX_PREAMBLE, + SLSI_RTT_EVENT_ATTR_RX_NSS, + SLSI_RTT_EVENT_ATTR_RX_BW, + SLSI_RTT_EVENT_ATTR_RX_MCS, + SLSI_RTT_EVENT_ATTR_RX_RATE, + SLSI_RTT_EVENT_ATTR_RTT, + SLSI_RTT_EVENT_ATTR_RTT_SD, + SLSI_RTT_EVENT_ATTR_RTT_SPREAD, + SLSI_RTT_EVENT_ATTR_DISTANCE_MM, + SLSI_RTT_EVENT_ATTR_DISTANCE_SD_MM, + SLSI_RTT_EVENT_ATTR_DISTANCE_SPREAD_MM, + SLSI_RTT_EVENT_ATTR_TIMESTAMP_US, + SLSI_RTT_EVENT_ATTR_BURST_DURATION_MSN, + SLSI_RTT_EVENT_ATTR_NEGOTIATED_BURST_NUM, + SLSI_RTT_EVENT_ATTR_LCI, + SLSI_RTT_EVENT_ATTR_LCR, + +}; + +/* RTT peer type */ +enum slsi_rtt_peer_type { + SLSI_RTT_PEER_AP = 0x1, + SLSI_RTT_PEER_STA, + SLSI_RTT_PEER_P2P_GO, + SLSI_RTT_PEER_P2P_CLIENT, + SLSI_RTT_PEER_NAN, +}; + +/* RTT Measurement Bandwidth */ +enum slsi_wifi_rtt_bw { + SLSI_WIFI_RTT_BW_5 = 0x01, + SLSI_WIFI_RTT_BW_10 = 0x02, + SLSI_WIFI_RTT_BW_20 = 0x04, + SLSI_WIFI_RTT_BW_40 = 0x08, + SLSI_WIFI_RTT_BW_80 = 0x10, + SLSI_WIFI_RTT_BW_160 = 0x20 +}; + +/* RTT Measurement Preamble */ +enum slsi_wifi_rtt_preamble { + SLSI_WIFI_RTT_PREAMBLE_LEGACY = 0x1, + SLSI_WIFI_RTT_PREAMBLE_HT = 0x2, + SLSI_WIFI_RTT_PREAMBLE_VHT = 0x4 +}; + +/* RTT Type */ +enum slsi_wifi_rtt_type { + SLSI_RTT_TYPE_1_SIDED = 0x1, + SLSI_RTT_TYPE_2_SIDED, +}; + +enum slsi_rtt_attribute { + SLSI_RTT_ATTRIBUTE_TARGET_CNT = 0, + SLSI_RTT_ATTRIBUTE_TARGET_INFO, + SLSI_RTT_ATTRIBUTE_TARGET_MAC, + SLSI_RTT_ATTRIBUTE_TARGET_TYPE, + SLSI_RTT_ATTRIBUTE_TARGET_PEER, + SLSI_RTT_ATTRIBUTE_TARGET_CHAN_WIDTH, + SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ, + SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ0, + SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ1, + SLSI_RTT_ATTRIBUTE_TARGET_PERIOD, + SLSI_RTT_ATTRIBUTE_TARGET_NUM_BURST, + SLSI_RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST, + SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM, + SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR, + SLSI_RTT_ATTRIBUTE_TARGET_LCI, + SLSI_RTT_ATTRIBUTE_TARGET_LCR, + SLSI_RTT_ATTRIBUTE_TARGET_BURST_DURATION, + SLSI_RTT_ATTRIBUTE_TARGET_PREAMBLE, + SLSI_RTT_ATTRIBUTE_TARGET_BW, + SLSI_RTT_ATTRIBUTE_RESULTS_COMPLETE = 30, + SLSI_RTT_ATTRIBUTE_RESULTS_PER_TARGET, + SLSI_RTT_ATTRIBUTE_RESULT_CNT, + SLSI_RTT_ATTRIBUTE_RESULT, + SLSI_RTT_ATTRIBUTE_TARGET_ID +}; + +/* Ranging status */ +enum slsi_wifi_rtt_status { + SLSI_RTT_STATUS_SUCCESS = 0, + SLSI_RTT_STATUS_FAILURE, /* general failure status */ + SLSI_RTT_STATUS_FAIL_NO_RSP, /* target STA does not respond to request */ + SLSI_RTT_STATUS_FAIL_REJECTED, /* request rejected. Applies to 2-sided RTT only*/ + SLSI_RTT_STATUS_FAIL_NOT_SCHEDULED_YET, + SLSI_RTT_STATUS_FAIL_TM_TIMEOUT, /* timing measurement times out */ + SLSI_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, /* Target on different channel, cannot range */ + SLSI_RTT_STATUS_FAIL_NO_CAPABILITY, /* ranging not supported */ + SLSI_RTT_STATUS_ABORTED, /* request aborted for unknown reason */ + SLSI_RTT_STATUS_FAIL_INVALID_TS, /* Invalid T1-T4 timestamp */ + SLSI_RTT_STATUS_FAIL_PROTOCOL, /* 11mc protocol failed */ + SLSI_RTT_STATUS_FAIL_SCHEDULE, /* request could not be scheduled */ + SLSI_RTT_STATUS_FAIL_BUSY_TRY_LATER, /* responder cannot collaborate at time of request */ + SLSI_RTT_STATUS_INVALID_REQ, /* bad request args */ + SLSI_RTT_STATUS_NO_WIFI, /* WiFi not enabled */ + SLSI_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE /* Responder overrides param info, cannot range with new params */ +}; + +/* Format of information elements found in the beacon */ +struct slsi_wifi_information_element { + u8 id; /* element identifier */ + u8 len; /* number of bytes to follow */ + u8 data[]; +}; + struct slsi_nl_gscan_capabilities { int max_scan_cache_size; int max_scan_buckets; @@ -1413,6 +1550,68 @@ struct slsi_hal_nan_match_ind { u8 cluster_attribute[32]; }; +struct slsi_rtt_capabilities { + u8 rtt_one_sided_supported; /* if 1-sided rtt data collection is supported */ + u8 rtt_ftm_supported; /* if ftm rtt data collection is supported */ + u8 lci_support; /* if initiator supports LCI request. Applies to 2-sided RTT */ + u8 lcr_support; /* if initiator supports LCR request. Applies to 2-sided RTT */ + u8 preamble_support; /* bit mask indicates what preamble is supported by initiator */ + u8 bw_support; /* bit mask indicates what BW is supported by initiator */ + u8 responder_supported; /* if 11mc responder mode is supported */ + u8 mc_version; /* draft 11mc spec version supported by chip. For instance, + *version 4.0 should be 40 and version 4.3 should be 43 etc. + */ +}; + +/* RTT configuration */ +struct slsi_rtt_config { + u8 source_addr[ETH_ALEN]; + u8 peer_addr[ETH_ALEN]; /* peer device mac address */ + u16 type; /* 1-sided or 2-sided RTT */ + u16 channel_freq; /* Required for STA-AP mode, optional for P2P, NBD etc. */ + u16 channel_info; + u8 burst_period; /* Time interval between bursts (units: 100 ms). */ + /* Applies to 1-sided and 2-sided RTT multi-burst requests. + *Range: 0-31, 0: no preference by initiator (2-sided RTT) + */ + u8 num_burst; /* Total number of RTT bursts to be executed. It will be + *specified in the same way as the parameter "Number of + *Burst Exponent" found in the FTM frame format. It + *applies to both: 1-sided RTT and 2-sided RTT. Valid + *values are 0 to 15 as defined in 802.11mc std + *0 means single shot + *The implication of this parameter on the maximum + *number of RTT results is the following: + *for 1-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst) + *for 2-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst - 1) + */ + u8 num_frames_per_burst; /* num of frames per burst. + *Minimum value = 1, Maximum value = 31 + *For 2-sided this equals the number of FTM frames + *to be attempted in a single burst. This also + *equals the number of FTM frames that the + *initiator will request that the responder send + *in a single frame. + */ + u8 num_retries_per_ftmr; /* Maximum number of retries that the initiator can + *retry an FTMR frame. + *Minimum value = 0, Maximum value = 3 + */ + u8 burst_duration; /* Applies to 1-sided and 2-sided RTT. Valid values will + *be 2-11 and 15 as specified by the 802.11mc std for + *the FTM parameter burst duration. In a multi-burst + *request, if responder overrides with larger value, + *the initiator will return failure. In a single-burst + *request if responder overrides with larger value, + *the initiator will sent TMR_STOP to terminate RTT + *at the end of the burst_duration it requested. + */ + u16 preamble; /* RTT preamble to be used in the RTT frames */ + u16 bw; /* RTT BW to be used in the RTT frames */ + u16 LCI_request; /* 1: request LCI, 0: do not request LCI */ + u16 LCR_request; /* 1: request LCR, 0: do not request LCR */ +}; + void slsi_nl80211_vendor_init(struct slsi_dev *sdev); void slsi_nl80211_vendor_deinit(struct slsi_dev *sdev); u8 slsi_gscan_get_scan_policy(enum wifi_band band); @@ -1425,6 +1624,13 @@ int slsi_gscan_alloc_buckets(struct slsi_dev *sdev, struct slsi_gscan *gscan, in int slsi_vendor_event(struct slsi_dev *sdev, int event_id, const void *data, int len); int slsi_mib_get_gscan_cap(struct slsi_dev *sdev, struct slsi_nl_gscan_capabilities *cap); void slsi_rx_rssi_report_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); +int slsi_mib_get_rtt_cap(struct slsi_dev *sdev, struct net_device *dev, struct slsi_rtt_capabilities *cap); +int slsi_mlme_add_range_req(struct slsi_dev *sdev, u8 count, struct slsi_rtt_config *nl_rtt_params, + u16 rtt_id, u16 vif_idx); +int slsi_mlme_del_range_req(struct slsi_dev *sdev, struct net_device *dev, u16 count, u8 *addr, u16 rtt_id); +void slsi_rx_range_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); +void slsi_rx_range_done_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); +int slsi_tx_rate_calc(struct sk_buff *nl_skb, u16 fw_rate, int res, bool tx_rate); void slsi_check_num_radios(struct slsi_dev *sdev); #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING void slsi_rx_event_log_indication(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); @@ -1456,4 +1662,5 @@ static inline enum slsi_lls_traffic_ac slsi_fapi_to_android_traffic_q(enum slsi_ return SLSI_LLS_AC_MAX; } } + #endif diff --git a/drivers/net/wireless/scsc/procfs.c b/drivers/net/wireless/scsc/procfs.c index c017af574fb9..1ef94dd567a7 100755 --- a/drivers/net/wireless/scsc/procfs.c +++ b/drivers/net/wireless/scsc/procfs.c @@ -103,6 +103,57 @@ static ssize_t slsi_procfs_mutex_stats_read(struct file *file, char __user *use } #endif +static ssize_t slsi_procfs_throughput_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[5 * 25]; + int pos = 0; + const size_t bufsz = sizeof(buf); + struct slsi_dev *sdev = (struct slsi_dev *)file->private_data; + struct net_device *dev; + struct slsi_mib_data mibrsp = { 0, NULL }; + struct slsi_mib_value *values = NULL; + struct slsi_mib_get_entry get_values[] = {{ SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 2, 0 } }, + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 3, 0 } }, + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 4, 0 } }, + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 24, 0 } }, + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 29, 0 } } }; + + SLSI_UNUSED_PARAMETER(file); + + dev = slsi_get_netdev(sdev, 1); + + mibrsp.dataLength = 15 * ARRAY_SIZE(get_values); + mibrsp.data = kmalloc(mibrsp.dataLength, GFP_KERNEL); + if (!mibrsp.data) + SLSI_ERR(sdev, "Cannot kmalloc %d bytes\n", mibrsp.dataLength); + values = slsi_read_mibs(sdev, dev, get_values, ARRAY_SIZE(get_values), &mibrsp); + if (!values) { + kfree(mibrsp.data); + return -EINVAL; + } + if (values[0].type != SLSI_MIB_TYPE_UINT) + SLSI_ERR(sdev, "invalid type. iter:%d", 0); /*bad_fcs_count*/ + if (values[1].type != SLSI_MIB_TYPE_UINT) + SLSI_ERR(sdev, "invalid type. iter:%d", 1); /*missed_ba_count*/ + if (values[2].type != SLSI_MIB_TYPE_UINT) + SLSI_ERR(sdev, "invalid type. iter:%d", 2); /*missed_ack_count*/ + if (values[3].type != SLSI_MIB_TYPE_UINT) + SLSI_ERR(sdev, "invalid type. iter:%d", 3); /*mac_bad_sig_count*/ + if (values[4].type != SLSI_MIB_TYPE_UINT) + SLSI_ERR(sdev, "invalid type. iter:%d", 4); /*rx_error_count*/ + + pos += scnprintf(buf, bufsz, "RX FCS: %d\n", values[0].u.uintValue); + pos += scnprintf(buf + pos, bufsz - pos, "RX bad SIG: %d\n", values[3].u.uintValue); + pos += scnprintf(buf + pos, bufsz - pos, "RX dot11 error: %d\n", values[4].u.uintValue); + pos += scnprintf(buf + pos, bufsz - pos, "TX MPDU no ACK: %d\n", values[2].u.uintValue); + pos += scnprintf(buf + pos, bufsz - pos, "TX A-MPDU no ACK: %d\n", values[1].u.uintValue); + + kfree(values); + kfree(mibrsp.data); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + static ssize_t slsi_procfs_sta_bss_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { char buf[100]; @@ -257,9 +308,13 @@ static int slsi_procfs_status_show(struct seq_file *m, void *v) seq_printf(m, "HW Version [MIB] : 0x%.4X (%u)\n", sdev->chip_info_mib.chip_version, sdev->chip_info_mib.chip_version); seq_printf(m, "Platform Build [MIB] : 0x%.4X (%u)\n", sdev->plat_info_mib.plat_build, sdev->plat_info_mib.plat_build); - for (i = 0; i < SLSI_WLAN_MAX_MIB_FILE; i++) + for (i = 0; i < SLSI_WLAN_MAX_MIB_FILE; i++) { seq_printf(m, "Hash [MIB%2d] : 0x%.4X (%u)\n", i, sdev->mib[i].mib_hash, sdev->mib[i].mib_hash); + seq_printf(m, "Platform: [MIB%2d] : %s\n", i, sdev->mib[i].platform); + } seq_printf(m, "Hash [local_MIB] : 0x%.4X (%u)\n", sdev->local_mib.mib_hash, sdev->local_mib.mib_hash); + seq_printf(m, "Platform: [local_MIB] : %s\n", sdev->local_mib.platform); + return 0; } @@ -995,6 +1050,7 @@ SLSI_PROCFS_READ_FILE_OPS(mutex_stats); #endif SLSI_PROCFS_READ_FILE_OPS(sta_bss); SLSI_PROCFS_READ_FILE_OPS(big_data); +SLSI_PROCFS_READ_FILE_OPS(throughput_stats); SLSI_PROCFS_SEQ_FILE_OPS(tcp_ack_suppression); int slsi_create_proc_dir(struct slsi_dev *sdev) @@ -1030,6 +1086,7 @@ int slsi_create_proc_dir(struct slsi_dev *sdev) #endif SLSI_PROCFS_ADD_FILE(sdev, sta_bss, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); SLSI_PROCFS_ADD_FILE(sdev, big_data, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + SLSI_PROCFS_ADD_FILE(sdev, throughput_stats, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); SLSI_PROCFS_SEQ_ADD_FILE(sdev, tcp_ack_suppression, sdev->procfs_dir, S_IRUSR | S_IRGRP); } @@ -1064,6 +1121,7 @@ void slsi_remove_proc_dir(struct slsi_dev *sdev) #endif SLSI_PROCFS_REMOVE_FILE(sta_bss, sdev->procfs_dir); SLSI_PROCFS_REMOVE_FILE(big_data, sdev->procfs_dir); + SLSI_PROCFS_REMOVE_FILE(throughput_stats, sdev->procfs_dir); SLSI_PROCFS_REMOVE_FILE(tcp_ack_suppression, sdev->procfs_dir); (void)snprintf(dir, sizeof(dir), "driver/unifi%d", sdev->procfs_instance); diff --git a/drivers/net/wireless/scsc/rx.c b/drivers/net/wireless/scsc/rx.c index cb01ff4d17dc..16e3b24673df 100755 --- a/drivers/net/wireless/scsc/rx.c +++ b/drivers/net/wireless/scsc/rx.c @@ -17,7 +17,10 @@ #include "cac.h" #include "nl80211_vendor.h" +#ifdef CONFIG_ANDROID #include "scsc_wifilogger_rings.h" +#endif + #ifdef CONFIG_SCSC_LOG_COLLECTION #include #endif @@ -500,8 +503,8 @@ void slsi_scan_complete(struct slsi_dev *sdev, struct net_device *dev, u16 scan_ } scan = slsi_dequeue_cached_scan_result(&ndev_vif->scan[scan_id], result_count); } - SLSI_NET_DBG3(dev, SLSI_MLME, "interface:%d, scan_id:%d, scan_results_count:%d %s\n", - ndev_vif->ifnum, scan_id, scan_results_count, + SLSI_INFO(sdev, "Scan count:%d APs\n", scan_results_count); + SLSI_NET_DBG3(dev, SLSI_MLME, "interface:%d, scan_id:%d,%s\n", ndev_vif->ifnum, scan_id, more_than_max_count ? "Scan results overflow" : ""); slsi_roam_channel_cache_prune(dev, SLSI_ROAMING_CHANNEL_CACHE_TIMEOUT); @@ -605,6 +608,7 @@ void slsi_rx_channel_switched_ind(struct slsi_dev *sdev, struct net_device *dev, ndev_vif->ap.channel_freq = freq; /* updated for GETSTAINFO */ cfg80211_ch_switch_notify(dev, &chandef); + slsi_kfree_skb(skb); } void __slsi_rx_blockack_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb) @@ -970,10 +974,12 @@ void slsi_rx_roamed_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk ndev_vif->sta.roam_in_progress = false; ndev_vif->chan = ndev_vif->sta.sta_bss->channel; -#ifndef SLSI_TEST_DEV +#if !defined SLSI_TEST_DEV && defined CONFIG_ANDROID SLSI_NET_DBG1(dev, SLSI_MLME, "Taking a wakelock for DHCP to finish after roaming\n"); wake_lock_timeout(&sdev->wlan_wl_roam, msecs_to_jiffies(10 * 1000)); +#ifdef CONFIG_SCSC_WIFILOGGER SCSC_WLOG_WAKELOCK(WLOG_NORMAL, WL_TAKEN, "wlan_wl_roam", WL_REASON_ROAM); +#endif #endif if (!temporal_keys_required) { @@ -1028,7 +1034,7 @@ static void slsi_tdls_event_discovered(struct slsi_dev *sdev, struct net_device SLSI_MUTEX_LOCK(ndev_vif->vif_mutex); - SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_tdls_event_discovered\n"); + SLSI_INFO(sdev, "\n"); if (len != 0) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) @@ -1056,7 +1062,7 @@ static void slsi_tdls_event_connected(struct slsi_dev *sdev, struct net_device * ndev_vif->sta.tdls_enabled = true; - SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_tdls_event_connected(vif:%d, peer_index:%d mac[%pM])\n", + SLSI_INFO(sdev, "(vif:%d, peer_index:%d mac[%pM])\n", fapi_get_vif(skb), peer_index, fapi_get_buff(skb, u.mlme_tdls_peer_ind.peer_sta_address)); if (!ndev_vif->activated) { @@ -1113,7 +1119,8 @@ static void slsi_tdls_event_disconnected(struct slsi_dev *sdev, struct net_devic if (WARN_ON(!dev)) goto exit; - SLSI_NET_DBG1(dev, SLSI_MLME, "slsi_tdls_event_disconnected(vif:%d, MAC:%pM)\n", ndev_vif->ifnum, fapi_get_buff(skb, u.mlme_tdls_peer_ind.peer_sta_address)); + SLSI_INFO(sdev, "(vif:%d, MAC:%pM)\n", ndev_vif->ifnum, + fapi_get_buff(skb, u.mlme_tdls_peer_ind.peer_sta_address)); if (!ndev_vif->activated) { SLSI_NET_DBG1(dev, SLSI_MLME, "VIF not activated\n"); @@ -1768,8 +1775,8 @@ void slsi_rx_frame_transmission_ind(struct slsi_dev *sdev, struct net_device *de if (tx_status != FAPI_TRANSMISSIONSTATUS_SUCCESSFUL) { ack = false; if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif)) { - if (sdev->hs2_state == HS2_VIF_TX) - sdev->hs2_state = HS2_VIF_ACTIVE; /*We wouldn't delete VIF*/ + if (sdev->wlan_unsync_vif_state == WLAN_UNSYNC_VIF_TX) + sdev->wlan_unsync_vif_state = WLAN_UNSYNC_VIF_ACTIVE; /*We wouldn't delete VIF*/ } else { if (sdev->p2p_group_exp_frame != SLSI_P2P_PA_INVALID) slsi_clear_offchannel_data(sdev, false); @@ -1898,9 +1905,9 @@ void slsi_rx_received_frame_ind(struct slsi_dev *sdev, struct net_device *dev, s if (mgmt->u.action.category == WLAN_CATEGORY_WMM) { cac_rx_wmm_action(sdev, dev, mgmt, mgmt_len); } else { - slsi_hs2_dump_public_action_subtype(mgmt, false); - if (sdev->hs2_state == HS2_VIF_TX) - sdev->hs2_state = HS2_VIF_ACTIVE; + slsi_wlan_dump_public_action_subtype(mgmt, false); + if (sdev->wlan_unsync_vif_state == WLAN_UNSYNC_VIF_TX) + sdev->wlan_unsync_vif_state = WLAN_UNSYNC_VIF_ACTIVE; } #ifdef CONFIG_SCSC_WLAN_WES_NCHO } @@ -1966,7 +1973,7 @@ void slsi_rx_received_frame_ind(struct slsi_dev *sdev, struct net_device *dev, s skb_pull(skb, fapi_get_siglen(skb)); skb->dev = dev; - skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->ip_summed = CHECKSUM_NONE; ndev_vif->stats.rx_packets++; ndev_vif->stats.rx_bytes += skb->len; @@ -2047,21 +2054,6 @@ void slsi_rx_listen_end_ind(struct net_device *dev, struct sk_buff *skb) slsi_kfree_skb(skb); } -#ifdef CONFIG_SCSC_WLAN_RX_NAPI -static int slsi_rx_msdu_napi(struct net_device *dev, struct sk_buff *skb) -{ - struct netdev_vif *ndev_vif = netdev_priv(dev); - - slsi_skb_queue_tail(&ndev_vif->napi.rx_data, skb); - slsi_spinlock_lock(&ndev_vif->napi.lock); - if (ndev_vif->napi.interrupt_enabled) { - ndev_vif->napi.interrupt_enabled = false; - napi_schedule(&ndev_vif->napi.napi); - } - slsi_spinlock_unlock(&ndev_vif->napi.lock); -} -#endif - static int slsi_rx_wait_ind_match(u16 recv_id, u16 wait_id) { if (recv_id == wait_id) diff --git a/drivers/net/wireless/scsc/sap_ma.c b/drivers/net/wireless/scsc/sap_ma.c index b2d54dea308f..2f7c49b275af 100755 --- a/drivers/net/wireless/scsc/sap_ma.c +++ b/drivers/net/wireless/scsc/sap_ma.c @@ -15,7 +15,9 @@ #include "hip4_sampler.h" #include "traffic_monitor.h" +#ifdef CONFIG_ANDROID #include "scsc_wifilogger_rings.h" +#endif #define SUPPORTED_OLD_VERSION 0 @@ -89,21 +91,20 @@ static int sap_ma_version_supported(u16 version) return -EINVAL; } -static int slsi_rx_amsdu_deaggregate(struct net_device *dev, struct sk_buff *skb) +static int slsi_rx_amsdu_deaggregate(struct net_device *dev, struct sk_buff *skb, struct sk_buff_head *msdu_list) { - struct netdev_vif *ndev_vif = netdev_priv(dev); - struct slsi_dev *sdev = ndev_vif->sdev; unsigned int msdu_len; unsigned int subframe_len; int padding; struct sk_buff *subframe = NULL; + bool last_sub_frame = false; const unsigned char mac_0[ETH_ALEN] = { 0 }; bool skip_frame = false; struct ethhdr *mh; SLSI_NET_DBG4(dev, SLSI_RX, "A-MSDU received (len:%d)\n", skb->len); - while (skb != subframe) { + while (!last_sub_frame) { msdu_len = (skb->data[ETH_ALEN * 2] << 8) | skb->data[(ETH_ALEN * 2) + 1]; /* check if the length of sub-frame is valid */ @@ -118,13 +119,14 @@ static int slsi_rx_amsdu_deaggregate(struct net_device *dev, struct sk_buff *skb /* For the last subframe skb length and subframe length will be same */ if (skb->len == subframe_len) { /* Use the original skb for the last subframe */ - subframe = skb; + subframe = slsi_skb_copy(skb, GFP_ATOMIC); /* There is no padding for last subframe */ padding = 0; + last_sub_frame = true; } else { /* Clone the skb for the subframe */ - subframe = slsi_skb_clone(skb, GFP_ATOMIC); + subframe = slsi_skb_copy(skb, GFP_ATOMIC); if (!subframe) { slsi_kfree_skb(skb); SLSI_NET_ERR(dev, "Failed to clone the SKB for A-MSDU subframe\n"); @@ -153,13 +155,12 @@ static int slsi_rx_amsdu_deaggregate(struct net_device *dev, struct sk_buff *skb skb_set_mac_header(subframe, 0); mh = eth_hdr(subframe); if (SLSI_ETHER_EQUAL(mh->h_dest, mac_0)) { - SLSI_NET_DBG3(dev, SLSI_RX, "msdu subframe filtered out: MAC destination address %pM\n", - mh->h_dest); + SLSI_NET_DBG3(dev, SLSI_RX, "msdu subframe filtered out: MAC destination address %pM\n", mh->h_dest); skip_frame = true; } /* If this is not the last subframe then move to the next subframe */ - if (skb != subframe) + if (!last_sub_frame) skb_pull(skb, (subframe_len + padding)); /* If this frame has been filtered out, free the clone and continue */ @@ -170,25 +171,9 @@ static int slsi_rx_amsdu_deaggregate(struct net_device *dev, struct sk_buff *skb slsi_kfree_skb(subframe); continue; } - - /* Prepare the skb */ - subframe->dev = dev; - subframe->ip_summed = CHECKSUM_UNNECESSARY; - ndev_vif->stats.rx_bytes += subframe->len; - ndev_vif->stats.rx_packets++; - - SCSC_HIP4_SAMPLER_TCP_DECODE(ndev_vif->sdev, dev, skb->data, true); - subframe->protocol = eth_type_trans(subframe, dev); -#ifdef CONFIG_SCSC_WLAN_RX_NAPI - slsi_rx_msdu_napi(dev, subframe); -#else - slsi_traffic_mon_event_rx(sdev, dev, subframe); - slsi_dbg_untrack_skb(subframe); - SLSI_DBG4(sdev, SLSI_RX, "pass %u bytes to local stack\n", subframe->len); - netif_rx_ni(subframe); -#endif + __skb_queue_tail(msdu_list, subframe); } - + slsi_kfree_skb(skb); return 0; } @@ -197,237 +182,241 @@ static inline bool slsi_rx_is_amsdu(struct sk_buff *skb) return (fapi_get_u16(skb, u.ma_unitdata_ind.data_unit_descriptor) == FAPI_DATAUNITDESCRIPTOR_AMSDU); } -static int slsi_rx_data_process_skb(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff **skb, bool from_ba) +void slsi_rx_data_deliver_skb(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb) { struct netdev_vif *ndev_vif = netdev_priv(dev); + struct sk_buff_head msdu_list; struct slsi_peer *peer = NULL; - struct ethhdr *ehdr; - u16 seq_num; - bool skip_ba = from_ba; - bool is_amsdu = slsi_rx_is_amsdu((*skb)); - u8 trafic_q = slsi_frame_priority_to_ac_queue(fapi_get_u16((*skb), u.ma_unitdata_ind.priority)); + struct ethhdr *eth_hdr; + bool is_amsdu = slsi_rx_is_amsdu(skb); + u8 trafic_q = slsi_frame_priority_to_ac_queue(fapi_get_u16(skb, u.ma_unitdata_ind.priority)); + + __skb_queue_head_init(&msdu_list); #ifdef CONFIG_SCSC_SMAPPER /* Check if the payload is in the SMAPPER entry */ - if (fapi_get_u16((*skb), u.ma_unitdata_ind.bulk_data_descriptor) == FAPI_BULKDATADESCRIPTOR_SMAPPER) { - ehdr = (struct ethhdr *)slsi_hip_get_skb_data_from_smapper(sdev, (*skb)); - if (!(ehdr)) { + if (fapi_get_u16(skb, u.ma_unitdata_ind.bulk_data_descriptor) == FAPI_BULKDATADESCRIPTOR_SMAPPER) { + /* Retrieve the associated smapper skb */ + skb = slsi_hip_get_skb_from_smapper(sdev, skb); + if (!skb) { SLSI_NET_DBG2(dev, SLSI_RX, "SKB from SMAPPER is NULL\n"); - return -EINVAL; + return; } } else { - ehdr = (struct ethhdr *)fapi_get_data((*skb)); + /* strip signal and any signal/bulk roundings/offsets */ + skb_pull(skb, fapi_get_siglen(skb)); } #else - ehdr = (struct ethhdr *)fapi_get_data((*skb)); + skb_pull(skb, fapi_get_siglen(skb)); #endif - SLSI_NET_DBG_HEX(dev, SLSI_RX, (*skb)->data, (*skb)->len < 64 ? (*skb)->len : 64, "\n"); + eth_hdr = (struct ethhdr *)skb->data; + peer = slsi_get_peer_from_mac(sdev, dev, eth_hdr->h_source); + if (!peer) { + SLSI_NET_WARN(dev, "Packet dropped (no peer records)\n"); + slsi_kfree_skb(skb); + return; + } - if (!((fapi_get_u16((*skb), u.ma_unitdata_ind.data_unit_descriptor) == FAPI_DATAUNITDESCRIPTOR_IEEE802_3_FRAME) || - (fapi_get_u16((*skb), u.ma_unitdata_ind.data_unit_descriptor) == FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME) || - (fapi_get_u16((*skb), u.ma_unitdata_ind.data_unit_descriptor) == FAPI_DATAUNITDESCRIPTOR_AMSDU))) { - WARN_ON(1); - slsi_kfree_skb((*skb)); - return -ENOTSUPP; + /* A-MSDU deaggregation */ + if (is_amsdu) { + if (slsi_rx_amsdu_deaggregate(dev, skb, &msdu_list)) { + ndev_vif->stats.rx_dropped++; + if (peer) + peer->sinfo.rx_dropped_misc++; + return; + } + } else { + __skb_queue_tail(&msdu_list, skb); + } + + while (!skb_queue_empty(&msdu_list)) { + struct sk_buff *rx_skb; + + rx_skb = __skb_dequeue(&msdu_list); + + /* In STA mode, the AP relays back our multicast traffic. + * Receiving these frames and passing it up confuses some + * protocols and applications, notably IPv6 Duplicate + * Address Detection. + * + * So these frames are dropped instead of passing it further. + * No need to update the drop statistics as these frames are + * locally generated and should not be accounted in reception. + */ + if (ndev_vif->vif_type == FAPI_VIFTYPE_STATION) { + struct ethhdr *ehdr = (struct ethhdr *)(rx_skb->data); + + if (is_multicast_ether_addr(ehdr->h_dest) && + !compare_ether_addr(ehdr->h_source, dev->dev_addr)) { + SLSI_NET_DBG2(dev, SLSI_RX, "drop locally generated multicast frame relayed back by AP\n"); + slsi_kfree_skb(rx_skb); + continue; + } + } + + /* Intra BSS */ + if (ndev_vif->vif_type == FAPI_VIFTYPE_AP && ndev_vif->peer_sta_records) { + struct slsi_peer *peer = NULL; + struct ethhdr *ehdr = (struct ethhdr *)(rx_skb->data); + + if (is_multicast_ether_addr(ehdr->h_dest)) { + struct sk_buff *rebroadcast_skb = slsi_skb_copy(rx_skb, GFP_KERNEL); + + if (!rebroadcast_skb) { + SLSI_WARN(sdev, "Intra BSS: failed to alloc new SKB for broadcast\n"); + } else { + SLSI_DBG3(sdev, SLSI_RX, "Intra BSS: multicast %pM\n", ehdr->h_dest); + rebroadcast_skb->dev = dev; + rebroadcast_skb->protocol = cpu_to_be16(ETH_P_802_3); + slsi_dbg_untrack_skb(rebroadcast_skb); + skb_reset_network_header(rebroadcast_skb); + skb_reset_mac_header(rebroadcast_skb); + dev_queue_xmit(rebroadcast_skb); + } + } else { + peer = slsi_get_peer_from_mac(sdev, dev, ehdr->h_dest); + if (peer && peer->authorized) { + SLSI_DBG3(sdev, SLSI_RX, "Intra BSS: unicast %pM\n", ehdr->h_dest); + rx_skb->dev = dev; + rx_skb->protocol = cpu_to_be16(ETH_P_802_3); + slsi_dbg_untrack_skb(rx_skb); + skb_reset_network_header(rx_skb); + skb_reset_mac_header(rx_skb); + dev_queue_xmit(rx_skb); + continue; + } + } + } + + if (peer) { + peer->sinfo.rx_packets++; + peer->sinfo.rx_bytes += rx_skb->len; + } + ndev_vif->stats.rx_packets++; + ndev_vif->stats.rx_bytes += rx_skb->len; + ndev_vif->rx_packets[trafic_q]++; + + rx_skb->dev = dev; + rx_skb->ip_summed = CHECKSUM_NONE; + rx_skb->protocol = eth_type_trans(rx_skb, dev); + + SCSC_HIP4_SAMPLER_TCP_DECODE(sdev, dev, rx_skb->data, true); + slsi_traffic_mon_event_rx(sdev, dev, rx_skb); + slsi_dbg_untrack_skb(rx_skb); + + SLSI_DBG4(sdev, SLSI_RX, "pass %u bytes to local stack\n", rx_skb->len); +#ifdef CONFIG_SCSC_WLAN_RX_NAPI_GRO + napi_gro_receive(&sdev->hip4_inst.hip_priv->napi, rx_skb); +#elif defined(CONFIG_SCSC_WLAN_RX_NAPI) + netif_receive_skb(rx_skb); +#else + netif_rx_ni(rx_skb); +#endif + slsi_wakelock_timeout(&sdev->wlan_wl_ma, SLSI_RX_WAKELOCK_TIME); } +} - seq_num = fapi_get_u16((*skb), u.ma_unitdata_ind.sequence_number); - SLSI_NET_DBG4(dev, SLSI_RX, "ma_unitdata_ind(vif:%d, %pM, datatype:%d, priority:%d, s:%d)\n", - fapi_get_vif((*skb)), - ehdr->h_source, - fapi_get_u16((*skb), u.ma_unitdata_ind.data_unit_descriptor), - fapi_get_u16((*skb), u.ma_unitdata_ind.priority), - (seq_num & SLSI_RX_SEQ_NUM_MASK)); +static void slsi_rx_data_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb) +{ + struct netdev_vif *ndev_vif = netdev_priv(dev); + struct slsi_peer *peer = NULL; + struct ethhdr *eth_hdr; + u16 seq_num; + + if (!((fapi_get_u16(skb, u.ma_unitdata_ind.data_unit_descriptor) == FAPI_DATAUNITDESCRIPTOR_IEEE802_3_FRAME) || + (fapi_get_u16(skb, u.ma_unitdata_ind.data_unit_descriptor) == FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME) || + (fapi_get_u16(skb, u.ma_unitdata_ind.data_unit_descriptor) == FAPI_DATAUNITDESCRIPTOR_AMSDU))) { + WARN_ON(1); + slsi_kfree_skb(skb); + return; + } #ifdef CONFIG_SCSC_WLAN_DEBUG /* pass the data up "As is" if the VIF type is Monitor */ if (ndev_vif->vif_type == FAPI_VIFTYPE_MONITOR) { /* strip signal */ - skb_pull((*skb), fapi_get_siglen((*skb))); + skb_pull(skb, fapi_get_siglen(skb)); - skb_reset_mac_header((*skb)); - (*skb)->dev = dev; - (*skb)->ip_summed = CHECKSUM_UNNECESSARY; - (*skb)->pkt_type = PACKET_OTHERHOST; - return 0; + skb_reset_mac_header(skb); + skb->dev = dev; + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->pkt_type = PACKET_OTHERHOST; + netif_rx_ni(skb); } #endif - peer = slsi_get_peer_from_mac(sdev, dev, ehdr->h_source); + +#ifdef CONFIG_SCSC_SMAPPER + /* Check if the payload is in the SMAPPER entry */ + if (fapi_get_u16(skb, u.ma_unitdata_ind.bulk_data_descriptor) == FAPI_BULKDATADESCRIPTOR_SMAPPER) { + eth_hdr = (struct ethhdr *)slsi_hip_get_skb_data_from_smapper(sdev, skb); + if (!(eth_hdr)) { + SLSI_NET_DBG2(dev, SLSI_RX, "SKB from SMAPPER is NULL\n"); + slsi_kfree_skb(skb); + return; + } + } else { + eth_hdr = (struct ethhdr *)fapi_get_data(skb); + } +#else + eth_hdr = (struct ethhdr *)fapi_get_data(skb); +#endif + seq_num = fapi_get_u16(skb, u.ma_unitdata_ind.sequence_number); + SLSI_NET_DBG4(dev, SLSI_RX, "ma_unitdata_ind(vif:%d, dest:%pM, src:%pM, datatype:%d, priority:%d, s:%d)\n", + fapi_get_vif(skb), + eth_hdr->h_dest, + eth_hdr->h_source, + fapi_get_u16(skb, u.ma_unitdata_ind.data_unit_descriptor), + fapi_get_u16(skb, u.ma_unitdata_ind.priority), + (seq_num & SLSI_RX_SEQ_NUM_MASK)); + + peer = slsi_get_peer_from_mac(sdev, dev, eth_hdr->h_source); if (!peer) { SLSI_NET_WARN(dev, "Packet dropped (no peer records)\n"); /* Race in Data plane (Shows up in fw test mode) */ - slsi_kfree_skb((*skb)); - return -EINVAL; + slsi_kfree_skb(skb); + return; } /* discard data frames if received before key negotiations are completed */ - if ((ndev_vif->vif_type == FAPI_VIFTYPE_AP) && (peer->connected_state != SLSI_STA_CONN_STATE_CONNECTED)) { + if (ndev_vif->vif_type == FAPI_VIFTYPE_AP && peer->connected_state != SLSI_STA_CONN_STATE_CONNECTED) { SLSI_NET_WARN(dev, "Packet dropped (peer connection not complete (state:%u))\n", peer->connected_state); - slsi_kfree_skb((*skb)); - return -EINVAL; + slsi_kfree_skb(skb); + return; } /* When TDLS connection has just been closed a few last frame may still arrive from the closed connection. * This frames must not be injected in to the block session with the AP as the sequence numbers are different * that will confuse the BA process. Therefore we have to skip BA for those frames. */ - if ((ndev_vif->vif_type == FAPI_VIFTYPE_STATION) && (peer->aid < SLSI_TDLS_PEER_INDEX_MIN) && (seq_num & SLSI_RX_VIA_TDLS_LINK)) { + if (ndev_vif->vif_type == FAPI_VIFTYPE_STATION && peer->aid < SLSI_TDLS_PEER_INDEX_MIN && (seq_num & SLSI_RX_VIA_TDLS_LINK)) { if (printk_ratelimit()) SLSI_NET_WARN(dev, "Packet received from TDLS but no TDLS exists (seq: %x) Skip BA\n", seq_num); - skip_ba = true; + + /* Skip BA reorder and pass the frames Up */ + slsi_rx_data_deliver_skb(sdev, dev, skb); + return; } /* TDLS is enabled for the PEER but still packet is received through the AP. Process this packet with the AP PEER */ - if ((ndev_vif->vif_type == FAPI_VIFTYPE_STATION) && (peer->aid >= SLSI_TDLS_PEER_INDEX_MIN) && (!(seq_num & SLSI_RX_VIA_TDLS_LINK))) { + if (ndev_vif->vif_type == FAPI_VIFTYPE_STATION && peer->aid >= SLSI_TDLS_PEER_INDEX_MIN && (!(seq_num & SLSI_RX_VIA_TDLS_LINK))) { SLSI_NET_DBG2(dev, SLSI_TDLS, "Packet received from TDLS peer through the AP(seq: %x)\n", seq_num); peer = slsi_get_peer_from_qs(sdev, dev, SLSI_STA_PEER_QUEUESET); if (!peer) { SLSI_NET_WARN(dev, "Packet dropped (AP peer not found)\n"); - slsi_kfree_skb((*skb)); - return -EINVAL; - } - } - - if (!skip_ba && (slsi_ba_check(peer, fapi_get_u16((*skb), u.ma_unitdata_ind.priority)))) - if (!slsi_ba_process_frame(dev, peer, (*skb), (seq_num & SLSI_RX_SEQ_NUM_MASK), - fapi_get_u16((*skb), u.ma_unitdata_ind.priority))) - return 1; - -#ifdef CONFIG_SCSC_SMAPPER - /* Check if the payload is in the SMAPPER entry */ - if (fapi_get_u16((*skb), u.ma_unitdata_ind.bulk_data_descriptor) == FAPI_BULKDATADESCRIPTOR_SMAPPER) { - /* Retrieve the associated smapper skb */ - *skb = slsi_hip_get_skb_from_smapper(sdev, (*skb)); - if (!(*skb)) { - SLSI_NET_DBG2(dev, SLSI_RX, "SKB from SMAPPER is NULL\n"); - return -EINVAL; - } - } else { - /* strip signal and any signal/bulk roundings/offsets */ - skb_pull((*skb), fapi_get_siglen((*skb))); - } -#else - skb_pull((*skb), fapi_get_siglen((*skb))); -#endif - - /* A-MSDU deaggregation */ - if (is_amsdu) { - /* This function will consume the skb */ - if (slsi_rx_amsdu_deaggregate(dev, (*skb))) { - ndev_vif->stats.rx_dropped++; - if (peer) - peer->sinfo.rx_dropped_misc++; - } else { - if (peer) { - peer->sinfo.rx_packets++; - ndev_vif->rx_packets[trafic_q]++; - } - slsi_wakelock_timeout(&sdev->wlan_wl_ma, SLSI_RX_WAKELOCK_TIME); - } - return 1; - } - - (*skb)->dev = dev; - (*skb)->ip_summed = CHECKSUM_UNNECESSARY; - - /* In STA mode, the AP relays back our multicast traffic. - * Receiving these frames and passing it up confuses some - * protocols and applications, notably IPv6 Duplicate - * Address Detection. - * - * So these frames are dropped instead of passing it further. - * No need to update the drop statistics as these frames are - * locally generated and should not be accounted in reception. - */ - if (ndev_vif->vif_type == FAPI_VIFTYPE_STATION) { - struct ethhdr *ehdr = (struct ethhdr *)((*skb)->data); - - if (is_multicast_ether_addr(ehdr->h_dest) && - !compare_ether_addr(ehdr->h_source, dev->dev_addr)) { - SLSI_NET_DBG2(dev, SLSI_RX, "drop locally generated multicast frame relayed back by AP\n"); - slsi_kfree_skb((*skb)); - return -EINVAL; - } - } - - if (peer) { - peer->sinfo.rx_packets++; - peer->sinfo.rx_bytes += (*skb)->len; - } - - ndev_vif->stats.rx_packets++; - ndev_vif->stats.rx_bytes += (*skb)->len; - ndev_vif->rx_packets[trafic_q]++; - - /* Intra BSS */ - if (ndev_vif->vif_type == FAPI_VIFTYPE_AP && ndev_vif->peer_sta_records) { - struct ethhdr *ehdr = (struct ethhdr *)((*skb)->data); - - if (is_multicast_ether_addr(ehdr->h_dest)) { - struct sk_buff *rebroadcast_skb = slsi_skb_copy((*skb), GFP_KERNEL); - - (*skb)->protocol = eth_type_trans((*skb), dev); - if (!rebroadcast_skb) { - SLSI_WARN(sdev, "Intra BSS: failed to alloc new SKB for broadcast\n"); - return 0; - } - SLSI_DBG3(sdev, SLSI_RX, "Intra BSS: multicast %pM\n", ehdr->h_dest); - rebroadcast_skb->dev = dev; - rebroadcast_skb->protocol = cpu_to_be16(ETH_P_802_3); - slsi_dbg_untrack_skb(rebroadcast_skb); - skb_reset_network_header(rebroadcast_skb); - skb_reset_mac_header(rebroadcast_skb); - dev_queue_xmit(rebroadcast_skb); - return 0; - } - - peer = slsi_get_peer_from_mac(sdev, dev, ehdr->h_dest); - if (peer && peer->authorized) { - SLSI_DBG3(sdev, SLSI_RX, "Intra BSS: unicast %pM\n", ehdr->h_dest); - (*skb)->protocol = cpu_to_be16(ETH_P_802_3); - slsi_dbg_untrack_skb((*skb)); - skb_reset_network_header((*skb)); - skb_reset_mac_header((*skb)); - dev_queue_xmit((*skb)); - return 1; + slsi_kfree_skb(skb); + return; } } - SCSC_HIP4_SAMPLER_TCP_DECODE(sdev, dev, (*skb)->data, true); - (*skb)->protocol = eth_type_trans((*skb), dev); - return 0; -} - -#ifdef CONFIG_SCSC_WLAN_RX_NAPI -int slsi_rx_data_napi(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb, bool from_ba) -{ - struct netdev_vif *ndev_vif = netdev_priv(dev); - slsi_debug_frame(sdev, dev, skb, "RX"); + /* If frame belongs to a negotiated BA, BA will consume the frame */ + if (slsi_ba_check(peer, fapi_get_u16(skb, u.ma_unitdata_ind.priority))) + if (!slsi_ba_process_frame(dev, peer, skb, (seq_num & SLSI_RX_SEQ_NUM_MASK), + fapi_get_u16(skb, u.ma_unitdata_ind.priority))) + return; - if (slsi_rx_data_process_skb(sdev, dev, skb, from_ba) == 0) { - slsi_skb_queue_tail(&ndev_vif->napi.rx_data, skb); - slsi_spinlock_lock(&ndev_vif->napi.lock); - if (ndev_vif->napi.interrupt_enabled) { - ndev_vif->napi.interrupt_enabled = false; - napi_schedule(&ndev_vif->napi.napi); - } - slsi_spinlock_unlock(&ndev_vif->napi.lock); - } - return 0; -} -#endif - -int slsi_rx_data(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb, bool from_ba) -{ - if (slsi_rx_data_process_skb(sdev, dev, &skb, from_ba) == 0) { - slsi_traffic_mon_event_rx(sdev, dev, skb); - slsi_dbg_untrack_skb(skb); - SLSI_DBG4(sdev, SLSI_RX, "pass %u bytes to local stack\n", skb->len); - netif_rx_ni(skb); - slsi_wakelock_timeout(&sdev->wlan_wl_ma, SLSI_RX_WAKELOCK_TIME); - } - return 0; + /* Pass to next receive process */ + slsi_rx_data_deliver_skb(sdev, dev, skb); } static int slsi_rx_data_cfm(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb) @@ -450,6 +439,47 @@ static int slsi_rx_data_cfm(struct slsi_dev *sdev, struct net_device *dev, struc return 0; } +#ifdef CONFIG_SCSC_WLAN_RX_NAPI +static int slsi_rx_napi_process(struct slsi_dev *sdev, struct sk_buff *skb) +{ + struct net_device *dev; + struct netdev_vif *ndev_vif; + u16 vif; + + vif = fapi_get_vif(skb); + + rcu_read_lock(); + dev = slsi_get_netdev_rcu(sdev, vif); + if (!dev) { + SLSI_ERR(sdev, "netdev(%d) No longer exists\n", vif); + rcu_read_unlock(); + return -EINVAL; + } + rcu_read_unlock(); + + ndev_vif = netdev_priv(dev); + + switch (fapi_get_u16(skb, id)) { + case MA_UNITDATA_IND: + slsi_rx_data_ind(sdev, dev, skb); + + /* SKBs in a BA session are not passed yet */ + if (atomic_read(&ndev_vif->ba_flush)) { + atomic_set(&ndev_vif->ba_flush, 0); + slsi_ba_process_complete(dev); + } + break; + case MA_UNITDATA_CFM: + (void)slsi_rx_data_cfm(sdev, dev, skb); + break; + default: + SLSI_DBG1(sdev, SLSI_RX, "Unexpected Data: 0x%.4x\n", fapi_get_sigid(skb)); + slsi_kfree_skb(skb); + break; + } + return 0; +} +#else void slsi_rx_netdev_data_work(struct work_struct *work) { struct slsi_skb_work *w = container_of(work, struct slsi_skb_work, work); @@ -470,6 +500,7 @@ void slsi_rx_netdev_data_work(struct work_struct *work) SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex); break; } + if (atomic_read(&ndev_vif->ba_flush)) { atomic_set(&ndev_vif->ba_flush, 0); slsi_ba_process_complete(dev); @@ -481,7 +512,6 @@ void slsi_rx_netdev_data_work(struct work_struct *work) break; } - slsi_debug_frame(sdev, dev, skb, "RX"); switch (fapi_get_u16(skb, id)) { case MA_UNITDATA_IND: #ifdef CONFIG_SCSC_SMAPPER @@ -496,7 +526,7 @@ void slsi_rx_netdev_data_work(struct work_struct *work) #else SCSC_HIP4_SAMPLER_TCP_DECODE(sdev, dev, skb->data + fapi_get_siglen(skb), false); #endif - (void)slsi_rx_data(sdev, dev, skb, false); + slsi_rx_data_ind(sdev, dev, skb); break; case MA_UNITDATA_CFM: (void)slsi_rx_data_cfm(sdev, dev, skb); @@ -527,19 +557,13 @@ static int slsi_rx_queue_data(struct slsi_dev *sdev, struct sk_buff *skb) goto err; } ndev_vif = netdev_priv(dev); - SCSC_WLOG_PKTFATE_LOG_RX_DATA_FRAME(fapi_get_u16(skb, u.ma_unitdata_ind.data_unit_descriptor), - fapi_get_data(skb), fapi_get_datalen(skb)); - -#ifdef CONFIG_SCSC_WLAN_RX_NAPI - slsi_rx_data_napi(sdev, dev, skb, false); -#else slsi_skb_work_enqueue(&ndev_vif->rx_data, skb); -#endif rcu_read_unlock(); return 0; err: return -EINVAL; } +#endif static int sap_ma_rx_handler(struct slsi_dev *sdev, struct sk_buff *skb) { @@ -562,7 +586,11 @@ static int sap_ma_rx_handler(struct slsi_dev *sdev, struct sk_buff *skb) } #endif case MA_UNITDATA_CFM: +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + return slsi_rx_napi_process(sdev, skb); +#else return slsi_rx_queue_data(sdev, skb); +#endif case MA_BLOCKACK_IND: /* It is anomolous to handle the MA_BLOCKACK_IND in the * mlme wq. diff --git a/drivers/net/wireless/scsc/sap_mlme.c b/drivers/net/wireless/scsc/sap_mlme.c index 082b2bc9ae40..64939c32ccc5 100755 --- a/drivers/net/wireless/scsc/sap_mlme.c +++ b/drivers/net/wireless/scsc/sap_mlme.c @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2014 - 2017 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ #include @@ -10,7 +10,10 @@ #include "sap_mlme.h" #include "hip.h" #include "mgt.h" + +#ifdef CONFIG_ANDROID #include "scsc_wifilogger_rings.h" +#endif #define SUPPORTED_OLD_VERSION 0 @@ -163,20 +166,33 @@ static int slsi_rx_netdev_mlme(struct slsi_dev *sdev, struct net_device *dev, st case MLME_RSSI_REPORT_IND: slsi_rx_rssi_report_ind(sdev, dev, skb); break; + case MLME_RANGE_IND: + slsi_rx_range_ind(sdev, dev, skb); + break; + case MLME_RANGE_DONE_IND: + slsi_rx_range_done_ind(sdev, dev, skb); + break; + #endif #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING case MLME_EVENT_LOG_IND: slsi_rx_event_log_indication(sdev, dev, skb); + break; #endif +#ifdef CONFIG_SCSC_WLAN_GSCAN_ENABLE case MLME_NAN_EVENT_IND: slsi_nan_event(sdev, dev, skb); + slsi_kfree_skb(skb); break; case MLME_NAN_FOLLOWUP_IND: slsi_nan_followup_ind(sdev, dev, skb); + slsi_kfree_skb(skb); break; case MLME_NAN_SERVICE_IND: slsi_nan_service_ind(sdev, dev, skb); + slsi_kfree_skb(skb); break; +#endif default: slsi_kfree_skb(skb); SLSI_NET_ERR(dev, "Unhandled Ind: 0x%.4x\n", id); @@ -290,7 +306,9 @@ static int sap_mlme_rx_handler(struct slsi_dev *sdev, struct sk_buff *skb) return 0; if (fapi_is_ind(skb)) { +#ifdef CONFIG_SCSC_WIFILOGGER SCSC_WLOG_PKTFATE_LOG_RX_CTRL_FRAME(fapi_get_data(skb), fapi_get_datalen(skb)); +#endif switch (fapi_get_sigid(skb)) { case MLME_SCAN_DONE_IND: @@ -325,6 +343,12 @@ static int sap_mlme_rx_handler(struct slsi_dev *sdev, struct sk_buff *skb) case MLME_NAN_FOLLOWUP_IND: case MLME_NAN_SERVICE_IND: return slsi_rx_enqueue_netdev_mlme(sdev, skb, vif); + case MLME_RANGE_IND: + case MLME_RANGE_DONE_IND: + if (vif == 0) + return slsi_rx_enqueue_netdev_mlme(sdev, skb, SLSI_NET_INDEX_WLAN); + else + return slsi_rx_enqueue_netdev_mlme(sdev, skb, vif); #endif #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING case MLME_EVENT_LOG_IND: diff --git a/drivers/net/wireless/scsc/sap_test.c b/drivers/net/wireless/scsc/sap_test.c index c8f81ccacb96..403368337c90 100644 --- a/drivers/net/wireless/scsc/sap_test.c +++ b/drivers/net/wireless/scsc/sap_test.c @@ -42,6 +42,9 @@ static int sap_test_version_supported(u16 version) static int sap_test_rx_handler(struct slsi_dev *sdev, struct sk_buff *skb) { + if (slsi_rx_blocking_signals(sdev, skb) == 0) + return 0; + SLSI_INFO_NODEV("TEST SAP not implemented\n"); /* Silently consume the skb */ slsi_kfree_skb(skb); diff --git a/drivers/net/wireless/scsc/scsc_wifi_fcq.c b/drivers/net/wireless/scsc/scsc_wifi_fcq.c index 779bd964ceae..fac2a1dc5d2e 100755 --- a/drivers/net/wireless/scsc/scsc_wifi_fcq.c +++ b/drivers/net/wireless/scsc/scsc_wifi_fcq.c @@ -373,18 +373,22 @@ static int fcq_transmit_gmod_domain(struct net_device *dev, struct scsc_wifi_fcq /* Check first the global domain */ if (sdev->hip4_inst.hip_priv->saturated) { +#ifdef CONFIG_SCSC_DEBUG SLSI_DBG4_NODEV(SLSI_WIFI_FCQ, "xxxxxxxxxxxxxxxxxxxxxxx Global domain. No space. active: %d vif: %d peer: %d ac: %d gcod (%d) gmod (%d) betx:%d berx:%d vitx:%d virx:%d votx:%d vorx:%d\n", atomic_read(&sdev->hip4_inst.hip_priv->gactive), vif, peer_index, priority, atomic_read(&sdev->hip4_inst.hip_priv->gcod), atomic_read(&sdev->hip4_inst.hip_priv->gmod), td[DIREC_TX][DOMAIN_G][0], td[DIREC_RX][DOMAIN_G][0], td[DIREC_TX][DOMAIN_G][2], td[DIREC_RX][DOMAIN_G][2], td[DIREC_TX][DOMAIN_G][3], td[DIREC_RX][DOMAIN_G][3]); fcq_stop_all_queues(sdev); +#endif spin_unlock(&sdev->hip4_inst.hip_priv->gbot_lock); return -ENOSPC; } if (!atomic_read(&sdev->hip4_inst.hip_priv->gactive) && sdev->hip4_inst.hip_priv->guard-- == 0) { +#ifdef CONFIG_SCSC_DEBUG SLSI_DBG4_NODEV(SLSI_WIFI_FCQ, "xxxxxxxxxxxxxxxxxxxxxxx Global domain. Saturating Gmod. active: %d vif: %d peer: %d ac: %d gcod (%d) gmod (%d) betx:%d berx:%d vitx:%d virx:%d votx:%d vorx:%d\n", atomic_read(&sdev->hip4_inst.hip_priv->gactive), vif, peer_index, priority, atomic_read(&sdev->hip4_inst.hip_priv->gcod), atomic_read(&sdev->hip4_inst.hip_priv->gmod), td[DIREC_TX][DOMAIN_G][0], td[DIREC_RX][DOMAIN_G][0], td[DIREC_TX][DOMAIN_G][2], td[DIREC_RX][DOMAIN_G][2], td[DIREC_TX][DOMAIN_G][3], td[DIREC_RX][DOMAIN_G][3]); +#endif sdev->hip4_inst.hip_priv->saturated = true; } @@ -392,10 +396,10 @@ static int fcq_transmit_gmod_domain(struct net_device *dev, struct scsc_wifi_fcq gcod = atomic_inc_return(&sdev->hip4_inst.hip_priv->gcod); #ifdef CONFIG_SCSC_DEBUG fcq_update_counters(DIREC_TX, DOMAIN_G, priority); -#endif SLSI_DBG4_NODEV(SLSI_WIFI_FCQ, "tx: active: %d vif: %d peer: %d ac: %d gcod (%d) gmod (%d) betx:%d berx:%d vitx:%d virx:%d votx:%d vorx:%d\n", atomic_read(&sdev->hip4_inst.hip_priv->gactive), vif, peer_index, priority, gcod, gmod, td[DIREC_TX][DOMAIN_G][0], td[DIREC_RX][DOMAIN_G][0], td[DIREC_TX][DOMAIN_G][2], td[DIREC_RX][DOMAIN_G][2], td[DIREC_TX][DOMAIN_G][3], td[DIREC_RX][DOMAIN_G][3]); +#endif if (gcod >= (atomic_read(&sdev->hip4_inst.hip_priv->gmod) - STOP_GUARD_GMOD)) { fcq_stop_all_queues(sdev); if (atomic_read(&sdev->hip4_inst.hip_priv->gactive)) { @@ -436,9 +440,11 @@ static int fcq_transmit_smod_domain(struct net_device *dev, struct scsc_wifi_fcq if (qs->saturated) { int i; +#ifdef CONFIG_SCSC_DEBUG SLSI_DBG4_NODEV(SLSI_WIFI_FCQ, "xxxxxxxxxxxxxxxxxxxxxxx Smod domain. No space. active %d vif: %d peer: %d ac: %d scod (%d) smod (%d) betx:%d berx:%d vitx:%d virx:%d votx:%d vorx:%d\n", atomic_read(&qs->active), vif, peer_index, priority, atomic_read(&qs->scod), atomic_read(&qs->smod), td[DIREC_TX][DOMAIN_S][0], td[DIREC_RX][DOMAIN_S][0], td[DIREC_TX][DOMAIN_S][2], td[DIREC_RX][DOMAIN_S][2], td[DIREC_TX][DOMAIN_S][3], td[DIREC_RX][DOMAIN_S][3]); +#endif /* Close subqueues again */ for (i = 0; i < SLSI_NETIF_Q_PER_PEER; i++) @@ -448,19 +454,21 @@ static int fcq_transmit_smod_domain(struct net_device *dev, struct scsc_wifi_fcq } /* Pass the frame until reaching the actual saturation */ if (!atomic_read(&qs->active) && (qs->guard-- == 0)) { +#ifdef CONFIG_SCSC_DEBUG SLSI_DBG4_NODEV(SLSI_WIFI_FCQ, "xxxxxxxxxxxxxxxxxxxxxxx Smod domain. Going into Saturation. active %d vif: %d peer: %d ac: %d scod (%d) smod (%d) betx:%d berx:%d vitx:%d virx:%d votx:%d vorx:%d\n", atomic_read(&qs->active), vif, peer_index, priority, atomic_read(&qs->scod), atomic_read(&qs->smod), td[DIREC_TX][DOMAIN_S][0], td[DIREC_RX][DOMAIN_S][0], td[DIREC_TX][DOMAIN_S][2], td[DIREC_RX][DOMAIN_S][2], td[DIREC_TX][DOMAIN_S][3], td[DIREC_RX][DOMAIN_S][3]); +#endif qs->saturated = true; } scod = atomic_inc_return(&qs->scod); SCSC_HIP4_SAMPLER_BOT_TX(sdev->minor_prof, scod, atomic_read(&qs->smod), priority << 6 | (peer_index & 0xf) << 2 | vif); #ifdef CONFIG_SCSC_DEBUG fcq_update_counters(DIREC_TX, DOMAIN_S, priority); -#endif SLSI_DBG4_NODEV(SLSI_WIFI_FCQ, "tx: active: %d vif: %d peer: %d ac: %d scod (%d) smod (%d) betx:%d berx:%d vitx:%d virx:%d votx:%d vorx:%d\n", atomic_read(&qs->active), vif, peer_index, priority, atomic_read(&qs->scod), atomic_read(&qs->smod), td[DIREC_TX][DOMAIN_S][0], td[DIREC_RX][DOMAIN_S][0], td[DIREC_TX][DOMAIN_S][2], td[DIREC_RX][DOMAIN_S][2], td[DIREC_TX][DOMAIN_S][3], td[DIREC_RX][DOMAIN_S][3]); +#endif if (scod >= (atomic_read(&qs->smod) - STOP_GUARD_SMOD)) { int i; #ifdef EXPERIMENTAL_DYNAMIC_SMOD_ADAPTATION @@ -520,10 +528,10 @@ static int fcq_transmit_qmod_domain(struct net_device *dev, struct scsc_wifi_fcq SCSC_HIP4_SAMPLER_BOT_QMOD_TX(sdev->minor_prof, qcod, atomic_read(&queue->qmod), priority << 6 | (peer_index & 0xf) << 2 | vif); #ifdef CONFIG_SCSC_DEBUG fcq_update_counters(DIREC_TX, DOMAIN_Q, priority); -#endif SLSI_DBG4_NODEV(SLSI_WIFI_FCQ, "tx: active: %d vif: %d peer: %d ac: %d qcod (%d) qmod (%d) betx:%d berx:%d vitx:%d virx:%d votx:%d vorx:%d\n", atomic_read(&queue->active), vif, peer_index, priority, atomic_read(&queue->qcod), atomic_read(&queue->qmod), td[DIREC_TX][DOMAIN_Q][0], td[DIREC_RX][DOMAIN_Q][0], td[DIREC_TX][DOMAIN_Q][2], td[DIREC_RX][DOMAIN_Q][2], td[DIREC_TX][DOMAIN_Q][3], td[DIREC_RX][DOMAIN_Q][3]); +#endif if (atomic_read(&queue->active) && qcod >= (atomic_read(&queue->qmod) - STOP_GUARD_QMOD)) { /* Before closing check whether we could get slots from non used queues */ #ifdef EXPERIMENTAL_DYNAMIC_SMOD_ADAPTATION @@ -655,10 +663,10 @@ static int fcq_receive_gmod_domain(struct net_device *dev, struct scsc_wifi_fcq_ #ifdef CONFIG_SCSC_DEBUG fcq_update_counters(DIREC_RX, DOMAIN_G, priority); -#endif SLSI_DBG4_NODEV(SLSI_WIFI_FCQ, "rx: active: %d vif: %d peer: %d ac: %d gcod (%d) gmod (%d) betx:%d berx:%d vitx:%d virx:%d votx:%d vorx:%d %s\n", gactive, vif, peer_index, priority, gcod, gmod, td[DIREC_TX][DOMAIN_G][0], td[DIREC_RX][DOMAIN_G][0], td[DIREC_TX][DOMAIN_G][2], td[DIREC_RX][DOMAIN_G][2], td[DIREC_TX][DOMAIN_G][3], td[DIREC_RX][DOMAIN_G][3], qs ? "" : "NO PEER"); +#endif if (!is_gmod_active(sdev) && (gcod + SCSC_WIFI_FCQ_GMOD_RESUME_HYSTERESIS / total < gmod)) { SLSI_DBG4_NODEV(SLSI_WIFI_FCQ, "Global Queues Started. gcod (%d) < gmod (%d)\n", gcod, gmod); @@ -683,10 +691,10 @@ static int fcq_receive_smod_domain(struct net_device *dev, struct scsc_wifi_fcq_ #ifdef CONFIG_SCSC_DEBUG fcq_update_counters(DIREC_RX, DOMAIN_S, priority); -#endif SLSI_DBG4_NODEV(SLSI_WIFI_FCQ, "rx: active: %d vif: %d peer: %d ac: %d scod (%d) smod (%d) betx:%d berx:%d vitx:%d virx:%d votx:%d vorx:%d\n", atomic_read(&qs->active), vif, peer_index, priority, atomic_read(&qs->scod), atomic_read(&qs->smod), td[DIREC_TX][DOMAIN_S][0], td[DIREC_RX][DOMAIN_S][0], td[DIREC_TX][DOMAIN_S][2], td[DIREC_RX][DOMAIN_S][2], td[DIREC_TX][DOMAIN_S][3], td[DIREC_RX][DOMAIN_S][3]); +#endif /* Only support a maximum of 16 peers!!!!!!*/ SCSC_HIP4_SAMPLER_BOT_RX(sdev->minor_prof, scod, atomic_read(&qs->smod), priority << 6 | (peer_index & 0xf) << 2 | vif); if (!is_smod_active(qs) && (scod + SCSC_WIFI_FCQ_SMOD_RESUME_HYSTERESIS / total < atomic_read(&qs->smod))) { @@ -736,10 +744,10 @@ static int fcq_receive_qmod_domain(struct net_device *dev, struct scsc_wifi_fcq_ #ifdef CONFIG_SCSC_DEBUG fcq_update_counters(DIREC_RX, DOMAIN_Q, priority); -#endif SLSI_DBG4_NODEV(SLSI_WIFI_FCQ, "rx: active: %d vif: %d peer: %d ac: %d qcod (%d) qmod (%d) betx:%d berx:%d vitx:%d virx:%d votx:%d vorx:%d\n", atomic_read(&queue->active), vif, peer_index, priority, atomic_read(&queue->qcod), atomic_read(&queue->qmod), td[DIREC_TX][DOMAIN_Q][0], td[DIREC_RX][DOMAIN_Q][0], td[DIREC_TX][DOMAIN_Q][2], td[DIREC_RX][DOMAIN_Q][2], td[DIREC_TX][DOMAIN_Q][3], td[DIREC_RX][DOMAIN_Q][3]); +#endif SCSC_HIP4_SAMPLER_BOT_QMOD_RX(sdev->minor_prof, qcod, atomic_read(&queue->qmod), priority << 6 | (peer_index & 0xf) << 2 | vif); if (!is_qmod_active(&qs->ac_q[priority]) && ((qcod + SCSC_WIFI_FCQ_QMOD_RESUME_HYSTERESIS / total) < atomic_read(&queue->qmod))) { diff --git a/drivers/net/wireless/scsc/src_sink.c b/drivers/net/wireless/scsc/src_sink.c index cc84b2968b0c..24b16179e536 100755 --- a/drivers/net/wireless/scsc/src_sink.c +++ b/drivers/net/wireless/scsc/src_sink.c @@ -42,6 +42,7 @@ static int slsi_src_sink_fake_sta_start(struct slsi_dev *sdev, struct net_device SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex); return -EFAULT; } + peer->qos_enabled = true; slsi_ps_port_control(sdev, dev, peer, SLSI_STA_CONN_STATE_CONNECTED); netif_carrier_on(dev); SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex); diff --git a/drivers/net/wireless/scsc/test/Makefile b/drivers/net/wireless/scsc/test/Makefile index 56f7cf1d473c..8d36b9e6fe70 100755 --- a/drivers/net/wireless/scsc/test/Makefile +++ b/drivers/net/wireless/scsc/test/Makefile @@ -26,7 +26,7 @@ $(CONFIG_SCSC_WLAN_MODULE)-y += ../fw_test.o $(CONFIG_SCSC_WLAN_MODULE)-y += ../cac.o $(CONFIG_SCSC_WLAN_MODULE)-y += ../ioctl.o $(CONFIG_SCSC_WLAN_MODULE)-y += ../wakelock.o - +$(CONFIG_SCSC_WLAN_MODULE)-y += ../traffic_monitor.o # enable GSCAN ifeq ($(CONFIG_SCSC_WLAN_GSCAN_ENABLE),y) $(CONFIG_SCSC_WLAN_MODULE)-y += ../nl80211_vendor.o diff --git a/drivers/net/wireless/scsc/traffic_monitor.c b/drivers/net/wireless/scsc/traffic_monitor.c index 4648c453d9fb..8913a623d2c0 100644 --- a/drivers/net/wireless/scsc/traffic_monitor.c +++ b/drivers/net/wireless/scsc/traffic_monitor.c @@ -66,9 +66,18 @@ static inline void traffic_mon_invoke_client_callback(struct slsi_dev *sdev, u32 } } +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +static void traffic_mon_timer(struct timer_list *t) +#else static void traffic_mon_timer(unsigned long data) +#endif { +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + struct slsi_traffic_mon_clients *clients = from_timer(clients, t, timer); + struct slsi_dev *sdev = container_of(clients, typeof(*sdev), traffic_mon_clients); +#else struct slsi_dev *sdev = (struct slsi_dev *)data; +#endif struct net_device *dev; struct netdev_vif *ndev_vif; bool stop_monitor; @@ -290,8 +299,11 @@ void slsi_traffic_mon_clients_init(struct slsi_dev *sdev) SLSI_ERR_NODEV("invalid sdev\n"); return; } - +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + timer_setup(&sdev->traffic_mon_clients.timer, traffic_mon_timer, 0); +#else setup_timer(&sdev->traffic_mon_clients.timer, traffic_mon_timer, (unsigned long)sdev); +#endif INIT_LIST_HEAD(&sdev->traffic_mon_clients.client_list); spin_lock_init(&sdev->traffic_mon_clients.lock); } diff --git a/drivers/net/wireless/scsc/tx.c b/drivers/net/wireless/scsc/tx.c index 431521777434..30e3c2bc62fb 100755 --- a/drivers/net/wireless/scsc/tx.c +++ b/drivers/net/wireless/scsc/tx.c @@ -17,7 +17,9 @@ static bool msdu_enable = true; module_param(msdu_enable, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(msdu_enable, "MSDU frame format, Y: enable (default), N: disable"); +#ifdef CONFIG_ANDROID #include "scsc_wifilogger_rings.h" +#endif /** * Needed to get HIP4_DAT)SLOTS...should be part @@ -237,9 +239,11 @@ int slsi_tx_data(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff * cb->colour = (slsi_frame_priority_to_ac_queue(skb->priority) << 8) | (fapi_get_u16(skb, u.ma_unitdata_req.peer_index) << 3) | ndev_vif->ifnum << 1; +#ifdef CONFIG_SCSC_WIFILOGGER /* Log only the linear skb chunk ... unidata anywya will be truncated to 100.*/ SCSC_WLOG_PKTFATE_LOG_TX_DATA_FRAME(fapi_get_u16(skb, u.ma_unitdata_req.host_tag), skb->data, skb_headlen(skb)); +#endif /* ACCESS POINT MODE */ if (ndev_vif->vif_type == FAPI_VIFTYPE_AP) { @@ -516,9 +520,11 @@ int slsi_tx_control(struct slsi_dev *sdev, struct net_device *dev, struct sk_buf hdr = (struct fapi_signal_header *)skb->data; hdr->fw_reference = 0; +#ifdef CONFIG_SCSC_WIFILOGGER /* Log only the linear skb chunk */ SCSC_WLOG_PKTFATE_LOG_TX_CTRL_FRAME(fapi_get_u16(skb, u.mlme_frame_transmission_ind.host_tag), skb->data, skb_headlen(skb)); +#endif slsi_debug_frame(sdev, dev, skb, "TX"); res = scsc_wifi_transmit_frame(&sdev->hip4_inst, true, skb); diff --git a/drivers/net/wireless/scsc/utils.h b/drivers/net/wireless/scsc/utils.h index c13c49fe8c33..2a353728c9ae 100755 --- a/drivers/net/wireless/scsc/utils.h +++ b/drivers/net/wireless/scsc/utils.h @@ -13,8 +13,8 @@ #include #include #include -#include +#include "netif.h" #include "wakelock.h" #ifdef CONFIG_SCSC_SMAPPER struct slsi_skb_cb { diff --git a/include/scsc/api/bsmhcp.h b/include/scsc/api/bsmhcp.h index df67be6aa0db..b1bbbfc5ceaf 100755 --- a/include/scsc/api/bsmhcp.h +++ b/include/scsc/api/bsmhcp.h @@ -191,7 +191,7 @@ struct BSMHCP_TD_IQ_REPORTING_EVT { uint8_t cte_type; uint8_t slot_durations; uint8_t sample_count; - uint16_t reserved; + uint16_t event_count; uint8_t data[BSMHCP_IQ_REPORT_BUFFER_SIZE]; }; diff --git a/include/scsc/scsc_logring.h b/include/scsc/scsc_logring.h index e9054bf337e6..65ce407c8808 100644 --- a/include/scsc/scsc_logring.h +++ b/include/scsc/scsc_logring.h @@ -100,10 +100,14 @@ enum scsc_logring_tags { #define SCSC_NDEV_2_DEV(ndev) \ ((ndev) ? SCSC_SDEV_2_DEV(((struct netdev_vif *)netdev_priv(ndev))->sdev) : NULL) -#define SCSC_TAG_FMT(tag, fmt) "[" # tag "]: %-5s: - %s: "fmt -#define SCSC_TAG_DBG_FMT(tag, fmt) "[" # tag "]: %s: "fmt -#define SCSC_DEV_FMT(fmt) "%-5s: - %s: "fmt -#define SCSC_DBG_FMT(fmt) "%s: "fmt +#define SCSC_PREFIX "wlbt: " /* prepended to log statements */ + +#define SCSC_TAG_FMT(tag, fmt) SCSC_PREFIX"[" # tag "]: %-5s: - %s: "fmt +#define SCSC_TAG_DBG_FMT(tag, fmt) SCSC_PREFIX"[" # tag "]: %s: "fmt +#define SCSC_DEV_FMT(fmt) SCSC_PREFIX"%-5s: - %s: "fmt +#define SCSC_DBG_FMT(fmt) SCSC_PREFIX"%s: "fmt + +int scsc_logring_enable(bool logging_enable); #ifdef CONFIG_SCSC_PRINTK @@ -302,38 +306,38 @@ int scsc_printk_bin(int force, int tag, int dlev, const void *start, size_t len) (start), (len)) #define SCSC_EMERG_FF(args ...) scsc_printk_tag(FORCE_PRK, WLBT, \ - KERN_EMERG args) + KERN_EMERG SCSC_PREFIX args) #define SCSC_ALERT_FF(args ...) scsc_printk_tag(FORCE_PRK, WLBT, \ - KERN_ALERT args) + KERN_ALERT SCSC_PREFIX args) #define SCSC_CRIT_FF(args ...) scsc_printk_tag(FORCE_PRK, WLBT, \ - KERN_CRIT args) + KERN_CRIT SCSC_PREFIX args) #define SCSC_ERR_FF(args ...) scsc_printk_tag(FORCE_PRK, WLBT, \ - KERN_ERR args) + KERN_ERR SCSC_PREFIX args) #define SCSC_WARNING_FF(args ...) scsc_printk_tag(FORCE_PRK, WLBT, \ - KERN_WARNING args) + KERN_WARNING SCSC_PREFIX args) #define SCSC_NOTICE_FF(args ...) scsc_printk_tag(FORCE_PRK, WLBT, \ - KERN_NOTICE args) + KERN_NOTICE SCSC_PREFIX args) #define SCSC_INFO_FF(args ...) scsc_printk_tag(FORCE_PRK, WLBT, \ - KERN_INFO args) + KERN_INFO SCSC_PREFIX args) #define SCSC_DEBUG_FF(args ...) scsc_printk_tag(FORCE_PRK, WLBT, \ - KERN_DEBUG args) + KERN_DEBUG SCSC_PREFIX args) #define SCSC_TAG_EMERG_FF(tag, args ...) scsc_printk_tag(FORCE_PRK, (tag), \ - KERN_EMERG args) + KERN_EMERG SCSC_PREFIX args) #define SCSC_TAG_ALERT_FF(tag, args ...) scsc_printk_tag(FORCE_PRK, (tag), \ - KERN_ALERT args) + KERN_ALERT SCSC_PREFIX args) #define SCSC_TAG_CRIT_FF(tag, args ...) scsc_printk_tag(FORCE_PRK, (tag), \ - KERN_CRIT args) + KERN_CRIT SCSC_PREFIX args) #define SCSC_TAG_ERR_FF(tag, args ...) scsc_printk_tag(FORCE_PRK, (tag), \ - KERN_ERR args) + KERN_ERR SCSC_PREFIX args) #define SCSC_TAG_WARNING_FF(tag, args ...) scsc_printk_tag(FORCE_PRK, (tag), \ - KERN_WARNING args) + KERN_WARNING SCSC_PREFIX args) #define SCSC_TAG_NOTICE_FF(tag, args ...) scsc_printk_tag(FORCE_PRK, (tag), \ - KERN_NOTICE args) + KERN_NOTICE SCSC_PREFIX args) #define SCSC_TAG_INFO_FF(tag, args ...) scsc_printk_tag(FORCE_PRK, (tag), \ - KERN_INFO args) + KERN_INFO SCSC_PREFIX args) #define SCSC_TAG_DEBUG_FF(tag, args ...) scsc_printk_tag(FORCE_PRK, (tag), \ - KERN_DEBUG args) + KERN_DEBUG SCSC_PREFIX args) #define SCSC_BIN_EMERG_FF(start, len) scsc_printk_bin(FORCE_PRK, 0, \ (start), (len)) @@ -421,18 +425,18 @@ int scsc_printk_bin(int force, int tag, int dlev, const void *start, size_t len) dev_printk_emit((lvl), (dev), fmt, ## args);\ } while (0) -#define SCSC_PRINTK(fmt, args ...) printk(fmt, ## args) -#define SCSC_PRINTK_TAG(tag, fmt, args ...) printk("[" # tag "] "fmt, ## args) +#define SCSC_PRINTK(fmt, args ...) printk(SCSC_PREFIX fmt, ## args) +#define SCSC_PRINTK_TAG(tag, fmt, args ...) printk(SCSC_PREFIX "[" # tag "] "fmt, ## args) #define SCSC_PRINTK_BIN(start, len) print_hex_dump(KERN_INFO, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) -#define SCSC_PRINTK_FF(fmt, args ...) printk(fmt, ## args) -#define SCSC_PRINTK_TAG_FF(tag, fmt, args ...) printk("[" # tag "] "fmt, ## args) +#define SCSC_PRINTK_FF(fmt, args ...) printk(SCSC_PREFIX fmt, ## args) +#define SCSC_PRINTK_TAG_FF(tag, fmt, args ...) printk(SCSC_PREFIX"[" # tag "] "fmt, ## args) #define SCSC_PRINTK_BIN_FF(start, len) print_hex_dump(KERN_INFO, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) @@ -465,43 +469,43 @@ int scsc_printk_bin(int force, int tag, int dlev, const void *start, size_t len) #define SCSC_BIN_EMERG(start, len) print_hex_dump(KERN_EMERG, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_ALERT(start, len) print_hex_dump(KERN_ALERT, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_CRIT(start, len) print_hex_dump(KERN_CRIT, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_ERR(start, len) print_hex_dump(KERN_ERR, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_WARNING(start, len) print_hex_dump(KERN_WARNING, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_NOTICE(start, len) print_hex_dump(KERN_NOTICE, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_INFO(start, len) print_hex_dump(KERN_INFO, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) @@ -510,43 +514,43 @@ int scsc_printk_bin(int force, int tag, int dlev, const void *start, size_t len) #define SCSC_BIN_TAG_EMERG(tag, start, len) print_hex_dump(KERN_EMERG, \ - "[" # tag "]->|", \ + SCSC_PREFIX"[" # tag "]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_TAG_ALERT(tag, start, len) print_hex_dump(KERN_ALERT, \ - "[" # tag "]->|", \ + SCSC_PREFIX"[" # tag "]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_TAG_CRIT(tag, start, len) print_hex_dump(KERN_CRIT, \ - "[" # tag "]->|", \ + SCSC_PREFIX"[" # tag "]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_TAG_ERR(tag, start, len) print_hex_dump(KERN_ERR, \ - "[" # tag "]->|", \ + SCSC_PREFIX"[" # tag "]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_TAG_WARNING(tag, start, len) print_hex_dump(KERN_WARNING, \ - "[" # tag "]->|", \ + SCSC_PREFIX"[" # tag "]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_TAG_NOTICE(tag, start, len) print_hex_dump(KERN_NOTICE, \ - "[" # tag "]->|", \ + SCSC_PREFIX"[" # tag "]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_TAG_INFO(tag, start, len) print_hex_dump(KERN_INFO, \ - "[" # tag "]->|", \ + SCSC_PREFIX"[" # tag "]->|", \ DUMP_PREFIX_NONE, \ 16, 1, start, \ len, false) @@ -554,13 +558,13 @@ int scsc_printk_bin(int force, int tag, int dlev, const void *start, size_t len) #define SCSC_BIN_TAG_DEBUG(tag, start, len) do {} while (0) -#define SCSC_EMERG_FF(args ...) pr_emerg(args) -#define SCSC_ALERT_FF(args ...) pr_alert(args) -#define SCSC_CRIT_FF(args ...) pr_crit(args) -#define SCSC_ERR_FF(args ...) pr_err(args) -#define SCSC_WARNING_FF(args ...) pr_warn(args) -#define SCSC_NOTICE_FF(args ...) pr_notice(args) -#define SCSC_INFO_FF(args ...) pr_info(args) +#define SCSC_EMERG_FF(args ...) pr_emerg(SCSC_PREFIX args) +#define SCSC_ALERT_FF(args ...) pr_alert(SCSC_PREFIX args) +#define SCSC_CRIT_FF(args ...) pr_crit(SCSC_PREFIX args) +#define SCSC_ERR_FF(args ...) pr_err(SCSC_PREFIX args) +#define SCSC_WARNING_FF(args ...) pr_warn(SCSC_PREFIX args) +#define SCSC_NOTICE_FF(args ...) pr_notice(SCSC_PREFIX args) +#define SCSC_INFO_FF(args ...) pr_info(SCSC_PREFIX args) #define SCSC_DEBUG_FF(args ...) do {} while (0) @@ -581,43 +585,43 @@ int scsc_printk_bin(int force, int tag, int dlev, const void *start, size_t len) #define SCSC_TAG_DEBUG_FF(tag, fmt, args ...) do {} while (0) #define SCSC_BIN_EMERG_FF(start, len) print_hex_dump(KERN_EMERG, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_ALERT_FF(start, len) print_hex_dump(KERN_ALERT, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_CRIT_FF(start, len) print_hex_dump(KERN_CRIT, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_ERR_FF(start, len) print_hex_dump(KERN_ERR, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_WARNING_FF(start, len) print_hex_dump(KERN_WARNING, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_NOTICE_FF(start, len) print_hex_dump(KERN_NOTICE, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) #define SCSC_BIN_INFO_FF(start, len) print_hex_dump(KERN_INFO, \ - "[BINARY]->|", \ + SCSC_PREFIX"[BINARY]->|", \ DUMP_PREFIX_ADDRESS, \ 16, 4, start, \ len, true) diff --git a/include/scsc/scsc_mx.h b/include/scsc/scsc_mx.h index 41f0f0ade980..ff8965c877da 100755 --- a/include/scsc/scsc_mx.h +++ b/include/scsc/scsc_mx.h @@ -41,7 +41,9 @@ enum scsc_service_id { SCSC_SERVICE_ID_INVALID = 0xff, }; +#ifdef CONFIG_SCSC_QOS #define SCSC_SERVICE_TOTAL 9 +#endif enum scsc_module_client_reason { SCSC_MODULE_CLIENT_REASON_HW_PROBE = 0, @@ -50,14 +52,16 @@ enum scsc_module_client_reason { SCSC_MODULE_CLIENT_REASON_INVALID = 0xff, }; +#ifdef CONFIG_SCSC_QOS enum scsc_qos_config { SCSC_QOS_DISABLED = 0, SCSC_QOS_MIN = 1, SCSC_QOS_MED = 2, SCSC_QOS_MAX = 3, }; -/* Core Driver Module registration */ +#endif +/* Core Driver Module registration */ struct scsc_mx_module_client { char *name; void (*probe)(struct scsc_mx_module_client *module_client, struct scsc_mx *mx, enum scsc_module_client_reason reason); @@ -157,6 +161,8 @@ int scsc_mx_service_mifram_alloc(struct scsc_service *service, size_t nbytes, sc /* Same as scsc_mx_service_mifram_alloc but allows to specify flags (MIFRAMMAN_MEM_POOL_XX). * So, for example, to allocate memory from the logging pool use MIFRAMMAN_MEM_POOL_LOGGING. */ int scsc_mx_service_mifram_alloc_extended(struct scsc_service *service, size_t nbytes, scsc_mifram_ref *ref, u32 align, uint32_t flags); +struct scsc_bt_audio_abox *scsc_mx_service_get_bt_audio_abox(struct scsc_service *service); +struct mifabox *scsc_mx_service_get_aboxram(struct scsc_service *service); /** Free a contiguous block of SDRAM */ void scsc_mx_service_mifram_free(struct scsc_service *service, scsc_mifram_ref ref); void scsc_mx_service_mifram_free_extended(struct scsc_service *service, scsc_mifram_ref ref, uint32_t flags); @@ -211,6 +217,7 @@ int scsc_service_mifintrbit_free_fromhost(struct scsc_service *service, int whic * but this may change in future. */ struct device *scsc_service_get_device(struct scsc_service *service); +struct device *scsc_service_get_device_by_mx(struct scsc_mx *mx); int scsc_service_force_panic(struct scsc_service *service); @@ -237,9 +244,11 @@ u32 scsc_service_mifsmapper_get_bank_base_address(struct scsc_service *service, u16 scsc_service_get_alignment(struct scsc_service *service); #endif +#ifdef CONFIG_SCSC_QOS int scsc_service_pm_qos_add_request(struct scsc_service *service, enum scsc_qos_config config); int scsc_service_pm_qos_update_request(struct scsc_service *service, enum scsc_qos_config config); int scsc_service_pm_qos_remove_request(struct scsc_service *service); +#endif /* MXLOGGER API */ /* If there is no service/mxman associated, register the observer as global (will affect all the mx instanes)*/ diff --git a/include/scsc/scsc_release.h b/include/scsc/scsc_release.h index 86caa4c8b81d..ebea1c3a87e2 100644 --- a/include/scsc/scsc_release.h +++ b/include/scsc/scsc_release.h @@ -10,7 +10,7 @@ #define SCSC_RELEASE_SOLUTION "mx250" #define SCSC_RELEASE_PRODUCT 6 -#define SCSC_RELEASE_ITERATION 51 +#define SCSC_RELEASE_ITERATION 57 #define SCSC_RELEASE_CANDIDATE 0 #define SCSC_RELEASE_POINT 0 -- 2.20.1