From d0522510bcfa90d4fcafacfb5d40584d01793a8f Mon Sep 17 00:00:00 2001 From: Youngsoo Date: Tue, 12 Feb 2019 14:02:08 +0900 Subject: [PATCH] [RAMEN9610-12050][common][9610] wlbt : enable NAPI & RPS with update host version 6.62.1 1. [9610] wlbt: delibrately panic kernel on fw panic 2. [9610] wlbt: [DO NOT MERGE UPSTREAM] enable NAPI 3. [9610] wlbt: Prevent issues in slsi_acs_init 4. [9610] wlbt: make mutex acquire safe in HIP 5. [9610] wlbt: update debug messages for hip4_mbulk_to_skb() 6. wlbt: Destroy Bluez workqueue on close 7. [9610][7885][7872][7570] wlbt: Passing Correct Request Id in CFG80211 ... 8. [9610] wlbt: Relax allocation in process context 9. [9610] wlbt: NAPI: fix broken HIP4 watchdog 10. [9610] wlbt: increment scsc_release to 6.62.1 Change-Id: I7acbea3ed623ab01df599781ed279bd3824f715b --- arch/arm64/boot/dts/exynos/exynos9610.dtsi | 2 +- arch/arm64/configs/erd9610_defconfig | 1 + drivers/misc/samsung/scsc/miframman.c | 7 +- drivers/misc/samsung/scsc/mx250_fm.c | 36 +- drivers/misc/samsung/scsc/mx250_fm_test.c | 30 +- drivers/misc/samsung/scsc/mxlogger.c | 6 +- drivers/misc/samsung/scsc/mxman.c | 301 +++++++++++- drivers/misc/samsung/scsc/mxman.h | 7 +- drivers/misc/samsung/scsc/mxmgmt_transport.c | 10 +- drivers/misc/samsung/scsc/mxproc.c | 4 +- drivers/misc/samsung/scsc/platform_mif.c | 10 +- .../misc/samsung/scsc/scsc_log_collector.c | 19 +- drivers/misc/samsung/scsc/scsc_service.c | 9 + drivers/misc/samsung/scsc/scsc_wlbtd.c | 48 +- drivers/misc/samsung/scsc/scsc_wlbtd.h | 20 +- drivers/misc/samsung/scsc_bt/scsc_bluez.c | 76 +-- drivers/misc/samsung/scsc_bt/scsc_bt_module.c | 34 +- drivers/misc/samsung/scsc_bt/scsc_shm.c | 4 +- drivers/net/wireless/scsc/Kconfig | 9 + drivers/net/wireless/scsc/cfg80211_ops.c | 66 ++- drivers/net/wireless/scsc/cm_if.c | 10 +- drivers/net/wireless/scsc/dev.c | 21 +- drivers/net/wireless/scsc/dev.h | 13 +- drivers/net/wireless/scsc/fapi.h | 4 + drivers/net/wireless/scsc/hip4.c | 83 ++-- drivers/net/wireless/scsc/ioctl.c | 60 ++- drivers/net/wireless/scsc/mgt.c | 93 +++- drivers/net/wireless/scsc/mgt.h | 9 +- drivers/net/wireless/scsc/mib.h | 449 ++++++++++++++++-- drivers/net/wireless/scsc/mlme.c | 140 +++--- drivers/net/wireless/scsc/netif.c | 21 +- drivers/net/wireless/scsc/nl80211_vendor.c | 171 ++++++- drivers/net/wireless/scsc/nl80211_vendor.h | 2 - drivers/net/wireless/scsc/procfs.c | 74 +-- drivers/net/wireless/scsc/rx.c | 32 +- drivers/net/wireless/scsc/sap_mlme.c | 2 - drivers/net/wireless/scsc/tx.c | 12 + drivers/net/wireless/scsc/utils.h | 13 + include/scsc/scsc_log_collector.h | 1 + include/scsc/scsc_mx.h | 52 +- include/scsc/scsc_release.h | 2 +- 41 files changed, 1563 insertions(+), 400 deletions(-) diff --git a/arch/arm64/boot/dts/exynos/exynos9610.dtsi b/arch/arm64/boot/dts/exynos/exynos9610.dtsi index 03b9ca9daa95..ef9ed3c8ad63 100644 --- a/arch/arm64/boot/dts/exynos/exynos9610.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos9610.dtsi @@ -3373,7 +3373,7 @@ boot_cfg: syscon@14C60000 { compatible = "boot_cfg", "syscon"; - reg = <0x0 0x14C60000 0x1100>; + reg = <0x0 0x14C60000 0x1200>; }; /* MAILBOX_AP2WLBT */ diff --git a/arch/arm64/configs/erd9610_defconfig b/arch/arm64/configs/erd9610_defconfig index 926ad16e7111..88c3d22d9fec 100755 --- a/arch/arm64/configs/erd9610_defconfig +++ b/arch/arm64/configs/erd9610_defconfig @@ -261,6 +261,7 @@ CONFIG_SCSC_WLAN=y CONFIG_SCSC_WLAN_DEBUG=y CONFIG_SCSC_WLAN_WIFI_SHARING=y # CONFIG_SCSC_WLAN_SINGLE_ANTENNA is not set +CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE=y CONFIG_INPUT_EVDEV=y CONFIG_INPUT_KEYRESET=y CONFIG_KEYBOARD_GPIO=y diff --git a/drivers/misc/samsung/scsc/miframman.c b/drivers/misc/samsung/scsc/miframman.c index ba6253cec887..3663b657d609 100644 --- a/drivers/misc/samsung/scsc/miframman.c +++ b/drivers/misc/samsung/scsc/miframman.c @@ -87,7 +87,8 @@ void *__miframman_alloc(struct miframman *ram, size_t nbytes) index = index + available + 1; } end: - SCSC_TAG_INFO(MIF, "Not enough memory\n"); + SCSC_TAG_INFO(MIF, "Not enough shared memory (nbytes %zd, free_mem %u)\n", + nbytes, ram->free_mem); return NULL; exit: return free_mem; @@ -107,8 +108,10 @@ void *miframman_alloc(struct miframman *ram, size_t nbytes, size_t align) void *mem, *align_mem = NULL; mutex_lock(&ram->lock); - if (!is_power_of_2(align) || nbytes == 0) + if (!is_power_of_2(align) || nbytes == 0) { + SCSC_TAG_ERR(MIF, "Failed size/alignment check (nbytes %zd, align %zd)\n", nbytes, align); goto end; + } if (align < sizeof(void *)) align = sizeof(void *); diff --git a/drivers/misc/samsung/scsc/mx250_fm.c b/drivers/misc/samsung/scsc/mx250_fm.c index cb21ab7b14df..93c5f695082b 100755 --- a/drivers/misc/samsung/scsc/mx250_fm.c +++ b/drivers/misc/samsung/scsc/mx250_fm.c @@ -142,11 +142,17 @@ static int open_start_close_service(void) return r; } - if (fm_client->ldo_on) + if (fm_client->ldo_on) { + /* FM turning on */ scsc_service_on_halt_ldos_on(fm_client->fm_service); - else + } else { + /* FM turning off */ scsc_service_on_halt_ldos_off(fm_client->fm_service); + /* Invalidate stored FM params */ + scsc_service_fm_set_params(fm_client->fm_service, NULL); + } + r = stop_close_service(); if (r) { SCSC_TAG_ERR(FM, "Error starting service: stop_close_service(fm_service) failed %d\n", r); @@ -233,6 +239,9 @@ static int mx250_fm_re(bool ldo_on) } +/* + * FM Radio is starting, tell WLBT drivers + */ int mx250_fm_request(void) { @@ -241,6 +250,9 @@ int mx250_fm_request(void) } EXPORT_SYMBOL(mx250_fm_request); +/* + * FM Radio is stopping, tell WLBT drivers + */ int mx250_fm_release(void) { SCSC_TAG_DEBUG(FM, "mx250: %s\n", __func__); @@ -248,6 +260,26 @@ int mx250_fm_release(void) } EXPORT_SYMBOL(mx250_fm_release); +/* + * FM Radio parameters are changing, tell WLBT drivers + */ +void mx250_fm_set_params(struct wlbt_fm_params *info) +{ + SCSC_TAG_DEBUG(FM, "mx250: %s\n", __func__); + + if (!info) + return; + + mutex_lock(&ss_lock); + + SCSC_TAG_INFO(FM, "freq %u\n", info->freq); + + scsc_service_fm_set_params(fm_client->fm_service, info); + + mutex_unlock(&ss_lock); +} +EXPORT_SYMBOL(mx250_fm_set_params); + void fm_client_module_probe(struct scsc_mx_module_client *module_client, struct scsc_mx *mx, enum scsc_module_client_reason reason) { diff --git a/drivers/misc/samsung/scsc/mx250_fm_test.c b/drivers/misc/samsung/scsc/mx250_fm_test.c index 70706628ee07..7132367ef303 100644 --- a/drivers/misc/samsung/scsc/mx250_fm_test.c +++ b/drivers/misc/samsung/scsc/mx250_fm_test.c @@ -35,20 +35,20 @@ static int mx250_fm_test_dev_release(struct inode *inode, struct file *file) static ssize_t mx250_fm_test_dev_write(struct file *file, const char *data, size_t len, loff_t *offset) { unsigned long count; - char str[2]; /* One value and carry return */ - long int val = 0; - - if (len > 2) { - SCSC_TAG_ERR(FM_TEST, "Incorrect value len %zd\n", len); - goto error; - } + char str[20]; /* One value and carry return */ + long val = 0; + struct wlbt_fm_params params; + int r; count = copy_from_user(str, data, len); - str[1] = 0; + str[sizeof(str) - 1] = 0; + if (len < sizeof(str)) + str[len - 1] = 0; - if (kstrtol(str, 10, &val)) { - SCSC_TAG_ERR(FM_TEST, "Invalid value\n"); + r = kstrtol(str, 0, &val); + if (r) { + SCSC_TAG_ERR(FM_TEST, "parse error %d, l=%zd\n", r, len); goto error; } @@ -56,8 +56,14 @@ static ssize_t mx250_fm_test_dev_write(struct file *file, const char *data, size mx250_fm_request(); else if (val == 0) mx250_fm_release(); - else - SCSC_TAG_INFO(FM_TEST, "val %ld is not valid, 1 - on, 0 - off\n", val); + else { + /* All other values are frequency info */ + params.freq = (u32)val; + + SCSC_TAG_INFO(FM_TEST, "FM freq=%u\n", params.freq); + + mx250_fm_set_params(¶ms); + } error: return len; } diff --git a/drivers/misc/samsung/scsc/mxlogger.c b/drivers/misc/samsung/scsc/mxlogger.c index fa7baec3f3d0..4d46c8b8b70e 100644 --- a/drivers/misc/samsung/scsc/mxlogger.c +++ b/drivers/misc/samsung/scsc/mxlogger.c @@ -279,9 +279,13 @@ static int __mxlogger_generate_sync_record(struct mxlogger *mxlogger, enum mxlog /* 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 */ + /* FW didn't update the record (FW panic?) */ 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))); + 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; return 0; } diff --git a/drivers/misc/samsung/scsc/mxman.c b/drivers/misc/samsung/scsc/mxman.c index 3b1b33b32fab..38d44c8085c1 100755 --- a/drivers/misc/samsung/scsc/mxman.c +++ b/drivers/misc/samsung/scsc/mxman.c @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ @@ -88,7 +88,7 @@ static struct work_struct wlbtd_work; #define SCSC_R4_V2_MINOR_52 52 #define SCSC_R4_V2_MINOR_53 53 -#define MM_HALT_RSP_TIMEOUT_MS 1000 +#define MM_HALT_RSP_TIMEOUT_MS 100 static char panic_record_dump[PANIC_RECORD_DUMP_BUFFER_SZ]; static BLOCKING_NOTIFIER_HEAD(firmware_chain); @@ -149,9 +149,12 @@ static bool disable_error_handling; module_param(disable_error_handling, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(disable_error_handling, "Disable error handling"); -static bool disable_recovery_handling = 1; -module_param(disable_recovery_handling, bool, S_IRUGO | S_IWUSR); +int disable_recovery_handling = 1; /* MEMDUMP_FILE_FOR_RECOVERY : for /sys/wifi/memdump */ +module_param(disable_recovery_handling, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(disable_recovery_handling, "Disable recovery handling"); +static bool disable_recovery_from_memdump_file = true; +static int memdump = -1; +static bool disable_recovery_until_reboot; static uint panic_record_delay = 1; module_param(panic_record_delay, uint, S_IRUGO | S_IWUSR); @@ -161,6 +164,120 @@ static bool disable_logger = true; module_param(disable_logger, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(disable_logger, "Disable launch of user space logger"); +/* + * shared between this module and mgt.c as this is the kobject referring to + * /sys/wifi directory. Core driver is called 1st we create the directory + * here and share the kobject, so in mgt.c wifi driver can create + * /sys/wif/mac_addr using sysfs_create_file api using the kobject + * + * If both modules tried to create the dir we were getting kernel panic + * failure due to kobject associated with dir already existed + */ +static struct kobject *wifi_kobj_ref; +static int refcount; +static ssize_t sysfs_show_memdump(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); +static ssize_t sysfs_store_memdump(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count); +static struct kobj_attribute memdump_attr = + __ATTR(memdump, 0660, sysfs_show_memdump, sysfs_store_memdump); + +/* Retrieve memdump in sysfs global */ +static ssize_t sysfs_show_memdump(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", memdump); +} + +/* Update memdump in sysfs global */ +static ssize_t sysfs_store_memdump(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + int r; + + r = kstrtoint(buf, 10, &memdump); + if (r < 0) + memdump = -1; + + switch (memdump) { + case 0: + case 2: + disable_recovery_from_memdump_file = false; + break; + case 3: + default: + disable_recovery_from_memdump_file = true; + break; + } + + SCSC_TAG_INFO(MXMAN, "memdump: %d\n", memdump); + + return (r > 0) ? count : 0; +} + +struct kobject *mxman_wifi_kobject_ref_get(void) +{ + if (refcount++ == 0) { + /* Create sysfs directory /sys/wifi */ + wifi_kobj_ref = kobject_create_and_add("wifi", NULL); + kobject_get(wifi_kobj_ref); + kobject_uevent(wifi_kobj_ref, KOBJ_ADD); + SCSC_TAG_INFO(MXMAN, "wifi_kobj_ref: 0x%p\n", wifi_kobj_ref); + WARN_ON(refcount == 0); + } + return wifi_kobj_ref; +} +EXPORT_SYMBOL(mxman_wifi_kobject_ref_get); + +void mxman_wifi_kobject_ref_put(void) +{ + if (--refcount == 0) { + kobject_put(wifi_kobj_ref); + kobject_uevent(wifi_kobj_ref, KOBJ_REMOVE); + wifi_kobj_ref = NULL; + WARN_ON(refcount < 0); + } +} +EXPORT_SYMBOL(mxman_wifi_kobject_ref_put); + +/* Register memdump override */ +void mxman_create_sysfs_memdump(void) +{ + int r; + struct kobject *kobj_ref = mxman_wifi_kobject_ref_get(); + + SCSC_TAG_INFO(MXMAN, "kobj_ref: 0x%p\n", kobj_ref); + + if (kobj_ref) { + /* Create sysfs file /sys/wifi/memdump */ + r = sysfs_create_file(kobj_ref, &memdump_attr.attr); + if (r) { + /* Failed, so clean up dir */ + SCSC_TAG_ERR(MXMAN, "Can't create /sys/wifi/memdump\n"); + mxman_wifi_kobject_ref_put(); + return; + } + } else { + SCSC_TAG_ERR(MXMAN, "failed to create /sys/wifi directory"); + } +} + +/* Unregister memdump override */ +void mxman_destroy_sysfs_memdump(void) +{ + if (!wifi_kobj_ref) + return; + + /* Destroy /sys/wifi/memdump file */ + sysfs_remove_file(wifi_kobj_ref, &memdump_attr.attr); + + /* Destroy /sys/wifi virtual dir */ + mxman_wifi_kobject_ref_put(); +} + /* Track when WLBT reset fails to allow debug */ bool reset_failed; static u64 reset_failed_time; @@ -226,6 +343,7 @@ enum { MM_HOST_RESUME = 4, MM_FW_CONFIG = 5, MM_HALT_RSP = 6, + MM_FM_RADIO_CONFIG = 7, } ma_msg; /** @@ -238,6 +356,15 @@ struct ma_msg_packet { uint32_t arg; /* Optional arg set by f/w in some to-host messages */ } __packed; +/** + * Special case Maxwell management, carrying FM radio configuration structure + */ +struct ma_msg_packet_fm_radio_config { + + uint8_t ma_msg; /* Message from ma_msg enum */ + struct wlbt_fm_params fm_params; /* FM Radio parameters */ +} __packed; + static bool send_fw_config_to_active_mxman(uint32_t fw_runtime_flags) { bool ret = false; @@ -274,6 +401,43 @@ static bool send_fw_config_to_active_mxman(uint32_t fw_runtime_flags) return ret; } +static bool send_fm_params_to_active_mxman(struct wlbt_fm_params *params) +{ + bool ret = false; + struct srvman *srvman = NULL; + + SCSC_TAG_INFO(MXMAN, "\n"); + if (!active_mxman) { + SCSC_TAG_ERR(MXMAN, "Active MXMAN NOT FOUND...cannot send FM params\n"); + return false; + } + + mutex_lock(&active_mxman->mxman_mutex); + srvman = scsc_mx_get_srvman(active_mxman->mx); + if (srvman && srvman->error) { + mutex_unlock(&active_mxman->mxman_mutex); + SCSC_TAG_INFO(MXMAN, "Called during error - ignore\n"); + return false; + } + + if (active_mxman->mxman_state == MXMAN_STATE_STARTED) { + struct ma_msg_packet_fm_radio_config message = { .ma_msg = MM_FM_RADIO_CONFIG, + .fm_params = *params }; + + SCSC_TAG_INFO(MXMAN, "MM_FM_RADIO_CONFIG\n"); + mxmgmt_transport_send(scsc_mx_get_mxmgmt_transport(active_mxman->mx), + MMTRANS_CHAN_ID_MAXWELL_MANAGEMENT, &message, + sizeof(message)); + + ret = true; /* Success */ + } else + SCSC_TAG_INFO(MXMAN, "MXMAN is NOT STARTED...cannot send MM_FM_RADIO_CONFIG msg.\n"); + + mutex_unlock(&active_mxman->mxman_mutex); + + return ret; +} + static void mxman_stop(struct mxman *mxman); static void print_mailboxes(struct mxman *mxman); #ifdef CONFIG_SCSC_WLBTD @@ -309,7 +473,21 @@ static int wait_for_mm_msg_start_ind(struct mxman *mxman) static int wait_for_mm_msg_halt_rsp(struct mxman *mxman) { - return wait_for_mm_msg(mxman, &mxman->mm_msg_halt_rsp_completion, MM_HALT_RSP_TIMEOUT_MS); + int r; + (void)mxman; /* unused */ + + if (MM_HALT_RSP_TIMEOUT_MS == 0) { + /* Zero implies infinite wait */ + r = wait_for_completion_interruptible(&mxman->mm_msg_halt_rsp_completion); + /* r = -ERESTARTSYS if interrupted, 0 if completed */ + return r; + } + + r = wait_for_completion_timeout(&mxman->mm_msg_halt_rsp_completion, msecs_to_jiffies(MM_HALT_RSP_TIMEOUT_MS)); + if (r) + SCSC_TAG_INFO(MXMAN, "Received MM_HALT_RSP from firmware"); + + return r; } #ifndef CONFIG_SCSC_WLBTD @@ -358,11 +536,13 @@ static int send_mm_msg_stop_blocking(struct mxman *mxman) r = wait_for_mm_msg_halt_rsp(mxman); if (r) { - SCSC_TAG_ERR(MXMAN, "wait_for_MM_HALT_RSP() failed: r=%d\n", r); - return r; + /* + * MM_MSG_HALT_RSP is not implemented in all versions of firmware, so don't treat it's non-arrival + * as an error + */ + SCSC_TAG_INFO(MXMAN, "wait_for_MM_HALT_RSP completed"); } - return 0; } @@ -381,7 +561,11 @@ static char *chip_version(u32 rf_hw_ver) case 0x00b2: return "S620"; case 0x0000: +#ifndef CONFIG_SOC_EXYNOS9610 return "Error: check if RF chip is present"; +#else + return "Unknown"; +#endif } return "Unknown"; } @@ -569,14 +753,14 @@ static int transports_init(struct mxman *mxman) /* Initialise mx management stack */ r = mxmgmt_transport_init(scsc_mx_get_mxmgmt_transport(mx), mx); if (r) { - SCSC_TAG_ERR(MXMAN, "mxmgmt_transport_init() failed\n"); + SCSC_TAG_ERR(MXMAN, "mxmgmt_transport_init() failed %d\n", r); return r; } /* Initialise gdb transport for cortex-R4 */ r = gdb_transport_init(scsc_mx_get_gdb_transport_r4(mx), mx, GDB_TRANSPORT_R4); if (r) { - SCSC_TAG_ERR(MXMAN, "gdb_transport_init() failed\n"); + SCSC_TAG_ERR(MXMAN, "gdb_transport_init() failed %d\n", r); mxmgmt_transport_release(scsc_mx_get_mxmgmt_transport(mx)); return r; } @@ -584,7 +768,7 @@ static int transports_init(struct mxman *mxman) /* Initialise gdb transport for cortex-M4 */ r = gdb_transport_init(scsc_mx_get_gdb_transport_m4(mx), mx, GDB_TRANSPORT_M4); if (r) { - SCSC_TAG_ERR(MXMAN, "gdb_transport_init() failed\n"); + SCSC_TAG_ERR(MXMAN, "gdb_transport_init() failed %d\n", r); gdb_transport_release(scsc_mx_get_gdb_transport_r4(mx)); mxmgmt_transport_release(scsc_mx_get_mxmgmt_transport(mx)); return r; @@ -592,7 +776,7 @@ static int transports_init(struct mxman *mxman) /* Initialise mxlog transport */ r = mxlog_transport_init(scsc_mx_get_mxlog_transport(mx), mx); if (r) { - SCSC_TAG_ERR(MXMAN, "mxlog_transport_init() failed\n"); + SCSC_TAG_ERR(MXMAN, "mxlog_transport_init() failed %d\n", r); gdb_transport_release(scsc_mx_get_gdb_transport_m4(mx)); gdb_transport_release(scsc_mx_get_gdb_transport_r4(mx)); mxmgmt_transport_release(scsc_mx_get_mxmgmt_transport(mx)); @@ -898,12 +1082,6 @@ static int mxman_start(struct mxman *mxman) 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; @@ -997,10 +1175,17 @@ static int mxman_start(struct mxman *mxman) static bool is_bug_on_enabled(struct scsc_mx *mx) { -#define MX140_MEMDUMP_INFO_FILE "/data/.memdump.info" + bool bug_on_enabled = false; +#ifdef CONFIG_SCSC_LOG_COLLECTION + return bug_on_enabled; +#else +#if defined(ANDROID_VERSION) && (ANDROID_VERSION >= 90000) + #define MX140_MEMDUMP_INFO_FILE "/data/vendor/conn/.memdump.info" +#else + #define MX140_MEMDUMP_INFO_FILE "/data/misc/conn/.memdump.info" +#endif const struct firmware *firm; int r; - bool bug_on_enabled = false; SCSC_TAG_INFO(MX_FILE, "Loading %s file\n", MX140_MEMDUMP_INFO_FILE); r = mx140_request_file(mx, MX140_MEMDUMP_INFO_FILE, &firm); @@ -1013,7 +1198,9 @@ static bool is_bug_on_enabled(struct scsc_mx *mx) else if (*firm->data == '3') bug_on_enabled = true; mx140_release_file(mx, firm); + SCSC_TAG_INFO(MX_FILE, "bug_on_enabled %d\n", bug_on_enabled); return bug_on_enabled; +#endif //CONFIG_SCSC_LOG_COLLECTION } static void print_panic_code_legacy(u16 code) @@ -1129,7 +1316,7 @@ void mxman_show_last_panic(struct mxman *mxman) 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) { + if (mxman_recovery_disabled()) { /* Labour the point that a reboot is needed when autorecovery is disabled */ SCSC_TAG_INFO(MXMAN, "\n\n*** HANDSET REBOOT NEEDED TO RESTART WLAN AND BT ***\n\n"); } @@ -1379,15 +1566,16 @@ static void mxman_failure_work(struct work_struct *work) } if (is_bug_on_enabled(mx)) { - SCSC_TAG_INFO(MX_FILE, "Deliberately panic the kernel due to WLBT firmware failure!\n"); - SCSC_TAG_INFO(MX_FILE, "calling BUG_ON(1)\n"); + SCSC_TAG_ERR(MX_FILE, "Deliberately panic the kernel due to WLBT firmware failure!\n"); + SCSC_TAG_ERR(MX_FILE, "calling BUG_ON(1)\n"); BUG_ON(1); } /* Clean up the MIF following error handling */ if (mif->mif_cleanup && mxman_recovery_disabled()) mif->mif_cleanup(mif); } - SCSC_TAG_INFO(MXMAN, "Auto-recovery: %s\n", mxman_recovery_disabled() ? "off" : "on"); + SCSC_TAG_INFO(MXMAN, "Auto-recovery: %s\n", + mxman_recovery_disabled() ? "off" : "on"); if (!mxman_recovery_disabled()) srvman_clear_error(srvman); @@ -1602,6 +1790,12 @@ int mxman_open(struct mxman *mxman) break; /* Running or given up */ } + /* If we have stored FM radio parameters, deliver them to FW now */ + if (r == 0 && mxman->fm_params_pending) { + SCSC_TAG_INFO(MXMAN, "Send pending FM params\n"); + mxman_fm_set_params(mxman, &mxman->fm_params); + } + return r; } @@ -1747,6 +1941,12 @@ void mxman_fail(struct mxman *mxman, u16 scsc_panic_code, const char *reason) mxman->mxman_next_state = MXMAN_STATE_FAILED; mxman->scsc_panic_code = scsc_panic_code; strlcpy(mxman->failure_reason, reason, sizeof(mxman->failure_reason)); + /* If recovery is disabled, don't let it be + * re-enabled from now on. Device must reboot + */ + if (mxman_recovery_disabled()) + disable_recovery_until_reboot = true; + failure_wq_start(mxman); } else { SCSC_TAG_WARNING(MXMAN, "Not in MXMAN_STATE_STARTED state, ignore (state %d)\n", mxman->mxman_state); @@ -1771,6 +1971,7 @@ void mxman_init(struct mxman *mxman, struct scsc_mx *mx) mxman->suspended = 0; #ifdef CONFIG_SCSC_FM mxman->on_halt_ldos_on = 0; + mxman->fm_params_pending = 0; #endif fw_crc_wq_init(mxman); failure_wq_init(mxman); @@ -1790,10 +1991,17 @@ void mxman_init(struct mxman *mxman, struct scsc_mx *mx) sizeof(saved_fw_build_id)); mxproc_create_info_proc_dir(&mxman->mxproc, mxman); active_mxman = mxman; + +#if defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000 + mxman_create_sysfs_memdump(); +#endif } void mxman_deinit(struct mxman *mxman) { +#if defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000 + mxman_destroy_sysfs_memdump(); +#endif active_mxman = NULL; mxproc_remove_info_proc_dir(&mxman->mxproc); fw_crc_wq_deinit(mxman); @@ -1894,6 +2102,40 @@ void mxman_on_halt_ldos_off(struct mxman *mxman) mxman->on_halt_ldos_on = 0; is_fm_on = 0; } + +/* Update parameters passed to WLBT FM */ +int mxman_fm_set_params(struct mxman *mxman, struct wlbt_fm_params *params) +{ + /* May be called when WLBT is off, so find the context in this case */ + if (!mxman) + mxman = active_mxman; + + if (!active_mxman) { + SCSC_TAG_ERR(MXMAN, "No active MXMAN\n"); + return -EINVAL; + } + + /* Params are no longer valid (FM stopped) */ + if (!params) { + mxman->fm_params_pending = 0; + SCSC_TAG_INFO(MXMAN, "FM params cleared\n"); + return 0; + } + + /* Once set the value needs to be remembered for each time WLBT starts */ + mxman->fm_params = *params; + mxman->fm_params_pending = 1; + + if (send_fm_params_to_active_mxman(params)) { + SCSC_TAG_INFO(MXMAN, "FM params sent to FW\n"); + return 0; + } + + /* Stored for next time FW is up */ + SCSC_TAG_INFO(MXMAN, "FM params stored\n"); + + return -EAGAIN; +} #endif void mxman_resume(struct mxman *mxman) @@ -2070,7 +2312,16 @@ EXPORT_SYMBOL(mx140_log_dump); bool mxman_recovery_disabled(void) { - return disable_recovery_handling; + /* If FW has panicked when recovery was disabled, don't allow it to + * be enabled. The horse has bolted. + */ + if (disable_recovery_until_reboot) + return true; + + if (disable_recovery_handling == MEMDUMP_FILE_FOR_RECOVERY) + return disable_recovery_from_memdump_file; + else + return disable_recovery_handling ? true : false; } EXPORT_SYMBOL(mxman_recovery_disabled); diff --git a/drivers/misc/samsung/scsc/mxman.h b/drivers/misc/samsung/scsc/mxman.h index df4a18f3e237..f5bcda69f34d 100755 --- a/drivers/misc/samsung/scsc/mxman.h +++ b/drivers/misc/samsung/scsc/mxman.h @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2014 - 2017 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ @@ -26,11 +26,11 @@ void mxman_freeze(struct mxman *mxman); int mxman_force_panic(struct mxman *mxman); int mxman_suspend(struct mxman *mxman); void mxman_resume(struct mxman *mxman); -bool mxman_recovery_disabled(void); void mxman_show_last_panic(struct mxman *mxman); #ifdef CONFIG_SCSC_FM void mxman_on_halt_ldos_on(struct mxman *mxman); void mxman_on_halt_ldos_off(struct mxman *mxman); +int mxman_fm_set_params(struct mxman *mxman, struct wlbt_fm_params *params); #endif enum mxman_state { @@ -80,6 +80,9 @@ struct mxman { u32 on_halt_ldos_on; #endif char failure_reason[SCSC_FAILURE_REASON_LEN]; /* previous failure reason */ + struct wlbt_fm_params fm_params; /* FM freq info */ + int fm_params_pending; /* FM freq info waiting to be delivered to FW */ + }; void mxman_register_gdb_channel(struct scsc_mx *mx, mxmgmt_channel_handler handler, void *data); diff --git a/drivers/misc/samsung/scsc/mxmgmt_transport.c b/drivers/misc/samsung/scsc/mxmgmt_transport.c index a45506194c61..ec4f95c82b8f 100644 --- a/drivers/misc/samsung/scsc/mxmgmt_transport.c +++ b/drivers/misc/samsung/scsc/mxmgmt_transport.c @@ -181,8 +181,10 @@ static int mxmgmt_thread_start(struct mxmgmt_transport *mxmgmt_transport) /* Start the kernel thread */ th->task = kthread_run(mxmgmt_thread_function, mxmgmt_transport, "%s", th->name); - if (IS_ERR(th->task)) + if (IS_ERR(th->task)) { + SCSC_TAG_ERR(MXMGT_TRANS, "error creating kthread\n"); return (int)PTR_ERR(th->task); + } SCSC_TAG_DEBUG(MXMGT_TRANS, "Started thread %s\n", th->name); @@ -254,16 +256,20 @@ int mxmgmt_transport_init(struct mxmgmt_transport *mxmgmt_transport, struct scsc mutex_init(&mxmgmt_transport->channel_handler_mutex); mxmgmt_transport->mx = mx; r = mif_stream_init(&mxmgmt_transport->mif_istream, SCSC_MIF_ABS_TARGET_R4, MIF_STREAM_DIRECTION_IN, num_packets, packet_size, mx, MIF_STREAM_INTRBIT_TYPE_ALLOC, input_irq_handler, mxmgmt_transport); - if (r) + if (r) { + SCSC_TAG_ERR(MXMGT_TRANS, "mif_stream_init IN failed %d\n", r); return r; + } r = mif_stream_init(&mxmgmt_transport->mif_ostream, SCSC_MIF_ABS_TARGET_R4, MIF_STREAM_DIRECTION_OUT, num_packets, packet_size, mx, MIF_STREAM_INTRBIT_TYPE_ALLOC, output_irq_handler, mxmgmt_transport); if (r) { + SCSC_TAG_ERR(MXMGT_TRANS, "mif_stream_init OUT failed %d\n", r); mif_stream_release(&mxmgmt_transport->mif_istream); return r; } r = mxmgmt_thread_start(mxmgmt_transport); if (r) { + SCSC_TAG_ERR(MXMGT_TRANS, "mxmgmt_thread_start failed %d\n", r); mif_stream_release(&mxmgmt_transport->mif_istream); mif_stream_release(&mxmgmt_transport->mif_ostream); return r; diff --git a/drivers/misc/samsung/scsc/mxproc.c b/drivers/misc/samsung/scsc/mxproc.c index 2bca3b7ce41b..464aa3c00b3e 100644 --- a/drivers/misc/samsung/scsc/mxproc.c +++ b/drivers/misc/samsung/scsc/mxproc.c @@ -477,9 +477,7 @@ static ssize_t mx_procfs_mx_release_read(struct file *file, char __user *user_bu bytes = snprintf(buf, sizeof(buf), "Release: %d.%d.%d.%d (f/w: %s)\n", SCSC_RELEASE_PRODUCT, SCSC_RELEASE_ITERATION, SCSC_RELEASE_CANDIDATE, SCSC_RELEASE_POINT, build_id ? build_id : "unknown"); -#ifdef CONFIG_SCSC_WLBTD - scsc_wlbtd_get_and_print_build_type(); -#endif + if (bytes > sizeof(buf)) bytes = sizeof(buf); diff --git a/drivers/misc/samsung/scsc/platform_mif.c b/drivers/misc/samsung/scsc/platform_mif.c index 2ea092387a92..61d56b8760a0 100755 --- a/drivers/misc/samsung/scsc/platform_mif.c +++ b/drivers/misc/samsung/scsc/platform_mif.c @@ -665,7 +665,7 @@ irqreturn_t platform_wdog_isr(int irq, void *data) * be programmed using the CBUS during the config phase. */ uint32_t ka_patch[] = { - /* Power save fix #2 + /* Low temp fix 28/1 * Maxwell142 PMU+PROC combined boot ROM * IP Version: 0xA3 * Major Version: 0xF, Minor Version: 0xF @@ -711,9 +711,9 @@ uint32_t ka_patch[] = { 0x019e7522, 0x75cfc175, 0xc375a4c2, - 0x47c4750a, + 0x47c4754a, 0x75a4c575, - 0xc7756cc6, + 0xc7756dc6, 0x03d27540, 0x7510d375, 0xca7500c9, @@ -724,8 +724,8 @@ uint32_t ka_patch[] = { 0x78009d75, 0x12827402, 0xc6438b80, - 0x74057802, - 0x8b8012d0, + 0x74097802, + 0x8b8012e7, 0x75d09075, 0x9e750291, 0x01a97502, diff --git a/drivers/misc/samsung/scsc/scsc_log_collector.c b/drivers/misc/samsung/scsc/scsc_log_collector.c index f7df7e51dde1..08d51e0faf17 100644 --- a/drivers/misc/samsung/scsc/scsc_log_collector.c +++ b/drivers/misc/samsung/scsc/scsc_log_collector.c @@ -1,6 +1,6 @@ /******************************************************************************** * - * Copyright (c) 2016 - 2018 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd. All rights reserved. * ********************************************************************************/ #include @@ -316,12 +316,6 @@ static inline int __scsc_log_collector_collect_to_ram(enum scsc_log_reason reaso #define align_chunk(ppos) (((ppos) + (SCSC_LOG_CHUNK_ALIGN - 1)) & \ ~(SCSC_LOG_CHUNK_ALIGN - 1)) -const char *scsc_loc_reason_str[] = { "unknown", "scsc_log_fw_panic", - "scsc_log_user", - "scsc_log_fw", "scsc_log_dumpstate", - "scsc_log_host_wlan", "scsc_log_host_bt", - "scsc_log_host_common"/* Add others */}; - static inline int __scsc_log_collector_collect(enum scsc_log_reason reason, u16 reason_code, u8 buffer) { struct scsc_log_client *lc, *next; @@ -341,13 +335,14 @@ static inline int __scsc_log_collector_collect(enum scsc_log_reason reason, u16 mutex_lock(&log_mutex); - pr_info("Log collection triggered %s reason_code 0x%x\n", scsc_loc_reason_str[reason], reason_code); + pr_info("Log collection triggered %s reason_code 0x%x\n", + scsc_get_trigger_str((int)reason), reason_code); start = ktime_get(); if (buffer == TO_FILE) { snprintf(memdump_path, sizeof(memdump_path), "%s/%s.sbl", - collection_dir_buf, scsc_loc_reason_str[reason]); + collection_dir_buf, scsc_get_trigger_str((int)reason)); /* change to KERNEL_DS address limit */ old_fs = get_fs(); @@ -458,7 +453,7 @@ exit: #ifdef CONFIG_SCSC_WLBTD if (sbl_is_valid) - call_wlbtd_sable(scsc_loc_reason_str[reason], reason_code); + call_wlbtd_sable((u8)reason, reason_code); #endif pr_info("Log collection end. Took: %lld\n", ktime_to_ns(ktime_sub(ktime_get(), start))); @@ -497,7 +492,7 @@ void scsc_log_collector_schedule_collection(enum scsc_log_reason reason, u16 rea 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); + scsc_get_trigger_str((int)reason), reason_code); mutex_unlock(&log_status.collection_serial); return; } @@ -505,7 +500,7 @@ void scsc_log_collector_schedule_collection(enum scsc_log_reason reason, u16 rea 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 queue_work error\n", - scsc_loc_reason_str[reason], reason_code); + scsc_get_trigger_str((int)reason), reason_code); mutex_unlock(&log_status.collection_serial); return; } diff --git a/drivers/misc/samsung/scsc/scsc_service.c b/drivers/misc/samsung/scsc/scsc_service.c index 9f28ea9c52e0..f4d31035c937 100755 --- a/drivers/misc/samsung/scsc/scsc_service.c +++ b/drivers/misc/samsung/scsc/scsc_service.c @@ -676,6 +676,15 @@ void scsc_service_on_halt_ldos_off(struct scsc_service *service) mxman_on_halt_ldos_off(mxman); } EXPORT_SYMBOL(scsc_service_on_halt_ldos_off); + +int scsc_service_fm_set_params(struct scsc_service *service, struct wlbt_fm_params *params) +{ + /* We allow this to be called when service is off and store parameters */ + (void)service; + + return mxman_fm_set_params(NULL, params); +} +EXPORT_SYMBOL(scsc_service_fm_set_params); #endif struct scsc_bt_audio_abox *scsc_mx_service_get_bt_audio_abox(struct scsc_service *service) diff --git a/drivers/misc/samsung/scsc/scsc_wlbtd.c b/drivers/misc/samsung/scsc/scsc_wlbtd.c index 207dd878ef31..34003a677cad 100755 --- a/drivers/misc/samsung/scsc/scsc_wlbtd.c +++ b/drivers/misc/samsung/scsc/scsc_wlbtd.c @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ #include @@ -19,23 +19,24 @@ static DEFINE_MUTEX(sable_lock); static struct wake_lock wlbtd_wakelock; +/* module parameter controlling recovery handling */ +extern int disable_recovery_handling; + /** * This callback runs whenever the socket receives messages. */ static int msg_from_wlbtd_cb(struct sk_buff *skb, struct genl_info *info) { - int status; + int status = 0; if (info->attrs[1]) - SCSC_TAG_INFO(WLBTD, "returned data : %s\n", + SCSC_TAG_INFO(WLBTD, "ATTR_STR: %s\n", (char *)nla_data(info->attrs[1])); if (info->attrs[2]) { status = *((__u32 *)nla_data(info->attrs[2])); - if (!status) - SCSC_TAG_INFO(WLBTD, "returned status : %u\n", status); - else - SCSC_TAG_ERR(WLBTD, "returned error : %u\n", status); + if (status) + SCSC_TAG_ERR(WLBTD, "ATTR_INT: %u\n", status); } complete(&event_done); @@ -45,18 +46,25 @@ static int msg_from_wlbtd_cb(struct sk_buff *skb, struct genl_info *info) static int msg_from_wlbtd_sable_cb(struct sk_buff *skb, struct genl_info *info) { - int status; + int status = 0; if (info->attrs[1]) - SCSC_TAG_INFO(WLBTD, "returned data : %s\n", + SCSC_TAG_INFO(WLBTD, "%s\n", (char *)nla_data(info->attrs[1])); if (info->attrs[2]) { status = nla_get_u16(info->attrs[2]); - if (!status) - SCSC_TAG_INFO(WLBTD, "returned status : %u\n", status); - else - SCSC_TAG_ERR(WLBTD, "returned error : %u\n", status); + if (status) + SCSC_TAG_ERR(WLBTD, "%u\n", status); + } + + if (disable_recovery_handling == MEMDUMP_FILE_FOR_RECOVERY) { + if (status == MEMDUMP_FILE_KERNEL_PANIC) { + /* Auto recovery off + moredump + kernel panic */ + SCSC_TAG_INFO(WLBTD, "Deliberately panic the kernel due to WLBT firmware failure!\n"); + SCSC_TAG_INFO(WLBTD, "calling BUG_ON(1)\n"); + BUG_ON(1); + } } complete(&event_done); @@ -106,8 +114,8 @@ static struct nla_policy policies[] = { }; static struct nla_policy policy_sable[] = { - [ATTR_STR] = { .type = NLA_STRING, }, [ATTR_INT] = { .type = NLA_U16, }, + [ATTR_INT8] = { .type = NLA_U8, }, }; static struct nla_policy policies_build_type[] = { @@ -228,7 +236,7 @@ error: return -1; } -int call_wlbtd_sable(const char *trigger, u16 reason_code) +int call_wlbtd_sable(u8 trigger_code, u16 reason_code) { struct sk_buff *skb; void *msg; @@ -239,7 +247,8 @@ int call_wlbtd_sable(const char *trigger, u16 reason_code) mutex_lock(&sable_lock); wake_lock(&wlbtd_wakelock); - SCSC_TAG_INFO(WLBTD, "start:trigger - %s\n", trigger); + SCSC_TAG_INFO(WLBTD, "start:trigger - %s\n", + scsc_get_trigger_str((int)trigger_code)); skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); if (!skb) { @@ -267,9 +276,9 @@ int call_wlbtd_sable(const char *trigger, u16 reason_code) goto error; } - rc = nla_put_string(skb, ATTR_STR, trigger); + rc = nla_put_u8(skb, ATTR_INT8, trigger_code); if (rc) { - SCSC_TAG_ERR(WLBTD, "nla_put_string failed. rc = %d\n", rc); + SCSC_TAG_ERR(WLBTD, "nla_put_u8 failed. rc = %d\n", rc); genlmsg_cancel(skb, msg); goto error; } @@ -309,7 +318,8 @@ int call_wlbtd_sable(const char *trigger, u16 reason_code) /* reinit so completion can be re-used */ reinit_completion(&event_done); - SCSC_TAG_INFO(WLBTD, " end:trigger - %s\n", trigger); + SCSC_TAG_INFO(WLBTD, " end:trigger - %s\n", + scsc_get_trigger_str((int)trigger_code)); done: wake_unlock(&wlbtd_wakelock); diff --git a/drivers/misc/samsung/scsc/scsc_wlbtd.h b/drivers/misc/samsung/scsc/scsc_wlbtd.h index 51b821af65af..746c12d4d090 100644 --- a/drivers/misc/samsung/scsc/scsc_wlbtd.h +++ b/drivers/misc/samsung/scsc/scsc_wlbtd.h @@ -1,10 +1,16 @@ /**************************************************************************** * - * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ #include #include +#include + +/* module parameter value to indicate control of recovery via .memdump.info file */ +#define MEMDUMP_FILE_FOR_RECOVERY 2 +/* content of .memdump.info file indicating to panic kernel */ +#define MEMDUMP_FILE_KERNEL_PANIC 3 /** * Attributes are fields of data your messages will contain. @@ -12,16 +18,14 @@ * data to the packet payload. */ enum attributes { - /* - * The first one has to be a throwaway empty attribute; I don't know - * why. - * If you remove it, ATTR_HELLO (the first one) stops working, because - * it then becomes the throwaway. - */ + /* The first one has to be a throwaway empty attribute */ ATTR_UNSPEC, ATTR_STR, ATTR_INT, + ATTR_PATH, + ATTR_CONTENT, + ATTR_INT8, /* This must be last! */ __ATTR_MAX, @@ -49,5 +53,5 @@ static const struct genl_multicast_group scsc_mcgrp[] = { int scsc_wlbtd_init(void); int scsc_wlbtd_deinit(void); int call_wlbtd(const char *script_path); -int call_wlbtd_sable(const char *trigger, u16 reason_code); +int call_wlbtd_sable(u8 trigger_code, u16 reason_code); int scsc_wlbtd_get_and_print_build_type(void); diff --git a/drivers/misc/samsung/scsc_bt/scsc_bluez.c b/drivers/misc/samsung/scsc_bt/scsc_bluez.c index cb20ab756948..1c58f95c19f0 100755 --- a/drivers/misc/samsung/scsc_bt/scsc_bluez.c +++ b/drivers/misc/samsung/scsc_bt/scsc_bluez.c @@ -49,6 +49,37 @@ static struct file s_file; static struct platform_device *slsi_btz_pdev; static struct rfkill *btz_rfkill; +static const struct h4_recv_pkt scsc_recv_pkts[] = { + { H4_RECV_ACL, .recv = hci_recv_frame }, + { H4_RECV_EVENT, .recv = hci_recv_frame }, +}; + +static void slsi_bt_fs_read_func(struct work_struct *work) +{ + int ret; + struct sk_buff *skb = NULL; + + while ((ret = bt_fs->read(&s_file, receive_buffer, sizeof(receive_buffer), NULL)) >= 0) { + if (terminate_read) + break; + + if (ret > 0) { + skb = h4_recv_buf(hdev, skb, receive_buffer, + ret, scsc_recv_pkts, + ARRAY_SIZE(scsc_recv_pkts)); + + if (IS_ERR(skb)) { + SCSC_TAG_ERR(BT_COMMON, "corrupted event packet\n"); + hdev->stat.err_rx++; + break; + } + hdev->stat.byte_rx += ret; + } + } + + SCSC_TAG_INFO(BT_COMMON, "BT BlueZ: Exiting %s\n", __func__); +} + static int slsi_bt_open(struct hci_dev *hdev) { int err; @@ -59,6 +90,10 @@ static int slsi_bt_open(struct hci_dev *hdev) if (0 == err) { terminate_read = false; + if (wq == NULL) { + wq = create_singlethread_workqueue("slsi_bt_bluez_wq"); + INIT_WORK(&read_work, slsi_bt_fs_read_func); + } queue_work(wq, &read_work); } @@ -87,6 +122,11 @@ static int slsi_bt_close(struct hci_dev *hdev) ret = bt_fs->release(NULL, NULL); + if (wq != NULL) { + destroy_workqueue(wq); + wq = NULL; + } + SCSC_TAG_INFO(BT_COMMON, "done\n"); return ret; @@ -101,7 +141,7 @@ static int slsi_bt_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { int ret; - SCSC_TAG_INFO(BT_H4, "sending frame(data=%p, len=%u)\n", skb->data, skb->len); + SCSC_TAG_DEBUG(BT_H4, "sending frame(data=%p, len=%u)\n", skb->data, skb->len); memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); @@ -130,37 +170,6 @@ static int slsi_bt_send_frame(struct hci_dev *hdev, struct sk_buff *skb) return ret; } -static const struct h4_recv_pkt scsc_recv_pkts[] = { - { H4_RECV_ACL, .recv = hci_recv_frame }, - { H4_RECV_EVENT, .recv = hci_recv_frame }, -}; - -static void slsi_bt_fs_read_func(struct work_struct *work) -{ - int ret; - struct sk_buff *skb = NULL; - - while ((ret = bt_fs->read(&s_file, receive_buffer, sizeof(receive_buffer), NULL)) >= 0) { - if (terminate_read) - break; - - if (ret > 0) { - skb = h4_recv_buf(hdev, skb, receive_buffer, - ret, scsc_recv_pkts, - ARRAY_SIZE(scsc_recv_pkts)); - - if (IS_ERR(skb)) { - SCSC_TAG_ERR(BT_COMMON, "corrupted event packet\n"); - hdev->stat.err_rx++; - break; - } - hdev->stat.byte_rx += ret; - } - } - - SCSC_TAG_INFO(BT_COMMON, "BT BlueZ: Exiting %s \n", __func__); -} - static void slsi_bt_open_worker(struct work_struct *work) { int err; @@ -210,9 +219,6 @@ void slsi_bt_notify_probe(struct device *dev, read_wait_ref = read_wait; dev_ref = dev; - wq = create_singlethread_workqueue("slsi_bt_bluez_wq"); - INIT_WORK(&read_work, slsi_bt_fs_read_func); - SCSC_TAG_INFO(BT_COMMON, "SLSI BT BlueZ probe\n"); } diff --git a/drivers/misc/samsung/scsc_bt/scsc_bt_module.c b/drivers/misc/samsung/scsc_bt/scsc_bt_module.c index 67f3dca83ad8..49c8f9cef2dd 100755 --- a/drivers/misc/samsung/scsc_bt/scsc_bt_module.c +++ b/drivers/misc/samsung/scsc_bt/scsc_bt_module.c @@ -47,6 +47,7 @@ #define SLSI_BT_SERVICE_CLOSE_RETRY 60 #define SLSI_BT_SERVICE_STOP_RECOVERY_TIMEOUT 20000 +#define SLSI_BT_SERVICE_STOP_RECOVERY_DISABLED_TIMEOUT 2000 #define SCSC_ANT_MAX_TIMEOUT (20*HZ) @@ -65,6 +66,8 @@ static int bt_recovery_in_progress; static int ant_recovery_in_progress; #endif +static int recovery_timeout = SLSI_BT_SERVICE_STOP_RECOVERY_TIMEOUT; + struct scsc_common_service common_service; struct scsc_bt_service bt_service; #ifdef CONFIG_SCSC_ANT @@ -688,6 +691,7 @@ static int setup_bhcs(struct scsc_service *service, firm = NULL; } +#ifdef CONFIG_SCSC_DEBUG SCSC_TAG_DEBUG(BT_COMMON, "Bluetooth address: %04X:%02X:%06X\n", bhcs->bluetooth_address_nap, bhcs->bluetooth_address_uap, @@ -698,6 +702,7 @@ static int setup_bhcs(struct scsc_service *service, bhcs->bluetooth_address_nap, bhcs->bluetooth_address_uap, bhcs->bluetooth_address_lap); +#endif /* CONFIG_SCSC_DEBUG */ return err; } @@ -759,6 +764,14 @@ int slsi_sm_bt_service_start(void) goto exit; } + /* Shorter completion timeout if autorecovery is disabled, as it will + * never be signalled. + */ + if (mxman_recovery_disabled()) + recovery_timeout = SLSI_BT_SERVICE_STOP_RECOVERY_DISABLED_TIMEOUT; + else + recovery_timeout = SLSI_BT_SERVICE_STOP_RECOVERY_TIMEOUT; + /* Get shared memory region for the configuration structure from * the MIF */ @@ -997,6 +1010,15 @@ int slsi_sm_ant_service_start(void) goto exit; } + /* Shorter completion timeout if autorecovery is disabled, as it will + * never be signalled. + */ + if (mxman_recovery_disabled()) + recovery_timeout = SLSI_BT_SERVICE_STOP_RECOVERY_DISABLED_TIMEOUT; + else + recovery_timeout = SLSI_BT_SERVICE_STOP_RECOVERY_TIMEOUT; + + /* Get shared memory region for the configuration structure from * the MIF */ @@ -1182,7 +1204,7 @@ recovery: mutex_unlock(&bt_start_mutex); ret = wait_for_completion_timeout(&bt_service.recovery_probe_complete, - msecs_to_jiffies(SLSI_BT_SERVICE_STOP_RECOVERY_TIMEOUT)); + msecs_to_jiffies(recovery_timeout)); if (ret == 0) SCSC_TAG_INFO(BT_COMMON, "recovery_probe_complete timeout\n"); } @@ -1226,7 +1248,7 @@ recovery: mutex_unlock(&ant_start_mutex); ret = wait_for_completion_timeout(&ant_service.recovery_probe_complete, - msecs_to_jiffies(SLSI_BT_SERVICE_STOP_RECOVERY_TIMEOUT)); + msecs_to_jiffies(recovery_timeout)); if (ret == 0) SCSC_TAG_INFO(BT_COMMON, "recovery_probe_complete timeout\n"); } @@ -1454,6 +1476,10 @@ static void slsi_bt_service_remove(struct scsc_mx_module_client *module_client, if (reason == SCSC_MODULE_CLIENT_REASON_RECOVERY && bt_recovery_in_progress) { mutex_unlock(&bt_start_mutex); + + /* Wait forever for recovery_release_complete, as it will + * arrive even if autorecovery is disabled. + */ wait_for_completion(&bt_service.recovery_release_complete); reinit_completion(&bt_service.recovery_release_complete); @@ -1538,6 +1564,10 @@ static void slsi_ant_service_remove(struct scsc_mx_module_client *module_client, int ret; mutex_unlock(&ant_start_mutex); + + /* Wait full duration for recovery_release_complete, as it will + * arrive even if autorecovery is disabled. + */ ret = wait_for_completion_timeout(&ant_service.recovery_release_complete, msecs_to_jiffies(SLSI_BT_SERVICE_STOP_RECOVERY_TIMEOUT)); reinit_completion(&ant_service.recovery_release_complete); diff --git a/drivers/misc/samsung/scsc_bt/scsc_shm.c b/drivers/misc/samsung/scsc_bt/scsc_shm.c index 4490936c48c6..d1cdd2c6fde6 100755 --- a/drivers/misc/samsung/scsc_bt/scsc_shm.c +++ b/drivers/misc/samsung/scsc_bt/scsc_shm.c @@ -411,6 +411,7 @@ static ssize_t scsc_bt_shm_h4_acl_write(const unsigned char *data, size_t count) return count; } +#ifdef CONFIG_SCSC_PRINTK static const char *scsc_hci_evt_decode_event_code(u8 hci_event_code, u8 hci_ulp_sub_code) { const char *ret = "NA"; @@ -508,6 +509,7 @@ static const char *scsc_hci_evt_decode_event_code(u8 hci_event_code, u8 hci_ulp_ return ret; } +#endif static ssize_t scsc_iq_report_evt_read(char __user *buf, size_t len) { @@ -558,7 +560,7 @@ static ssize_t scsc_hci_evt_read(char __user *buf, size_t len) /* Is this the start of the copy operation */ if (0 == bt_service.read_offset) { - SCSC_TAG_INFO(BT_RX, "HCI Event [type=%s (0x%02x), length=%u]\n", + SCSC_TAG_DEBUG(BT_RX, "HCI Event [type=%s (0x%02x), length=%u]\n", scsc_hci_evt_decode_event_code(td->data[0], td->data[2]), td->data[0], td->data[1]); if (td->data[1] + HCI_EVENT_HEADER_LENGTH != td->length) { diff --git a/drivers/net/wireless/scsc/Kconfig b/drivers/net/wireless/scsc/Kconfig index daeb6f02cf82..fea095676678 100644 --- a/drivers/net/wireless/scsc/Kconfig +++ b/drivers/net/wireless/scsc/Kconfig @@ -39,12 +39,14 @@ config SCSC_WLAN_SKB_TRACKING config SCSC_WLAN_RX_NAPI bool "Enable use of net device napi rx polling api" + default y ---help--- This option enables the drivers use of the napi api config SCSC_WLAN_RX_NAPI_GRO bool "Enable use of net device napi rx GRO" depends on SCSC_WLAN_RX_NAPI + default y ---help--- This option enables the drivers use of the napi Generic Receive Offload @@ -180,3 +182,10 @@ config SCSC_AP_INTERFACE_NAME default "wlan1" ---help--- AP net device interface name. + +config SCSC_WLAN_MHS_STATIC_INTERFACE + bool "Static AP Interface Support" + default n + ---help--- + This option tells if AP interface has been created + statically or dynamically. diff --git a/drivers/net/wireless/scsc/cfg80211_ops.c b/drivers/net/wireless/scsc/cfg80211_ops.c index 39f404951c1b..67d67c4f8cdb 100755 --- a/drivers/net/wireless/scsc/cfg80211_ops.c +++ b/drivers/net/wireless/scsc/cfg80211_ops.c @@ -1,6 +1,6 @@ /*************************************************************************** * - * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ @@ -29,13 +29,18 @@ MODULE_PARM_DESC(keep_alive_period, "default is 10 seconds"); static bool slsi_is_mhs_active(struct slsi_dev *sdev) { struct net_device *mhs_dev = sdev->netdev_ap; - struct netdev_vif *ndev_vif = netdev_priv(mhs_dev); + struct netdev_vif *ndev_vif; bool ret; - SLSI_MUTEX_LOCK(ndev_vif->vif_mutex); - ret = ndev_vif->is_available; - SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex); - return ret; + if (mhs_dev) { + ndev_vif = netdev_priv(mhs_dev); + SLSI_MUTEX_LOCK(ndev_vif->vif_mutex); + ret = ndev_vif->is_available; + SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex); + return ret; + } + + return 0; } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) @@ -709,7 +714,7 @@ int slsi_sched_scan_start(struct wiphy *wiphy, if (r != 0) { if (r > 0) { SLSI_NET_DBG2(dev, SLSI_CFG80211, "Nothing to be done\n"); - cfg80211_sched_scan_stopped(wiphy, 0); + cfg80211_sched_scan_stopped(wiphy, request->reqid); r = 0; } else { SLSI_NET_DBG2(dev, SLSI_CFG80211, "add_scan error: %d\n", r); @@ -882,6 +887,10 @@ int slsi_connect(struct wiphy *wiphy, struct net_device *dev, } if (!memcmp(&connected_ssid[2], sme->ssid, connected_ssid[1])) { /*same ssid*/ + if (!sme->channel) { + SLSI_NET_ERR(dev, "Roaming has been rejected, as sme->channel is null\n"); + goto exit_with_error; + } r = slsi_mlme_roam(sdev, dev, sme->bssid, sme->channel->center_freq); if (r) { SLSI_NET_ERR(dev, "Failed to roam : %d\n", r); @@ -1092,7 +1101,8 @@ int slsi_disconnect(struct wiphy *wiphy, struct net_device *dev, * Unless the MLME-DISCONNECT-CFM fails. */ if (!ndev_vif->activated) { - r = -EINVAL; + r = 0; + SLSI_NET_INFO(dev, "Vif is already Deactivated\n"); goto exit; } @@ -1107,6 +1117,7 @@ int slsi_disconnect(struct wiphy *wiphy, struct net_device *dev, switch (ndev_vif->vif_type) { case FAPI_VIFTYPE_STATION: { + slsi_reset_throughput_stats(dev); /* Disconnecting spans several host firmware interactions so track the status * so that the Host can ignore connect related signaling eg. MLME-CONNECT-IND * now that it has triggered a disconnect. @@ -1356,22 +1367,6 @@ int slsi_get_station(struct wiphy *wiphy, struct net_device *dev, goto exit; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) - SLSI_NET_DBG1(dev, SLSI_CFG80211, "%pM, tx:%d, txbytes:%llu, rx:%d, rxbytes:%llu\n", - mac, - peer->sinfo.tx_packets, - peer->sinfo.tx_bytes, - peer->sinfo.rx_packets, - peer->sinfo.rx_bytes); -#else - SLSI_NET_DBG1(dev, SLSI_CFG80211, "%pM, tx:%d, txbytes:%d, rx:%d, rxbytes:%d\n", - mac, - peer->sinfo.tx_packets, - peer->sinfo.tx_bytes, - peer->sinfo.rx_packets, - peer->sinfo.rx_bytes); -#endif - if (((ndev_vif->iftype == NL80211_IFTYPE_STATION && !(ndev_vif->sta.roam_in_progress)) || ndev_vif->iftype == NL80211_IFTYPE_P2P_CLIENT)) { /*Read MIB and fill into the peer.sinfo*/ @@ -1385,6 +1380,26 @@ int slsi_get_station(struct wiphy *wiphy, struct net_device *dev, *sinfo = peer->sinfo; sinfo->generation = ndev_vif->cfg80211_sinfo_generation; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) + SLSI_NET_DBG1(dev, SLSI_CFG80211, "%pM, tx:%d, txbytes:%llu, rx:%d, rxbytes:%llu tx_fail:%d tx_retry:%d\n", + mac, + peer->sinfo.tx_packets, + peer->sinfo.tx_bytes, + peer->sinfo.rx_packets, + peer->sinfo.rx_bytes, + peer->sinfo.tx_failed, + peer->sinfo.tx_retries); +#else + SLSI_NET_DBG1(dev, SLSI_CFG80211, "%pM, tx:%d, txbytes:%d, rx:%d, rxbytes:%d tx_fail:%d tx_retry:%d\n", + mac, + peer->sinfo.tx_packets, + peer->sinfo.tx_bytes, + peer->sinfo.rx_packets, + peer->sinfo.rx_bytes, + peer->sinfo.tx_failed, + peer->sinfo.tx_retries); +#endif + exit: SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex); return r; @@ -2360,7 +2375,8 @@ int slsi_change_beacon(struct wiphy *wiphy, struct net_device *dev, int slsi_stop_ap(struct wiphy *wiphy, struct net_device *dev) { - /* AP stop stuff is done in del_station callback*/ + slsi_reset_throughput_stats(dev); + return 0; } diff --git a/drivers/net/wireless/scsc/cm_if.c b/drivers/net/wireless/scsc/cm_if.c index ea0a07441528..0f3447ee243e 100755 --- a/drivers/net/wireless/scsc/cm_if.c +++ b/drivers/net/wireless/scsc/cm_if.c @@ -33,7 +33,6 @@ static struct mutex slsi_start_mutex; static int recovery_in_progress; static u16 latest_scsc_panic_code; -#define SLSI_SM_WLAN_SERVICE_STOP_RECOVERY_TIMEOUT 20000 /* TODO: Would be good to get this removed - use module_client? */ struct slsi_cm_ctx { @@ -305,7 +304,7 @@ static void slsi_wlan_service_remove(struct scsc_mx_module_client *module_client mutex_unlock(&slsi_start_mutex); r = wait_for_completion_timeout(&sdev->recovery_stop_completion, - msecs_to_jiffies(SLSI_SM_WLAN_SERVICE_STOP_RECOVERY_TIMEOUT)); + msecs_to_jiffies(sdev->recovery_timeout)); if (r == 0) SLSI_INFO(sdev, "recovery_stop_completion timeout\n"); @@ -414,6 +413,9 @@ bool slsi_is_rf_test_mode_enabled(void) return EnableRfTestMode; } +#define SLSI_SM_WLAN_SERVICE_RECOVERY_COMPLETED_TIMEOUT 20000 +#define SLSI_SM_WLAN_SERVICE_RECOVERY_DISABLED_TIMEOUT 2000 + int slsi_sm_wlan_service_open(struct slsi_dev *sdev) { int err = 0; @@ -428,6 +430,8 @@ int slsi_sm_wlan_service_open(struct slsi_dev *sdev) goto exit; } + sdev->recovery_timeout = mxman_recovery_disabled() ? SLSI_SM_WLAN_SERVICE_RECOVERY_DISABLED_TIMEOUT : SLSI_SM_WLAN_SERVICE_RECOVERY_COMPLETED_TIMEOUT; + /* Open service - will download FW - will set MBOX0 with Starting address */ SLSI_INFO(sdev, "Open WLAN service\n"); sdev->service = scsc_mx_service_open(sdev->maxwell_core, SCSC_SERVICE_ID_WLAN, &sdev->mx_wlan_client, &err); @@ -554,7 +558,7 @@ static void __slsi_sm_wlan_service_stop_wait_locked(struct slsi_dev *sdev) mutex_unlock(&slsi_start_mutex); r = wait_for_completion_timeout(&sdev->recovery_remove_completion, - msecs_to_jiffies(SLSI_SM_WLAN_SERVICE_STOP_RECOVERY_TIMEOUT)); + msecs_to_jiffies(sdev->recovery_timeout)); if (r == 0) SLSI_INFO(sdev, "recovery_remove_completion timeout\n"); diff --git a/drivers/net/wireless/scsc/dev.c b/drivers/net/wireless/scsc/dev.c index fa4a70d09d29..4701f88e8fd3 100644 --- a/drivers/net/wireless/scsc/dev.c +++ b/drivers/net/wireless/scsc/dev.c @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ @@ -247,12 +247,10 @@ 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); + 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 SLSI_MUTEX_INIT(sdev->logger_mutex); -#endif sdev->dev = dev; sdev->maxwell_core = core; @@ -367,16 +365,21 @@ struct slsi_dev *slsi_dev_attach(struct device *dev, struct scsc_mx *core, struc SLSI_ERR(sdev, "failed to register with p2p netdev\n"); goto err_wlan_registered; } - +#if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000) if (slsi_netif_register(sdev, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]) != 0) { SLSI_ERR(sdev, "failed to register with p2px_wlan1 netdev\n"); - goto err_mhs_registered; + goto err_p2p_registered; } rcu_assign_pointer(sdev->netdev_ap, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]); +#endif #if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4 if (slsi_netif_register(sdev, sdev->netdev[SLSI_NET_INDEX_NAN]) != 0) { SLSI_ERR(sdev, "failed to register with NAN netdev\n"); - goto err_mhs_registered; +#if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000) + slsi_netif_remove(sdev, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]); + rcu_assign_pointer(sdev->netdev_ap, NULL); +#endif + goto err_p2p_registered; } #endif #endif @@ -406,10 +409,6 @@ err_nan_registered: slsi_netif_remove(sdev, sdev->netdev[SLSI_NET_INDEX_NAN]); #endif -err_mhs_registered: - slsi_netif_remove(sdev, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]); - rcu_assign_pointer(sdev->netdev_ap, NULL); - err_p2p_registered: slsi_netif_remove(sdev, sdev->netdev[SLSI_NET_INDEX_P2P]); diff --git a/drivers/net/wireless/scsc/dev.h b/drivers/net/wireless/scsc/dev.h index eb27876c45a8..11f8a55b3161 100755 --- a/drivers/net/wireless/scsc/dev.h +++ b/drivers/net/wireless/scsc/dev.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ @@ -155,7 +155,8 @@ static inline void ethr_ii_to_subframe_msdu(struct sk_buff *skb) #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 | SLSI_ACTION_FRAME_PROTECTED_DUAL) + SLSI_ACTION_FRAME_QOS | SLSI_ACTION_FRAME_PROTECTED_DUAL |\ + SLSI_ACTION_FRAME_RADIO_MEASUREMENT) /* Default value for MIB SLSI_PSID_UNIFI_DISCONNECT_TIMEOUT + 1 sec*/ #define SLSI_DEFAULT_AP_DISCONNECT_IND_TIMEOUT 3000 @@ -963,13 +964,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 + /* mutex to protect dynamic netdev removal */ + struct mutex netdev_remove_mutex; int netdev_up_count; struct net_device __rcu *netdev[CONFIG_SCSC_WLAN_MAX_INTERFACES + 1]; /* 0 is reserved */ struct net_device __rcu *netdev_ap; @@ -1094,18 +1094,17 @@ struct slsi_dev { u32 fw_dwell_time; int lls_num_radio; -#ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG struct slsi_mutex logger_mutex; #else /* a std mutex */ struct mutex logger_mutex; -#endif #endif struct slsi_traffic_mon_clients traffic_mon_clients; /*Store vif index corresponding to rtt id for FTM*/ u16 rtt_vif[8]; bool acs_channel_switched; + int recovery_timeout; /* ms autorecovery completion timeout */ }; /* Compact representation of channels a ESS has been seen on diff --git a/drivers/net/wireless/scsc/fapi.h b/drivers/net/wireless/scsc/fapi.h index b726062af1f6..b72e3a9dffbd 100644 --- a/drivers/net/wireless/scsc/fapi.h +++ b/drivers/net/wireless/scsc/fapi.h @@ -565,6 +565,10 @@ static inline struct slsi_skb_cb *slsi_skb_cb_init(struct sk_buff *skb) #define FAPI_RESULTCODE_AUTH_TIMEOUT 0x8010 #define FAPI_RESULTCODE_ASSOC_TIMEOUT 0x8011 #define FAPI_RESULTCODE_ASSOC_ABORT 0x8012 +/*Will remove it once we get latest fapi.xml */ +#define FAPI_RESULTCODE_AUTH_NO_ACK 0x8013 +#define FAPI_RESULTCODE_ASSOC_NO_ACK 0x8014 +/*--------------------------------------------------*/ #define FAPI_RESULTCODE_INVALID_TLV_VALUE 0x9000 #define FAPI_RESULTCODE_NAN_PROTOCOL_FAILURE 0x9001 #define FAPI_RESULTCODE_NAN_INVALID_PUBLISH_SUBSCRIBE_ID 0x9002 diff --git a/drivers/net/wireless/scsc/hip4.c b/drivers/net/wireless/scsc/hip4.c index 3ae77329d489..8d80f4142217 100755 --- a/drivers/net/wireless/scsc/hip4.c +++ b/drivers/net/wireless/scsc/hip4.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * *****************************************************************************/ @@ -58,7 +58,7 @@ static bool hip4_smapper_is_enabled; #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 */ +static int napi_select_cpu; /* CPU number */ module_param(napi_select_cpu, int, 0644); MODULE_PARM_DESC(napi_select_cpu, "select a specific CPU to execute NAPI poll"); #endif @@ -722,7 +722,7 @@ static struct mbulk *hip4_skb_to_mbulk(struct hip4_priv *hip, struct sk_buff *sk } /* Transform mbulk to skb (fapi_signal + payload) */ -static struct sk_buff *hip4_mbulk_to_skb(struct scsc_service *service, struct mbulk *m, scsc_mifram_ref *to_free, bool cfm) +static struct sk_buff *hip4_mbulk_to_skb(struct scsc_service *service, struct hip4_priv *hip_priv, struct mbulk *m, scsc_mifram_ref *to_free, bool atomic) { struct slsi_skb_cb *cb; struct mbulk *next_mbulk[MBULK_MAX_CHAIN]; @@ -735,8 +735,10 @@ static struct sk_buff *hip4_mbulk_to_skb(struct scsc_service *service, struct mb size_t bytes_to_alloc = 0; /* Get the mif ref pointer, check for incorrect mbulk */ - if (scsc_mx_service_mif_ptr_to_addr(service, m, &ref)) + if (scsc_mx_service_mif_ptr_to_addr(service, m, &ref)) { + SLSI_ERR_NODEV("mbulk address conversion failed\n"); return NULL; + } /* Track mbulk that should be freed */ to_free[free++] = ref; @@ -780,9 +782,15 @@ static struct sk_buff *hip4_mbulk_to_skb(struct scsc_service *service, struct mb } cont: - skb = slsi_alloc_skb(bytes_to_alloc, GFP_ATOMIC); + if (atomic) + skb = slsi_alloc_skb(bytes_to_alloc, GFP_ATOMIC); + else { + spin_unlock_bh(&hip_priv->rx_lock); + skb = slsi_alloc_skb(bytes_to_alloc, GFP_KERNEL); + spin_lock_bh(&hip_priv->rx_lock); + } if (!skb) { - SLSI_ERR_NODEV("Error allocating skb\n"); + SLSI_ERR_NODEV("Error allocating skb %d bytes\n", bytes_to_alloc); return NULL; } @@ -1027,7 +1035,10 @@ consume_fb_mbulk: 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]); + if (!atomic_read(&hip->hip_priv->closing)) { + atomic_set(&hip->hip_priv->watchdog_timer_active, 0); + 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); @@ -1108,10 +1119,9 @@ static void hip4_wq_ctrl(struct work_struct *data) 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); + skb = hip4_mbulk_to_skb(service, hip_priv, m, to_free, false); if (!skb) { - SLSI_ERR_NODEV("Ctrl: Error parsing skb\n"); + SLSI_ERR_NODEV("Ctrl: Error parsing or allocating skb\n"); hip4_dump_dbg(hip, m, skb, service); goto consume_ctl_mbulk; } @@ -1159,7 +1169,10 @@ consume_ctl_mbulk: 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]); + if (!atomic_read(&hip->hip_priv->closing)) { + atomic_set(&hip->hip_priv->watchdog_timer_active, 0); + 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); @@ -1225,8 +1238,11 @@ static int hip4_napi_poll(struct napi_struct *napi, int budget) 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]); + if (!atomic_read(&hip->hip_priv->closing)) { + atomic_set(&hip->hip_priv->watchdog_timer_active, 0); + /* 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; } @@ -1253,9 +1269,9 @@ static int hip4_napi_poll(struct napi_struct *napi, int budget) #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); + skb = hip4_mbulk_to_skb(service, hip_priv, m, to_free, true); if (!skb) { - SLSI_ERR_NODEV("Dat: Error parsing skb\n"); + SLSI_ERR_NODEV("Dat: Error parsing or allocating skb\n"); hip4_dump_dbg(hip, m, skb, service); goto consume_dat_mbulk; } @@ -1302,8 +1318,11 @@ consume_dat_mbulk: 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]); + if (!atomic_read(&hip->hip_priv->closing)) { + atomic_set(&hip->hip_priv->watchdog_timer_active, 0); + /* 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); @@ -1372,7 +1391,9 @@ static bool slsi_check_rx_flowcontrol(struct slsi_dev *sdev) if (ndev_vif) qlen = skb_queue_len(&ndev_vif->rx_data.queue); - SLSI_MUTEX_LOCK(sdev->netdev_remove_mutex); + if (!mutex_trylock(&sdev->netdev_remove_mutex)) + goto evaluate; + #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]); @@ -1386,8 +1407,9 @@ static bool slsi_check_rx_flowcontrol(struct slsi_dev *sdev) qlen += skb_queue_len(&ndev_vif->rx_data.queue); } #endif - SLSI_MUTEX_UNLOCK(sdev->netdev_remove_mutex); + mutex_unlock(&sdev->netdev_remove_mutex); +evaluate: if (qlen > max_buffered_frames) { SLSI_DBG1_NODEV(SLSI_HIP, "max qlen reached: %d\n", qlen); return true; @@ -1426,13 +1448,15 @@ static void hip4_wq(struct work_struct *data) return; } + service = sdev->service; + + atomic_set(&hip->hip_priv->in_rx, 1); if (slsi_check_rx_flowcontrol(sdev)) rx_flowcontrol = true; - service = sdev->service; - + atomic_set(&hip->hip_priv->in_rx, 2); spin_lock_bh(&hip_priv->rx_lock); - atomic_set(&hip->hip_priv->in_rx, 1); + atomic_set(&hip->hip_priv->in_rx, 3); bh_init = ktime_get(); @@ -1522,7 +1546,7 @@ consume_fb_mbulk: } SCSC_HIP4_SAMPLER_INT_OUT_BH(hip_priv->minor, 2); - atomic_set(&hip->hip_priv->in_rx, 2); + atomic_set(&hip->hip_priv->in_rx, 4); idx_r = hip4_read_index(hip, HIP4_MIF_Q_TH_CTRL, ridx); idx_w = hip4_read_index(hip, HIP4_MIF_Q_TH_CTRL, widx); @@ -1556,10 +1580,9 @@ consume_fb_mbulk: goto consume_ctl_mbulk; } /* Process Control Signal */ - - skb = hip4_mbulk_to_skb(service, m, to_free, false); + skb = hip4_mbulk_to_skb(service, hip_priv, m, to_free, false); if (!skb) { - SLSI_ERR_NODEV("Ctrl: Error parsing skb\n"); + SLSI_ERR_NODEV("Ctrl: Error parsing or allocating skb\n"); hip4_dump_dbg(hip, m, skb, service); goto consume_ctl_mbulk; } @@ -1619,7 +1642,7 @@ consume_ctl_mbulk: if (rx_flowcontrol) goto skip_data_q; - atomic_set(&hip->hip_priv->in_rx, 3); + atomic_set(&hip->hip_priv->in_rx, 5); idx_r = hip4_read_index(hip, HIP4_MIF_Q_TH_DAT, ridx); idx_w = hip4_read_index(hip, HIP4_MIF_Q_TH_DAT, widx); @@ -1676,9 +1699,9 @@ consume_ctl_mbulk: goto consume_dat_mbulk; } - skb = hip4_mbulk_to_skb(service, m, to_free, false); + skb = hip4_mbulk_to_skb(service, hip_priv, m, to_free, false); if (!skb) { - SLSI_ERR_NODEV("Dat: Error parsing skb\n"); + SLSI_ERR_NODEV("Dat: Error parsing or allocating skb\n"); hip4_dump_dbg(hip, m, skb, service); goto consume_dat_mbulk; } @@ -1801,7 +1824,7 @@ static void hip4_irq_handler(int irq, void *data) SLSI_ERR_NODEV("bh_init %lld\n", ktime_to_ns(bh_init)); SLSI_ERR_NODEV("bh_end %lld\n", ktime_to_ns(bh_end)); SLSI_ERR_NODEV("hip4_wq work_busy %d\n", work_busy(&hip->hip_priv->intr_wq)); - SLSI_ERR_NODEV("hip4_priv->in_rx %d\n", atomic_read(&hip->hip_priv->in_rx)); + 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)) { diff --git a/drivers/net/wireless/scsc/ioctl.c b/drivers/net/wireless/scsc/ioctl.c index bc4e8e521177..7d6395af8379 100755 --- a/drivers/net/wireless/scsc/ioctl.c +++ b/drivers/net/wireless/scsc/ioctl.c @@ -106,6 +106,7 @@ #define CMD_SET_TX_POWER_CALLING "SET_TX_POWER_CALLING" #define CMD_DRIVERDEBUGDUMP "DEBUG_DUMP" +#define CMD_DRIVERDEBUGCOMMAND "DEBUG_COMMAND" #define CMD_TESTFORCEHANG "SLSI_TEST_FORCE_HANG" #define CMD_GETREGULATORY "GETREGULATORY" @@ -660,17 +661,26 @@ static ssize_t slsi_rx_filter_num_write(struct net_device *dev, int add_remove, } #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING +#if !defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION < 90000) static ssize_t slsi_create_interface(struct net_device *dev, char *intf_name) { struct netdev_vif *ndev_vif = netdev_priv(dev); struct slsi_dev *sdev = ndev_vif->sdev; - struct net_device *swlan_dev; + struct net_device *ap_dev; - swlan_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_P2PX_SWLAN); - if (swlan_dev && (swlan_dev->name == intf_name)) + ap_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_P2PX_SWLAN); + if (ap_dev && (strcmp(ap_dev->name, intf_name) == 0)) { + SLSI_NET_ERR(dev, "%s already created\n", intf_name); + return -EINVAL; + } + + ap_dev = slsi_dynamic_interface_create(sdev->wiphy, intf_name, NL80211_IFTYPE_AP, NULL); + if (ap_dev) { + sdev->netdev_ap = ap_dev; return 0; + } - SLSI_NET_ERR(dev, "Failed to create interface %s\n", intf_name); + SLSI_NET_ERR(dev, "Failed to create AP interface %s\n", intf_name); return -EINVAL; } @@ -678,19 +688,26 @@ static ssize_t slsi_delete_interface(struct net_device *dev, char *intf_name) { struct netdev_vif *ndev_vif = netdev_priv(dev); struct slsi_dev *sdev = ndev_vif->sdev; - struct net_device *swlan_dev; - swlan_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_P2PX_SWLAN); - if (swlan_dev && (swlan_dev->name == intf_name)) { - ndev_vif = netdev_priv(swlan_dev); - if (ndev_vif->activated) - slsi_stop_net_dev(sdev, swlan_dev); - return 0; + if (strcmp(intf_name, CONFIG_SCSC_AP_INTERFACE_NAME) == 0) + dev = sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]; + + if (!dev) { + SLSI_WARN(sdev, "AP dev is NULL"); + return -EINVAL; } + ndev_vif = netdev_priv(dev); - SLSI_NET_ERR(dev, "Failed to delete interface %s\n", intf_name); - return -EINVAL; + if (ndev_vif->activated) + slsi_stop_net_dev(sdev, dev); + slsi_netif_remove_rtlnl_locked(sdev, dev); + + sdev->netdev_ap = NULL; + SLSI_DBG1_NODEV(SLSI_MLME, "Successfully deleted AP interface %s ", intf_name); + + return 0; } +#endif static ssize_t slsi_set_indoor_channels(struct net_device *dev, char *arg) { @@ -2127,6 +2144,7 @@ int slsi_get_sta_info(struct net_device *dev, char *command, int buf_len) return -EINVAL; } +#if defined(ANDROID_VERSION) && (ANDROID_VERSION >= 90000) len = snprintf(command, buf_len, "GETSTAINFO %pM Rx_Retry_Pkts=%d Rx_BcMc_Pkts=%d CAP=%04x %02x:%02x:%02x ", ndev_vif->ap.last_disconnected_sta.address, ndev_vif->ap.last_disconnected_sta.rx_retry_packets, @@ -2142,6 +2160,15 @@ int slsi_get_sta_info(struct net_device *dev, char *command, int buf_len) ndev_vif->ap.last_disconnected_sta.tx_data_rate, ndev_vif->ap.last_disconnected_sta.mode, ndev_vif->ap.last_disconnected_sta.antenna_mode, ndev_vif->ap.last_disconnected_sta.mimo_used, ndev_vif->ap.last_disconnected_sta.reason); +#else + len = snprintf(command, buf_len, "wl_get_sta_info : %02x%02x%02x %u %d %d %d %d %d %d %u ", + ndev_vif->ap.last_disconnected_sta.address[0], ndev_vif->ap.last_disconnected_sta.address[1], + ndev_vif->ap.last_disconnected_sta.address[2], ndev_vif->ap.channel_freq, + ndev_vif->ap.last_disconnected_sta.bandwidth, ndev_vif->ap.last_disconnected_sta.rssi, + ndev_vif->ap.last_disconnected_sta.tx_data_rate, ndev_vif->ap.last_disconnected_sta.mode, + ndev_vif->ap.last_disconnected_sta.antenna_mode, + ndev_vif->ap.last_disconnected_sta.mimo_used, ndev_vif->ap.last_disconnected_sta.reason); +#endif SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex); @@ -2253,6 +2280,7 @@ int slsi_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = slsi_rx_filter_num_write(dev, 0, filter_num); #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING +#if !defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION < 90000) } else if (strncasecmp(command, CMD_INTERFACE_CREATE, strlen(CMD_INTERFACE_CREATE)) == 0) { char *intf_name = command + strlen(CMD_INTERFACE_CREATE) + 1; @@ -2261,6 +2289,7 @@ int slsi_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) char *intf_name = command + strlen(CMD_INTERFACE_DELETE) + 1; ret = slsi_delete_interface(dev, intf_name); +#endif } else if (strncasecmp(command, CMD_SET_INDOOR_CHANNELS, strlen(CMD_SET_INDOOR_CHANNELS)) == 0) { char *arg = command + strlen(CMD_SET_INDOOR_CHANNELS) + 1; @@ -2474,10 +2503,11 @@ int slsi_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) (strncasecmp(command, CMD_SETSINGLEANT, strlen(CMD_SETSINGLEANT)) == 0)) { ret = -ENOTSUPP; #ifndef SLSI_TEST_DEV - } else if (strncasecmp(command, CMD_DRIVERDEBUGDUMP, strlen(CMD_DRIVERDEBUGDUMP)) == 0) { + } else if ((strncasecmp(command, CMD_DRIVERDEBUGDUMP, strlen(CMD_DRIVERDEBUGDUMP)) == 0) || + (strncasecmp(command, CMD_DRIVERDEBUGCOMMAND, strlen(CMD_DRIVERDEBUGCOMMAND)) == 0)) { slsi_dump_stats(dev); #ifdef CONFIG_SCSC_LOG_COLLECTION - scsc_log_collector_schedule_collection(SCSC_LOG_HOST_WLAN, SCSC_LOG_HOST_WLAN_REASON_DRIVERDEBUGDUMP); + scsc_log_collector_schedule_collection(SCSC_LOG_DUMPSTATE, SCSC_LOG_DUMPSTATE_REASON_DRIVERDEBUGDUMP); #else ret = mx140_log_dump(); #endif diff --git a/drivers/net/wireless/scsc/mgt.c b/drivers/net/wireless/scsc/mgt.c index d5d444682f15..f80ca486d438 100755 --- a/drivers/net/wireless/scsc/mgt.c +++ b/drivers/net/wireless/scsc/mgt.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved * *****************************************************************************/ @@ -66,6 +66,74 @@ 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 struct kobject *wifi_kobj_ref; +static char sysfs_mac_override[] = "ff:ff:ff:ff:ff:ff"; +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; + + wifi_kobj_ref = mxman_wifi_kobject_ref_get(); + pr_info("wifi_kobj_ref: 0x%p\n", wifi_kobj_ref); + + if (wifi_kobj_ref) { + /* Create sysfs file /sys/wifi/mac_addr */ + r = sysfs_create_file(wifi_kobj_ref, &mac_attr.attr); + if (r) { + /* Failed, so clean up dir */ + pr_err("Can't create /sys/wifi/mac_addr\n"); + return; + } + } else { + pr_err("failed to create /sys/wifi/mac_addr\n"); + } +} + +/* Unregister sysfs mac address override */ +void slsi_destroy_sysfs_macaddr(void) +{ + if (!wifi_kobj_ref) + return; + + /* Destroy /sys/wifi/mac_addr file */ + sysfs_remove_file(wifi_kobj_ref, &mac_attr.attr); + + /* Destroy /sys/wifi virtual dir */ + mxman_wifi_kobject_ref_put(); +} + void slsi_purge_scan_results_locked(struct netdev_vif *ndev_vif, u16 scan_id) { struct slsi_scan_result *scan_result; @@ -368,7 +436,6 @@ struct scsc_log_collector_client slsi_hcf_client = { }; #endif -#define SLSI_SM_WLAN_SERVICE_RECOVERY_COMPLETED_TIMEOUT 20000 int slsi_start(struct slsi_dev *sdev) { #ifndef CONFIG_SCSC_DOWNLOAD_FILE @@ -398,7 +465,7 @@ int slsi_start(struct slsi_dev *sdev) if (sdev->recovery_status) { r = wait_for_completion_timeout(&sdev->recovery_completed, - msecs_to_jiffies(SLSI_SM_WLAN_SERVICE_RECOVERY_COMPLETED_TIMEOUT)); + msecs_to_jiffies(sdev->recovery_timeout)); if (r == 0) SLSI_INFO(sdev, "recovery_completed timeout\n"); @@ -532,7 +599,7 @@ 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 +#if defined(ANDROID_VERSION) && (ANDROID_VERSION >= 90000) offset += snprintf(buf + offset, sizeof(buf), "DualInterface=%s\n", "yes"); #else offset += snprintf(buf + offset, sizeof(buf), "DualInterface=%s\n", "no"); @@ -773,7 +840,7 @@ void slsi_scan_cleanup(struct slsi_dev *sdev, struct net_device *dev) if (ndev_vif->scan[i].sched_req && i == SLSI_SCAN_SCHED_ID) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) - cfg80211_sched_scan_stopped(sdev->wiphy, SLSI_SCAN_SCHED_ID); + cfg80211_sched_scan_stopped(sdev->wiphy, ndev_vif->scan[i].sched_req->reqid); #else cfg80211_sched_scan_stopped(sdev->wiphy); #endif @@ -1371,6 +1438,22 @@ int slsi_set_mib_roam(struct slsi_dev *dev, struct net_device *ndev, u16 psid, i return error; } +void slsi_reset_throughput_stats(struct net_device *dev) +{ + struct netdev_vif *ndev_vif = netdev_priv(dev); + struct slsi_dev *sdev = ndev_vif->sdev; + struct slsi_mib_data mib_data = { 0, NULL }; + int error = SLSI_MIB_STATUS_FAILURE; + + if (slsi_mib_encode_int(&mib_data, SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, 0, 0) == SLSI_MIB_STATUS_SUCCESS) + if (mib_data.dataLength) { + error = slsi_mlme_set(sdev, dev, mib_data.data, mib_data.dataLength); + if (error) + SLSI_ERR(sdev, "Err Setting MIB failed. error = %d\n", error); + kfree(mib_data.data); + } +} + int slsi_get_mib_roam(struct slsi_dev *sdev, u16 psid, int *mib_value) { struct slsi_mib_data mibreq = { 0, NULL }; diff --git a/drivers/net/wireless/scsc/mgt.h b/drivers/net/wireless/scsc/mgt.h index 31c909a692c9..631a975d4bc4 100755 --- a/drivers/net/wireless/scsc/mgt.h +++ b/drivers/net/wireless/scsc/mgt.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved * *****************************************************************************/ @@ -45,6 +45,12 @@ #define SLSI_EAPOL_KEY_DATA_LENGTH_HIGHER_BYTE_POS (97) #define SLSI_EAPOL_KEY_DATA_LENGTH_LOWER_BYTE_POS (98) +#define SLSI_EAP_CODE_POS (4) +#define SLSI_EAP_PACKET_REQUEST (1) +#define SLSI_EAP_PACKET_RESPONSE (2) +#define SLSI_EAP_PACKET_SUCCESS (3) +#define SLSI_EAP_PACKET_FAILURE (4) + #define SLSI_80211_AC_VO 0 #define SLSI_80211_AC_VI 1 #define SLSI_80211_AC_BE 2 @@ -449,6 +455,7 @@ int slsi_update_packet_filters(struct slsi_dev *sdev, struct net_device *dev); int slsi_clear_packet_filters(struct slsi_dev *sdev, struct net_device *dev); int slsi_ap_prepare_add_info_ies(struct netdev_vif *ndev_vif, const u8 *ies, size_t ies_len); int slsi_set_mib_roam(struct slsi_dev *dev, struct net_device *ndev, u16 psid, int value); +void slsi_reset_throughput_stats(struct net_device *dev); int slsi_set_mib_rssi_boost(struct slsi_dev *sdev, struct net_device *dev, u16 psid, int index, int boost); void slsi_modify_ies_on_channel_switch(struct net_device *dev, struct cfg80211_ap_settings *settings, u8 *ds_params_ie, u8 *ht_operation_ie, struct ieee80211_mgmt *mgmt, diff --git a/drivers/net/wireless/scsc/mib.h b/drivers/net/wireless/scsc/mib.h index 2200988c2e69..cc6f5ab3dddd 100644 --- a/drivers/net/wireless/scsc/mib.h +++ b/drivers/net/wireless/scsc/mib.h @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ @@ -333,7 +333,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint16 * MIN : 1 * MAX : 255 - * DEFAULT : 15 + * DEFAULT : 32 * DESCRIPTION : * Maximum number of transmission attempts of a frame, the length of which * is less than or equal to dot11RTSThreshold, that shall be made before a @@ -614,6 +614,19 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_MLME_SCAN_CHANNEL_PROBE_INTERVAL 0x07D2 +/******************************************************************************* + * NAME : UnifiMlmeScanChannelRule + * PSID : 2003 (0x07D3) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 4 + * MAX : 4 + * DEFAULT : { 0X00, 0X01, 0X00, 0X01 } + * DESCRIPTION : + * Rules for channel scanners. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_MLME_SCAN_CHANNEL_RULE 0x07D3 + /******************************************************************************* * NAME : UnifiMlmeDataReferenceTimeout * PSID : 2005 (0x07D5) @@ -667,7 +680,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 255 * DEFAULT : 20 * DESCRIPTION : - * Magnitude of the change in RSSI for which a scan result will be issued + * Magnitude of the change in RSSI for which a scan result will be issued. *******************************************************************************/ #define SLSI_PSID_UNIFI_MLME_SCAN_DELTA_RSSI_THRESHOLD 0x07DA @@ -795,7 +808,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint8 * MIN : 9 * MAX : 9 - * DEFAULT : { 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X40, 0X00 } + * DEFAULT : { 0X01, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X40, 0X80 } * DESCRIPTION : * Extended capabilities. Bit field definition and coding follows IEEE * 802.11 Extended Capability Information Element, with spare subfields for @@ -817,6 +830,19 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_HT_CAPABILITIES 0x07F0 +/******************************************************************************* + * NAME : UnifiSoftAp40MhzOn24g + * PSID : 2034 (0x07F2) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * Enables 40MHz operation on 2.4GHz band for SoftAP. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_SOFT_AP40_MHZ_ON24G 0x07F2 + /******************************************************************************* * NAME : Unifi24G40MhzChannels * PSID : 2035 (0x07F3) @@ -826,8 +852,7 @@ 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 for STA. Our AP does not - * support this. + * Enables 40Mz wide channels in the 2.4G band for STA. *******************************************************************************/ #define SLSI_PSID_UNIFI24_G40_MHZ_CHANNELS 0x07F3 @@ -1188,6 +1213,19 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_AP_OLBC_INTERVAL 0x081D +/******************************************************************************* + * NAME : UnifiMlmednsSupportEnabled + * PSID : 2078 (0x081E) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * This MIB enables support for transmitting DNS frame via MLME. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_MLMEDNS_SUPPORT_ENABLED 0x081E + /******************************************************************************* * NAME : UnifiOffchannelScheduleTimeout * PSID : 2079 (0x081F) @@ -1218,19 +1256,18 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf #define SLSI_PSID_UNIFI_FRAME_RESPONSE_TIMEOUT 0x0820 /******************************************************************************* - * NAME : UnifiConnectionFailureTimeout + * NAME : UnifiConnectingFrameTimeout * PSID : 2081 (0x0821) * PER INTERFACE?: NO * TYPE : SlsiUint16 * UNITS : TU * MIN : 0 * MAX : 4000 - * DEFAULT : 1500 + * DEFAULT : 1000 * DESCRIPTION : - * How long the complete connection procedure has before the MLME times out - * and issues a Connect Indication (fail). + * For how long should a frame be retried before giving up. *******************************************************************************/ -#define SLSI_PSID_UNIFI_CONNECTION_FAILURE_TIMEOUT 0x0821 +#define SLSI_PSID_UNIFI_CONNECTING_FRAME_TIMEOUT 0x0821 /******************************************************************************* * NAME : UnifiConnectingProbeTimeout @@ -1320,8 +1357,8 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 65535 * DEFAULT : 2 * DESCRIPTION : - * Max number of Probe Request sets that the scan engine will send on a - * single channel. + * Part of Scan Algorithm: Max number of Probe Request sets that the scan + * engine will send on a single channel. *******************************************************************************/ #define SLSI_PSID_UNIFI_MLME_SCAN_MAX_NUMBER_OF_PROBE_SETS 0x0827 @@ -1388,7 +1425,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 65535 * DEFAULT : * DESCRIPTION : - * The tx rate that was used for transmissions prior disconnection; + * The tx rate that was used for transmissions prior disconnection *******************************************************************************/ #define SLSI_PSID_UNIFI_PEER_TX_DATA_RATE 0x0830 @@ -1602,12 +1639,13 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * 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) 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). + * priority (uint8) octet 1 - Scan Flags (uint8) bit 0 - Enable Early + * Channel Exit (bool) bit 1 - Disable Scan (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 @@ -1628,6 +1666,32 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_EXTERNAL_FAST_CLOCK_REQUEST_PIO 0x086E +/******************************************************************************* + * NAME : UnifiPeerRxRetryCount + * PSID : 2198 (0x0896) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * The number of retry packets from peer station + *******************************************************************************/ +#define SLSI_PSID_UNIFI_PEER_RX_RETRY_COUNT 0x0896 + +/******************************************************************************* + * NAME : UnifiPeerRxMulticastCount + * PSID : 2199 (0x0897) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * The number of multicast and broadcast packets received from peer station + *******************************************************************************/ +#define SLSI_PSID_UNIFI_PEER_RX_MULTICAST_COUNT 0x0897 + /******************************************************************************* * NAME : UnifiRssi * PSID : 2200 (0x0898) @@ -2941,6 +3005,70 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_LAA_GI_SPECULATION_INTERVAL_SLOT_MAX_NUM 0x0921 +/******************************************************************************* + * NAME : UnifiLaaTxDiversityBeamformEnabled + * PSID : 2350 (0x092E) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * For Link Adaptation Algorithm. It is used to enable or disable TX + * beamformer functionality. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LAA_TX_DIVERSITY_BEAMFORM_ENABLED 0x092E + +/******************************************************************************* + * NAME : UnifiLaaTxDiversityBeamformMinMcs + * PSID : 2351 (0x092F) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 2 + * DESCRIPTION : + * For Link Adaptation Algorithm. TX Beamform is applied when MCS is same or + * larger than this threshold value. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LAA_TX_DIVERSITY_BEAMFORM_MIN_MCS 0x092F + +/******************************************************************************* + * NAME : UnifiLaaTxDiversityFixMode + * PSID : 2352 (0x0930) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : + * DESCRIPTION : + * For Link Adaptation Algorithm. It is used to fix TX diversity mode. With + * two antennas available and only one spatial stream used, then one of the + * following modes can be selected: - 0 : Not fixed. Tx diversity mode is + * automatically selected by LAA. - 1 : CDD fixed mode - 2 : Beamforming + * fixed mode - 3 : STBC fixed mode + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LAA_TX_DIVERSITY_FIX_MODE 0x0930 + +/******************************************************************************* + * NAME : UnifiLaaProtectionConfigOverride + * PSID : 2356 (0x0934) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 6 + * DESCRIPTION : + * Overrides the default Protection configuration. Only valid flags are + * DPIF_PEER_INFO_PROTECTION_TXOP_AMPDU and + * DPIF_PEER_INFO_PROTECTION_ALLOWED. Default allows protection code to work + * out the rules based on VIF configuration. If + * DPIF_PEER_INFO_PROTECTION_ALLOWED is unset, all protection, for this vif, + * is disabled. If DPIF_PEER_INFO_PROTECTION_TXOP_AMPDU is unset then, for + * the specified vif, the first A-MPDU in the TxOp is no longer protected. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_LAA_PROTECTION_CONFIG_OVERRIDE 0x0934 + /******************************************************************************* * NAME : UnifiCsrOnlyEifsDuration * PSID : 2362 (0x093A) @@ -3347,6 +3475,51 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #define SLSI_PSID_UNIFI_AP_SCAN_ABSENCE_PERIOD 0x09B1 +/******************************************************************************* + * NAME : UnifiMlmestaKeepAliveTimeoutCheck + * PSID : 2485 (0x09B5) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * UNITS : second + * MIN : 0 + * MAX : 100 + * DEFAULT : 5 + * DESCRIPTION : + * DO NOT SET TO A VALUE HIGHER THAN THE TIMEOUT!!! How long before + * keepalive timeout to start polling. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_MLMESTA_KEEP_ALIVE_TIMEOUT_CHECK 0x09B5 + +/******************************************************************************* + * NAME : UnifiMlmeapKeepAliveTimeoutCheck + * PSID : 2486 (0x09B6) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * UNITS : second + * MIN : 0 + * MAX : 100 + * DEFAULT : 5 + * DESCRIPTION : + * DO NOT SET TO A VALUE HIGHER THAN THE TIMEOUT!!! How long before + * keepalive timeout to start polling. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_MLMEAP_KEEP_ALIVE_TIMEOUT_CHECK 0x09B6 + +/******************************************************************************* + * NAME : UnifiMlmegoKeepAliveTimeoutCheck + * PSID : 2487 (0x09B7) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * UNITS : second + * MIN : 0 + * MAX : 100 + * DEFAULT : 5 + * DESCRIPTION : + * DO NOT SET TO A VALUE HIGHER THAN THE TIMEOUT!!! How long before + * keepalive timeout to start polling. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_MLMEGO_KEEP_ALIVE_TIMEOUT_CHECK 0x09B7 + /******************************************************************************* * NAME : UnifiFastPowerSaveTimeout * PSID : 2500 (0x09C4) @@ -3929,7 +4102,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 - * MAX : 65535 + * MAX : 255 * DEFAULT : 5 * DESCRIPTION : * Number of retries of probe response frame. @@ -4757,7 +4930,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint32 * MIN : 0 * MAX : 4294967295 - * DEFAULT : 100 + * DEFAULT : 5000 * DESCRIPTION : * Lower threshold for total number of frames received in the system which * is considered as low load @@ -4771,7 +4944,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint32 * MIN : 0 * MAX : 4294967295 - * DEFAULT : 1000 + * DEFAULT : 10000 * DESCRIPTION : * Upper threshold for total number of frames received in the system which * is considered as high load @@ -5166,12 +5339,25 @@ 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 : * Mac Address Randomisation should be applied for Probe Requests. *******************************************************************************/ #define SLSI_PSID_UNIFI_MAC_ADDRESS_RANDOMISATION_ACTIVATED 0x13B4 -/* TDB: Auto generate to add this */ + +/******************************************************************************* + * NAME : UnifiMacAddressRandomisationMask + * PSID : 5047 (0x13B7) + * PER INTERFACE?: NO + * TYPE : SlsiUint8 + * MIN : 6 + * MAX : 6 + * DEFAULT : { 0X00, 0X00, 0X00, 0X00, 0X00, 0X00 } + * DESCRIPTION : + * FW randomises MAC Address bits that have a corresponding bit set to 0 in + * the MAC Mask for Probe Requests. This excludes U/L and I/G bits which + * will be set to Local and Individual respectively. + *******************************************************************************/ #define SLSI_PSID_UNIFI_MAC_ADDRESS_RANDOMISATION_MASK 0x13B7 /******************************************************************************* @@ -5663,10 +5849,10 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * NAME : UnifiCcaMasterSwitch * PSID : 5102 (0x13EE) * PER INTERFACE?: NO - * TYPE : SlsiUint16 + * TYPE : SlsiUint32 * MIN : 0 - * MAX : 65535 - * DEFAULT : + * MAX : 4294967295 + * DEFAULT : 0X00540050 * DESCRIPTION : * Enables CCA *******************************************************************************/ @@ -5756,11 +5942,10 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 - * MAX : 65535 + * MAX : 255 * DEFAULT : 5 * DESCRIPTION : - * Indicates the default minimum time between consecutive FTM frames in - * units of 100 us + * Default minimum time between consecutive FTM frames in units of 100 us. *******************************************************************************/ #define SLSI_PSID_UNIFI_MIN_DELTA_FTM 0x14B5 @@ -5769,12 +5954,11 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * PSID : 5302 (0x14B6) * PER INTERFACE?: NO * TYPE : SlsiUint16 - * MIN : 0 - * MAX : 65535 + * MIN : 1 + * MAX : 31 * DEFAULT : 4 * DESCRIPTION : - * indicates how many successfully transmitted FTM frames are requested per - * burst instance + * Requested FTM frames per burst. *******************************************************************************/ #define SLSI_PSID_UNIFI_FTM_PER_BURST 0x14B6 @@ -5783,13 +5967,13 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * PSID : 5303 (0x14B7) * PER INTERFACE?: NO * TYPE : SlsiUint16 - * MIN : 0 - * MAX : 65535 + * MIN : 2 + * MAX : 11 * DEFAULT : 6 * DESCRIPTION : * 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" + * 15 means "no preference". *******************************************************************************/ #define SLSI_PSID_UNIFI_FTM_BURST_DURATION 0x14B7 @@ -5799,11 +5983,11 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * PER INTERFACE?: NO * TYPE : SlsiUint16 * MIN : 0 - * MAX : 65535 + * MAX : 14 * DEFAULT : * DESCRIPTION : - * the number of burst instances is 2^(Number of Bursts Exponent), value 15 - * means "no preference" + * The number of burst instances is 2^(Number of Bursts Exponent), value 15 + * means "no preference". *******************************************************************************/ #define SLSI_PSID_UNIFI_NUM_OF_BURSTS_EXPONENT 0x14B8 @@ -5814,12 +5998,184 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiBool * MIN : 0 * MAX : 1 - * DEFAULT : 1 + * DEFAULT : TRUE * DESCRIPTION : * Enable support for ASAP mode in FTM *******************************************************************************/ #define SLSI_PSID_UNIFI_ASAP_MODE_ENABLED 0x14B9 +/******************************************************************************* + * NAME : UnifiFtmResponderEnabled + * PSID : 5306 (0x14BA) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * Enable support for FTM Responder + *******************************************************************************/ +#define SLSI_PSID_UNIFI_FTM_RESPONDER_ENABLED 0x14BA + +/******************************************************************************* + * NAME : UnifiFtmDefaultSessionEstablishmentTimeout + * PSID : 5307 (0x14BB) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 10 + * MAX : 100 + * DEFAULT : 50 + * DESCRIPTION : + * Default timeout for session estabishmant in units of ms. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_FTM_DEFAULT_SESSION_ESTABLISHMENT_TIMEOUT 0x14BB + +/******************************************************************************* + * NAME : UnifiFtmDefaultGapBeforeFirstBurstPerResponder + * PSID : 5308 (0x14BC) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 10 + * MAX : 100 + * DEFAULT : 50 + * DESCRIPTION : + * Used to calculate Responder burst start times. In units of ms. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_FTM_DEFAULT_GAP_BEFORE_FIRST_BURST_PER_RESPONDER 0x14BC + +/******************************************************************************* + * NAME : UnifiFtmDefaultGapBetweenBursts + * PSID : 5309 (0x14BD) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 5 + * MAX : 50 + * DEFAULT : 10 + * DESCRIPTION : + * Used to calculate Responder burst start times. In units of ms. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_FTM_DEFAULT_GAP_BETWEEN_BURSTS 0x14BD + +/******************************************************************************* + * NAME : UnifiFtmDefaultTriggerDelay + * PSID : 5401 (0x1519) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 100 + * DEFAULT : 1 + * DESCRIPTION : + * Delay to account for differences in time between Iniator and Responder. + * In units of ms. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_FTM_DEFAULT_TRIGGER_DELAY 0x1519 + +/******************************************************************************* + * NAME : UnifiFtmDefaultEndBurstDelay + * PSID : 5402 (0x151A) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 100 + * DEFAULT : 10 + * DESCRIPTION : + * Delay to account for differences in time between Iniator and Responder. + * In units of ms. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_FTM_DEFAULT_END_BURST_DELAY 0x151A + +/******************************************************************************* + * NAME : UnifiFtmRequestValidationEnabled + * PSID : 5403 (0x151B) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * Enable Validation for FTM Add Range request RTT_Configs + *******************************************************************************/ +#define SLSI_PSID_UNIFI_FTM_REQUEST_VALIDATION_ENABLED 0x151B + +/******************************************************************************* + * NAME : UnifiFtmResponseValidationEnabled + * PSID : 5404 (0x151C) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * Enable Validation for FTM Response + *******************************************************************************/ +#define SLSI_PSID_UNIFI_FTM_RESPONSE_VALIDATION_ENABLED 0x151C + +/******************************************************************************* + * NAME : UnifiFtmUseResponseParameters + * PSID : 5405 (0x151D) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : FALSE + * DESCRIPTION : + * Use Response burst parameters for burst + *******************************************************************************/ +#define SLSI_PSID_UNIFI_FTM_USE_RESPONSE_PARAMETERS 0x151D + +/******************************************************************************* + * NAME : UnifiMlmeScanContinueIfMoreThanXAps + * PSID : 5410 (0x1522) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 10 + * DESCRIPTION : + * Part of Scan Algorithm: Keep scanning on a channel with lots of APs. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_MLME_SCAN_CONTINUE_IF_MORE_THAN_XAPS 0x1522 + +/******************************************************************************* + * NAME : UnifiMlmeScanStopIfLessThanXNewAps + * PSID : 5411 (0x1523) + * PER INTERFACE?: NO + * TYPE : SlsiUint16 + * MIN : 0 + * MAX : 65535 + * DEFAULT : 4 + * DESCRIPTION : + * Part of Scan Algorithm: Stop scanning on a channel if less than X NEW APs + * are seen. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_MLME_SCAN_STOP_IF_LESS_THAN_XNEW_APS 0x1523 + +/******************************************************************************* + * NAME : UnifiMlmeScanMultiVifEnabled + * PSID : 5412 (0x1524) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : 1 + * DESCRIPTION : + * Part of Scan Algorithm: Enable support for Multi Vif channel times. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_MLME_SCAN_MULTI_VIF_ENABLED 0x1524 + +/******************************************************************************* + * NAME : UnifiMlmeScanNewAlgorithmEnabled + * PSID : 5413 (0x1525) + * PER INTERFACE?: NO + * TYPE : SlsiBool + * MIN : 0 + * MAX : 1 + * DEFAULT : 1 + * DESCRIPTION : + * Part of Scan Algorithm: Enable support for the new algorithm. + *******************************************************************************/ +#define SLSI_PSID_UNIFI_MLME_SCAN_NEW_ALGORITHM_ENABLED 0x1525 + /******************************************************************************* * NAME : UnifiTpcMinPower2Gmimo * PSID : 6011 (0x177B) @@ -5931,7 +6287,8 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * MAX : 32767 * DEFAULT : 127 * DESCRIPTION : - * Maximum User Set Tx Power (quarter dBm). For Test only. + * Maximum User Set Tx Power (quarter dBm). For Test only. Enable it in + * unifiTestTxPowerEnable. *******************************************************************************/ #define SLSI_PSID_UNIFI_USER_SET_TXPOWER_LEVEL 0x1785 @@ -6063,7 +6420,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint16 * MIN : 0 * MAX : 65535 - * DEFAULT : 0XFFFF + * DEFAULT : 0X03DD * DESCRIPTION : * Bitfield to enable Control Plane Tx Power processing. MLME/Macrame use * only. @@ -6753,7 +7110,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * TYPE : SlsiUint8 * MIN : 0 * MAX : 20 - * DEFAULT : {0X01,0X0E,0X24,0X04,0X34,0X04,0X64,0X0C,0X95,0X05} + * DEFAULT : {0X01,0X0D,0X24,0X04,0X34,0X04,0X64,0X0C,0X95,0X05} * DESCRIPTION : * Supported 20MHz channel centre frequency grouped in sub-bands. For each * sub-band: starting channel number, followed by number of channels @@ -6779,7 +7136,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * PER INTERFACE?: NO * TYPE : SlsiUint8 * MIN : 2 - * MAX : 250 + * MAX : 270 * DEFAULT : (Too Large to display) * DESCRIPTION : * Defines the ordered list of countries present in unifiRegulatoryTable. diff --git a/drivers/net/wireless/scsc/mlme.c b/drivers/net/wireless/scsc/mlme.c index 127ce2e6a187..4d8d3a793737 100755 --- a/drivers/net/wireless/scsc/mlme.c +++ b/drivers/net/wireless/scsc/mlme.c @@ -715,7 +715,8 @@ int slsi_mlme_set_ipv6_address(struct slsi_dev *sdev, struct net_device *dev) return -EIO; if (fapi_get_u16(cfm, u.mlme_set_ip_address_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_set_ip_address_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_set_ip_address_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_set_ip_address_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_set_ip_address_cfm.result_code)); r = -EINVAL; } slsi_kfree_skb(cfm); @@ -840,7 +841,8 @@ int slsi_mlme_add_vif(struct slsi_dev *sdev, struct net_device *dev, u8 *interfa return -EIO; if (fapi_get_u16(cfm, u.mlme_add_vif_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_add_vif_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_add_vif_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_add_vif_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_add_vif_cfm.result_code)); r = -EINVAL; } @@ -874,7 +876,8 @@ void slsi_mlme_del_vif(struct slsi_dev *sdev, struct net_device *dev) return; if (fapi_get_u16(cfm, u.mlme_del_vif_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) - SLSI_NET_ERR(dev, "mlme_del_vif_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_del_vif_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_del_vif_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_del_vif_cfm.result_code)); if (((ndev_vif->iftype == NL80211_IFTYPE_P2P_CLIENT) || (ndev_vif->iftype == NL80211_IFTYPE_STATION)) && (ndev_vif->delete_probe_req_ies)) { @@ -919,7 +922,8 @@ int slsi_mlme_set_channel(struct slsi_dev *sdev, struct net_device *dev, struct return -EIO; if (fapi_get_u16(cfm, u.mlme_set_channel_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_set_channel_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_set_channel_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_set_channel_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_set_channel_cfm.result_code)); r = -EINVAL; } @@ -947,7 +951,7 @@ int slsi_mlme_spare_signal_1(struct slsi_dev *sdev, struct net_device *dev) return -EIO; if (fapi_get_u16(cfm, u.mlme_set_channel_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_spare_channel_cfm(result:%u) ERROR\n", + SLSI_NET_ERR(dev, "mlme_spare_channel_cfm(result:0x%04x) ERROR\n", fapi_get_u16(cfm, u.mlme_set_channel_cfm.result_code)); r = -EINVAL; } @@ -999,7 +1003,8 @@ static bool slsi_scan_cfm_validate(struct slsi_dev *sdev, struct net_device *dev bool r = true; if (fapi_get_u16(cfm, u.mlme_add_scan_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_ERR_NODEV("mlme_add_scan_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_add_scan_cfm.result_code)); + SLSI_ERR_NODEV("mlme_add_scan_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_add_scan_cfm.result_code)); r = false; } @@ -1073,7 +1078,7 @@ int slsi_mlme_set_bssid_hotlist_req(struct slsi_dev *sdev, struct net_device *de SLSI_DBG2(sdev, SLSI_GSCAN, "mlme_set_bssid_hotlist_cfm(datalen:%u)\n", fapi_get_datalen(cfm)); if (fapi_get_u16(cfm, u.mlme_set_bssid_hotlist_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_set_bssid_hotlist_cfm(result: %#x) ERROR\n", + SLSI_NET_ERR(dev, "mlme_set_bssid_hotlist_cfm(result:0x%04x) ERROR\n", fapi_get_u16(cfm, u.mlme_set_bssid_hotlist_cfm.result_code)); slsi_kfree_skb(cfm); return -EINVAL; @@ -1380,7 +1385,8 @@ int slsi_mlme_add_sched_scan(struct slsi_dev *sdev, return -EIO; if (fapi_get_u16(rx, u.mlme_add_scan_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_add_scan_cfm(result:%u) ERROR\n", fapi_get_u16(rx, u.mlme_add_scan_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_add_scan_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(rx, u.mlme_add_scan_cfm.result_code)); r = -EINVAL; } @@ -1513,7 +1519,8 @@ int slsi_mlme_add_scan( if (!rx) return -EIO; if (fapi_get_u16(rx, u.mlme_add_scan_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_add_scan_cfm(result:%u) ERROR\n", fapi_get_u16(rx, u.mlme_add_scan_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_add_scan_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(rx, u.mlme_add_scan_cfm.result_code)); r = -EINVAL; } } @@ -1549,7 +1556,8 @@ int slsi_mlme_del_scan(struct slsi_dev *sdev, struct net_device *dev, u16 scan_i return -EIO; if (fapi_get_u16(cfm, u.mlme_del_scan_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_del_scan_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_del_scan_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_del_scan_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_del_scan_cfm.result_code)); r = -EINVAL; } @@ -1947,7 +1955,8 @@ int slsi_mlme_start(struct slsi_dev *sdev, struct net_device *dev, u8 *bssid, st if (!cfm) return -EIO; if (fapi_get_u16(cfm, u.mlme_start_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_start_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_start_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_start_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_start_cfm.result_code)); r = -EINVAL; } @@ -2116,7 +2125,8 @@ static int slsi_mlme_connect_info_elements(struct slsi_dev *sdev, struct net_dev return -EIO; if (fapi_get_u16(cfm, u.mlme_add_info_elements_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_add_info_elements_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_connect_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_add_info_elements_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_connect_cfm.result_code)); r = -EINVAL; } @@ -2238,7 +2248,8 @@ int slsi_mlme_connect(struct slsi_dev *sdev, struct net_device *dev, struct cfg8 return -EIO; if (fapi_get_u16(cfm, u.mlme_connect_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_connect_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_connect_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_connect_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_connect_cfm.result_code)); r = -EINVAL; } @@ -2322,7 +2333,8 @@ bool slsi_disconnect_cfm_validate(struct slsi_dev *sdev, struct net_device *dev, r = true; /* Not present code would mean peer is already disconnected and hence no ind (could be race scenario), don't log as error */ else if (result != FAPI_RESULTCODE_NOT_PRESENT) - SLSI_NET_ERR(dev, "mlme_disconnect_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_disconnect_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_disconnect_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_disconnect_cfm.result_code)); exit: slsi_kfree_skb(cfm); @@ -2365,7 +2377,8 @@ int slsi_mlme_disconnect(struct slsi_dev *sdev, struct net_device *dev, u8 *mac, rx = slsi_mlme_req_cfm(sdev, dev, req, MLME_DISCONNECT_CFM); if (rx) { if (fapi_get_u16(rx, u.mlme_disconnect_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_disconnect_cfm(result:%u) ERROR\n", fapi_get_u16(rx, u.mlme_disconnect_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_disconnect_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(rx, u.mlme_disconnect_cfm.result_code)); r = -EINVAL; } } else { @@ -2438,7 +2451,8 @@ int slsi_mlme_set_key(struct slsi_dev *sdev, struct net_device *dev, u16 key_id, return -EIO; if (fapi_get_u16(cfm, u.mlme_setkeys_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_setkeys_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_setkeys_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_setkeys_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_setkeys_cfm.result_code)); r = -EINVAL; } slsi_kfree_skb(cfm); @@ -2466,7 +2480,8 @@ int slsi_mlme_get_key(struct slsi_dev *sdev, struct net_device *dev, u16 key_id, return -EIO; if (fapi_get_u16(cfm, u.mlme_get_key_sequence_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_get_key_sequence_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_get_key_sequence_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_get_key_sequence_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_get_key_sequence_cfm.result_code)); r = -ENOENT; } else { int i; @@ -2596,11 +2611,10 @@ 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 } }, + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 3, 0 } }, /* bad_fcs_count*/ + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 10, 0 } }, /* mpdus_failed_transmit*/ + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 25, 0 } }, /* mac_bad_sig_count*/ + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 30, 0 } }, /* rx_error_count*/ }; int tx_counter = 0; int rx_counter = 0; @@ -2679,27 +2693,29 @@ int slsi_mlme_get_sinfo_mib(struct slsi_dev *sdev, struct net_device *dev, 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*/ + tx_counter += values[3].u.uintValue; /*mpdus_failed_transmit*/ 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*/ + rx_counter += values[4].u.uintValue; /*mac_bad_sig_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*/ + rx_counter += values[5].u.uintValue; /*rx_error_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; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) + peer->sinfo.filled |= BIT(NL80211_STA_INFO_TX_FAILED) | BIT(NL80211_STA_INFO_RX_DROP_MISC) | + BIT(NL80211_STA_INFO_TX_PACKETS); +#endif } else { - SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_get_req failed(result:%u)\n", r); + SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_get_req failed(result:0x%4x)\n", r); } kfree(mibrsp.data); @@ -2847,7 +2863,8 @@ int slsi_mlme_powermgt_unlocked(struct slsi_dev *sdev, struct net_device *dev, u if (fapi_get_u16(rx, u.mlme_powermgt_cfm.result_code) == FAPI_RESULTCODE_SUCCESS) { ndev_vif->power_mode = power_mode; } else { - SLSI_NET_ERR(dev, "mlme_powermgt_cfm(result:%u) ERROR\n", fapi_get_u16(rx, u.mlme_powermgt_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_powermgt_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(rx, u.mlme_powermgt_cfm.result_code)); r = -EINVAL; } @@ -2887,7 +2904,8 @@ int slsi_mlme_register_action_frame(struct slsi_dev *sdev, struct net_device *de return -EIO; if (fapi_get_u16(cfm, u.mlme_register_action_frame_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_register_action_frame_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_register_action_frame_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_register_action_frame_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_register_action_frame_cfm.result_code)); r = -EINVAL; } @@ -2917,7 +2935,8 @@ int slsi_mlme_channel_switch(struct slsi_dev *sdev, struct net_device *dev, u16 return -EIO; if (fapi_get_u16(cfm, u.mlme_channel_switch_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_channel_switch_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_channel_switch_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_channel_switch_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_channel_switch_cfm.result_code)); r = -EINVAL; } @@ -2955,7 +2974,8 @@ int slsi_mlme_add_info_elements(struct slsi_dev *sdev, struct net_device *dev, return -EIO; if (fapi_get_u16(cfm, u.mlme_add_info_elements_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_add_info_elements_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_add_info_elements_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_add_info_elements_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_add_info_elements_cfm.result_code)); r = -EINVAL; } @@ -3088,7 +3108,8 @@ int slsi_mlme_send_frame_mgmt(struct slsi_dev *sdev, struct net_device *dev, con return -EIO; if (fapi_get_u16(cfm, u.mlme_send_frame_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_send_frame_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_send_frame_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_send_frame_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_send_frame_cfm.result_code)); r = -EINVAL; } @@ -3117,7 +3138,8 @@ int slsi_mlme_reset_dwell_time(struct slsi_dev *sdev, struct net_device *dev) return -EIO; if (fapi_get_u16(cfm, u.mlme_reset_dwell_time_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_reset_dwell_time_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_reset_dwell_time_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_reset_dwell_time_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_reset_dwell_time_cfm.result_code)); r = -EINVAL; } @@ -3205,7 +3227,8 @@ int slsi_mlme_set_pmk(struct slsi_dev *sdev, struct net_device *dev, const u8 *p return -EIO; if (fapi_get_u16(cfm, u.mlme_set_pmk_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_set_pmk_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_set_pmk_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_set_pmk_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_set_pmk_cfm.result_code)); r = -EINVAL; } slsi_kfree_skb(cfm); @@ -3234,7 +3257,8 @@ int slsi_mlme_roam(struct slsi_dev *sdev, struct net_device *dev, const u8 *bssi if (!cfm) return -EIO; if (fapi_get_u16(cfm, u.mlme_roam_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_roam_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_roam_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_roam_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_roam_cfm.result_code)); r = -EINVAL; } slsi_kfree_skb(cfm); @@ -3305,7 +3329,8 @@ int slsi_mlme_set_cached_channels(struct slsi_dev *sdev, struct net_device *dev, return -EIO; if (fapi_get_u16(cfm, u.mlme_set_cached_channels_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_set_cached_channels_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_set_cached_channels_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_set_cached_channels_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_set_cached_channels_cfm.result_code)); r = -EINVAL; } @@ -3343,7 +3368,8 @@ int slsi_mlme_set_acl(struct slsi_dev *sdev, struct net_device *dev, u16 ifnum, return -EIO; if (fapi_get_u16(cfm, u.mlme_set_acl_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_set_acl_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_set_acl_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_set_acl_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_set_acl_cfm.result_code)); r = -EINVAL; } @@ -3386,7 +3412,8 @@ int slsi_mlme_set_traffic_parameters(struct slsi_dev *sdev, struct net_device *d return -EIO; if (fapi_get_u16(rx, u.mlme_set_traffic_parameters_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_set_traffic_parameters_cfm(result:%u) ERROR\n", fapi_get_u16(rx, u.mlme_set_traffic_parameters_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_set_traffic_parameters_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(rx, u.mlme_set_traffic_parameters_cfm.result_code)); r = -EINVAL; } @@ -3420,7 +3447,8 @@ int slsi_mlme_del_traffic_parameters(struct slsi_dev *sdev, struct net_device *d return -EIO; if (fapi_get_u16(rx, u.mlme_del_traffic_parameters_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_del_traffic_parameters_cfm(result:%u) ERROR\n", fapi_get_u16(rx, u.mlme_del_traffic_parameters_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_del_traffic_parameters_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(rx, u.mlme_del_traffic_parameters_cfm.result_code)); r = -EINVAL; } @@ -3580,7 +3608,8 @@ int slsi_mlme_tdls_action(struct slsi_dev *sdev, struct net_device *dev, const u return -EIO; if (fapi_get_u16(cfm, u.mlme_tdls_action_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_tdls_action_cfm(result:%u) ERROR\n", fapi_get_u16(cfm, u.mlme_tdls_action_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_tdls_action_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_tdls_action_cfm.result_code)); r = -EINVAL; } @@ -3610,9 +3639,11 @@ int slsi_mlme_reassociate(struct slsi_dev *sdev, struct net_device *dev) return -EIO; if (fapi_get_u16(cfm, u.mlme_reassociate_cfm.result_code) == FAPI_RESULTCODE_HOST_REQUEST_SUCCESS) { - SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_reassoc_cfm(result:0x%4x)\n", fapi_get_u16(cfm, u.mlme_reassociate_cfm.result_code)); + SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_reassoc_cfm(result:0x%04x)\n", + fapi_get_u16(cfm, u.mlme_reassociate_cfm.result_code)); } else { - SLSI_NET_ERR(dev, "mlme_reassoc_cfm(result:0x%4x) ERROR\n", fapi_get_u16(cfm, u.mlme_reassociate_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_reassoc_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.mlme_reassociate_cfm.result_code)); r = -EINVAL; } slsi_kfree_skb(cfm); @@ -3768,7 +3799,7 @@ int slsi_mlme_significant_change_set(struct slsi_dev *sdev, struct net_device *d return -EIO; } else if (fapi_get_u16(rx, u.mlme_add_scan_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { gscan->bucket[0]->for_change_tracking = false; - SLSI_NET_ERR(dev, "mlme_add_scan_cfm(ERROR:%u)", fapi_get_u16(rx, u.mlme_add_scan_cfm.result_code)); + SLSI_NET_ERR(dev, "mlme_add_scan_cfm(ERROR:0x%04x)", fapi_get_u16(rx, u.mlme_add_scan_cfm.result_code)); r = -EINVAL; } else { gscan->bucket[0]->for_change_tracking = true; @@ -3820,7 +3851,7 @@ int slsi_mlme_add_range_req(struct slsi_dev *sdev, u8 count, 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)", + SLSI_ERR(sdev, "mlme_add_range_cfm(ERROR:0x%04x)", fapi_get_u16(rx, u.mlme_add_range_cfm.result_code)); r = -EINVAL; } @@ -3842,7 +3873,7 @@ bool slsi_del_range_cfm_validate(struct slsi_dev *sdev, struct net_device *dev, if (result == FAPI_RESULTCODE_SUCCESS) r = true; else - SLSI_NET_ERR(dev, "mlme_del_range_cfm(result:%u) ERROR\n", result); + SLSI_NET_ERR(dev, "mlme_del_range_cfm(result:0x%04x) ERROR\n", result); exit: slsi_kfree_skb(cfm); @@ -3991,7 +4022,7 @@ int slsi_mlme_set_pno_list(struct slsi_dev *sdev, int count, if (!rx) return -EIO; if (fapi_get_u16(rx, u.mlme_set_pno_list_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_ERR(sdev, "mlme_set_pno_list_cfm(ERROR:%u)", + SLSI_ERR(sdev, "mlme_set_pno_list_cfm(ERROR:0x%04x)", fapi_get_u16(rx, u.mlme_set_pno_list_cfm.result_code)); r = -EINVAL; } @@ -4022,7 +4053,7 @@ int slsi_mlme_start_link_stats_req(struct slsi_dev *sdev, u16 mpdu_size_threshol return -EIO; if (fapi_get_u16(cfm, u.mlme_start_link_statistics_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_ERR(sdev, "mlme_start_link_statistics_cfm (result: %u) ERROR\n", + SLSI_ERR(sdev, "mlme_start_link_statistics_cfm (result:0x%04x) ERROR\n", fapi_get_u16(cfm, u.mlme_start_link_statistics_cfm.result_code)); r = -EINVAL; } @@ -4051,7 +4082,7 @@ int slsi_mlme_stop_link_stats_req(struct slsi_dev *sdev, u16 stats_stop_mask) return -EIO; if (fapi_get_u16(cfm, u.mlme_stop_link_statistics_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_ERR(sdev, "mlme_stop_link_statistics_cfm (result: %u) ERROR\n", + SLSI_ERR(sdev, "mlme_stop_link_statistics_cfm (result:0x%04x) ERROR\n", fapi_get_u16(cfm, u.mlme_stop_link_statistics_cfm.result_code)); r = -EINVAL; } @@ -4144,7 +4175,7 @@ int slsi_mlme_set_ctwindow(struct slsi_dev *sdev, struct net_device *dev, unsign return -EIO; if (fapi_get_u16(cfm, u.mlme_set_ctwindow_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_set_ctwindow_cfm(result:%u) ERROR\n", + SLSI_NET_ERR(dev, "mlme_set_ctwindow_cfm(result:0x%04x) ERROR\n", fapi_get_u16(cfm, u.mlme_set_ctwindow_cfm.result_code)); r = -EINVAL; } @@ -4182,7 +4213,7 @@ int slsi_mlme_set_p2p_noa(struct slsi_dev *sdev, struct net_device *dev, unsigne return -EIO; if (fapi_get_u16(cfm, u.mlme_set_noa_cfm.result_code) != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "mlme_set_noa_cfm(result:%u) ERROR\n", + SLSI_NET_ERR(dev, "mlme_set_noa_cfm(result:0x%04x) ERROR\n", fapi_get_u16(cfm, u.mlme_set_noa_cfm.result_code)); r = -EINVAL; } @@ -4852,7 +4883,8 @@ int slsi_test_sap_configure_monitor_mode(struct slsi_dev *sdev, struct net_devic } 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)); + SLSI_NET_ERR(dev, "test_configure_monitor_mode_cfm(result:0x%04x) ERROR\n", + fapi_get_u16(cfm, u.test_configure_monitor_mode_cfm.result_code)); r = -EINVAL; } diff --git a/drivers/net/wireless/scsc/netif.c b/drivers/net/wireless/scsc/netif.c index 9bb0f622ff30..2dfcc8b653c1 100755 --- a/drivers/net/wireless/scsc/netif.c +++ b/drivers/net/wireless/scsc/netif.c @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ @@ -1176,9 +1176,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); + mutex_lock(&sdev->netdev_remove_mutex); free_netdev(dev); - SLSI_MUTEX_UNLOCK(sdev->netdev_remove_mutex); + mutex_unlock(&sdev->netdev_remove_mutex); return ret; } @@ -1189,11 +1189,17 @@ int slsi_netif_dynamic_iface_add(struct slsi_dev *sdev, const char *name) SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex); +#if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000) if (sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN] == sdev->netdev_ap) { rcu_assign_pointer(sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN], NULL); err = slsi_netif_add_locked(sdev, name, SLSI_NET_INDEX_P2PX_SWLAN); index = err ? err : SLSI_NET_INDEX_P2PX_SWLAN; } +#else + err = slsi_netif_add_locked(sdev, name, SLSI_NET_INDEX_P2PX_SWLAN); + index = err ? err : SLSI_NET_INDEX_P2PX_SWLAN; +#endif + SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex); return index; } @@ -1222,7 +1228,7 @@ int slsi_netif_init(struct slsi_dev *sdev) SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex); return -EINVAL; } - +#if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000) if (slsi_netif_add_locked(sdev, CONFIG_SCSC_AP_INTERFACE_NAME, SLSI_NET_INDEX_P2PX_SWLAN) != 0) { rtnl_lock(); slsi_netif_remove_locked(sdev, sdev->netdev[SLSI_NET_INDEX_WLAN]); @@ -1231,12 +1237,15 @@ int slsi_netif_init(struct slsi_dev *sdev) SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex); return -EINVAL; } +#endif #if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4 if (slsi_netif_add_locked(sdev, "nan%d", SLSI_NET_INDEX_NAN) != 0) { rtnl_lock(); slsi_netif_remove_locked(sdev, sdev->netdev[SLSI_NET_INDEX_WLAN]); slsi_netif_remove_locked(sdev, sdev->netdev[SLSI_NET_INDEX_P2P]); +#if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000) slsi_netif_remove_locked(sdev, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]); +#endif rtnl_unlock(); SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex); return -EINVAL; @@ -1343,9 +1352,9 @@ void slsi_netif_remove_locked(struct slsi_dev *sdev, struct net_device *dev) atomic_set(&ndev_vif->is_registered, 0); unregister_netdevice(dev); } else { - SLSI_MUTEX_LOCK(sdev->netdev_remove_mutex); + mutex_lock(&sdev->netdev_remove_mutex); free_netdev(dev); - SLSI_MUTEX_UNLOCK(sdev->netdev_remove_mutex); + mutex_unlock(&sdev->netdev_remove_mutex); } } diff --git a/drivers/net/wireless/scsc/nl80211_vendor.c b/drivers/net/wireless/scsc/nl80211_vendor.c index 50679c5ed3df..869c98832967 100755 --- a/drivers/net/wireless/scsc/nl80211_vendor.c +++ b/drivers/net/wireless/scsc/nl80211_vendor.c @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ #include @@ -17,16 +17,28 @@ #include "mib.h" #include "nl80211_vendor.h" -#ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING #include "scsc_wifilogger.h" #include "scsc_wifilogger_rings.h" #include "scsc_wifilogger_types.h" -#endif #define SLSI_GSCAN_INVALID_RSSI 0x7FFF #define SLSI_EPNO_AUTH_FIELD_WEP_OPEN 1 #define SLSI_EPNO_AUTH_FIELD_WPA_PSK 2 #define SLSI_EPNO_AUTH_FIELD_WPA_EAP 4 +#define WIFI_EVENT_FW_BTM_FRAME_REQUEST 56 // Request for a BTM frame is received +#define WIFI_EVENT_FW_BTM_FRAME_RESPONSE 57 // A BTM frame is transmitted. + +#define WIFI_TAG_VD_CHANNEL_UTILISATION 0xf01a +#define WIFI_TAG_VD_ROAMING_REASON 0xf019 +#define WIFI_TAG_VD_BTM_REQUEST_MODE 0xf01b +#define WIFI_TAG_VD_BTM_RESPONSE_STATUS 0xf01c +#define WIFI_TAG_VD_RETRY_COUNT 0xf00f +#define WIFI_ROAMING_SEARCH_REASON_RESERVED 0 +#define WIFI_ROAMING_SEARCH_REASON_LOW_RSSI 1 +#define WIFI_ROAMING_SEARCH_REASON_LINK_LOSS 2 +#define WIFI_ROAMING_SEARCH_REASON_BTM_REQ 3 +#define WIFI_ROAMING_SEARCH_REASON_CU_TRIGGER 4 + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING @@ -2989,6 +3001,7 @@ static int slsi_get_feature_set(struct wiphy *wiphy, feature_set |= SLSI_WIFI_HAL_FEATURE_RSSI_MONITOR; feature_set |= SLSI_WIFI_HAL_FEATURE_CONTROL_ROAMING; + feature_set |= SLSI_WIFI_HAL_FEATURE_TDLS | SLSI_WIFI_HAL_FEATURE_TDLS_OFFCHANNEL; #ifndef CONFIG_SCSC_WLAN_NAT_KEEPALIVE_DISABLE feature_set |= SLSI_WIFI_HAL_FEATURE_MKEEP_ALIVE; #endif @@ -5307,6 +5320,136 @@ exit: return ret; } +char *slsi_get_roam_reason_str(int roam_reason) +{ + switch (roam_reason) { + case WIFI_ROAMING_SEARCH_REASON_RESERVED: + return "WIFI_ROAMING_SEARCH_REASON_RESERVED"; + case WIFI_ROAMING_SEARCH_REASON_LOW_RSSI: + return "WIFI_ROAMING_SEARCH_REASON_LOW_RSSI"; + case WIFI_ROAMING_SEARCH_REASON_LINK_LOSS: + return "WIFI_ROAMING_SEARCH_REASON_LINK_LOSS"; + case WIFI_ROAMING_SEARCH_REASON_BTM_REQ: + return "WIFI_ROAMING_SEARCH_REASON_BTM_REQ"; + case WIFI_ROAMING_SEARCH_REASON_CU_TRIGGER: + return "WIFI_ROAMING_SEARCH_REASON_CU_TRIGGER"; + default: + return "UNKNOWN_REASON"; + } +} + +void slsi_rx_event_log_indication(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb) +{ + u16 event_id = 0; + u64 timestamp = 0; + u8 *tlv_data; + u32 roam_reason, chan_utilisation, btm_request_mode, btm_response, eapol_msg_type; + u32 deauth_reason, eapol_retry_count, roam_rssi, eapol_result_code; + u16 vendor_len, tag_id, tag_len, vtag_id; + u32 tag_value, vtag_value, rssi_bits = 0; + int roam_rssi_val; + __le16 *le16_ptr = NULL; + int tlv_buffer__len = fapi_get_datalen(skb), i = 0; + + SLSI_MUTEX_LOCK(sdev->logger_mutex); + event_id = fapi_get_s16(skb, u.mlme_event_log_ind.event); + timestamp = fapi_get_u64(skb, u.mlme_event_log_ind.timestamp); + tlv_data = fapi_get_data(skb); + + SLSI_DBG3(sdev, SLSI_GSCAN, + "slsi_rx_event_log_indication, event id = %d, len = %d\n", event_id, tlv_buffer__len); + +#ifdef CONFIG_SCSC_WIFILOGGER + SCSC_WLOG_FW_EVENT(WLOG_NORMAL, event_id, timestamp, fapi_get_data(skb), fapi_get_datalen(skb)); +#endif + while (i + 4 < tlv_buffer__len) { + le16_ptr = (__le16 *)&tlv_data[i]; + tag_id = le16_to_cpu(*le16_ptr); + le16_ptr = (__le16 *)&tlv_data[i + 2]; + tag_len = le16_to_cpu(*le16_ptr); + i += 4; + if (i + tag_len > tlv_buffer__len) { + SLSI_INFO(sdev, "Incorrect fapi bulk data\n"); + slsi_kfree_skb(skb); + SLSI_MUTEX_UNLOCK(sdev->logger_mutex); + return; + } + tag_value = slsi_convert_tlv_data_to_value(&tlv_data[i], tag_len); + switch (tag_id) { + case WIFI_TAG_RSSI: + roam_rssi = tag_value; + while (roam_rssi) { + rssi_bits++; + roam_rssi >>= 1; + } + roam_rssi_val = ((1 << rssi_bits) - 1) ^ tag_value; + roam_rssi_val = -(roam_rssi_val + 1); + break; + case WIFI_TAG_REASON_CODE: + deauth_reason = tag_value; + break; + case WIFI_TAG_VENDOR_SPECIFIC: + vendor_len = tag_len - 2; + le16_ptr = (__le16 *)&tlv_data[i]; + vtag_id = le16_to_cpu(*le16_ptr); + vtag_value = slsi_convert_tlv_data_to_value(&tlv_data[i + 2], vendor_len); + switch (vtag_id) { + case WIFI_TAG_VD_CHANNEL_UTILISATION: + chan_utilisation = vtag_value; + break; + case WIFI_TAG_VD_ROAMING_REASON: + roam_reason = vtag_value; + break; + case WIFI_TAG_VD_BTM_REQUEST_MODE: + btm_request_mode = vtag_value; + break; + case WIFI_TAG_VD_BTM_RESPONSE_STATUS: + btm_response = vtag_value; + break; + case WIFI_TAG_VD_RETRY_COUNT: + eapol_retry_count = vtag_value; + break; + } + break; + case WIFI_TAG_EAPOL_MESSAGE_TYPE: + eapol_msg_type = tag_value; + break; + case WIFI_TAG_STATUS: + eapol_result_code = tag_value; + break; + } + i += tag_len; + } + switch (event_id) { + case WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START: + SLSI_INFO(sdev, "WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START, Send 4way-H/S, M%d\n", eapol_msg_type); + break; + case WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP: + SLSI_INFO(sdev, "WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP,Result Code:%d, Retry Count:%d\n", + eapol_result_code, eapol_retry_count); + break; + case WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED: + SLSI_INFO(sdev, "WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED, Received 4way-H/S, M%d\n", eapol_msg_type); + break; + case WIFI_EVENT_FW_BTM_FRAME_REQUEST: + SLSI_INFO(sdev, "WIFI_EVENT_FW_BTM_FRAME_REQUEST,Request Mode:%d\n", btm_request_mode); + break; + case WIFI_EVENT_FW_BTM_FRAME_RESPONSE: + SLSI_INFO(sdev, "WIFI_EVENT_FW_BTM_FRAME_RESPONSE:%s\n", btm_response ? "Success" : "Failure"); + break; + case WIFI_EVENT_ROAM_SEARCH_STARTED: + SLSI_INFO(sdev, "WIFI_EVENT_ROAM_SEARCH_STARTED, RSSI:%d, Deauth Reason:0x%04x, Channel Utilisation:%d," + "Roam Reason: %s\n", roam_rssi_val, deauth_reason, chan_utilisation, + slsi_get_roam_reason_str(roam_reason)); + break; + default: + SLSI_INFO(sdev, "Unknown Event_ID:%d\n", event_id); + } + + slsi_kfree_skb(skb); + SLSI_MUTEX_UNLOCK(sdev->logger_mutex); +} + #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) @@ -5868,23 +6011,6 @@ exit: return ret; } -void slsi_rx_event_log_indication(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb) -{ - u16 event_id = 0; - u64 timestamp = 0; - - SLSI_MUTEX_LOCK(sdev->logger_mutex); - event_id = fapi_get_s16(skb, u.mlme_event_log_ind.event); - 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); -} - static int slsi_start_pkt_fate_monitoring(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { int ret = 0; @@ -6192,7 +6318,7 @@ static int slsi_acs_init(struct wiphy *wiphy, int type; const struct nlattr *attr; int r = 0; - u32 *freq_list; + u32 *freq_list = NULL; int freq_list_len = 0; SLSI_INFO(sdev, "SUBCMD_ACS_INIT Received\n"); @@ -6233,6 +6359,9 @@ static int slsi_acs_init(struct wiphy *wiphy, } case SLSI_ACS_ATTR_FREQ_LIST: { + if (freq_list) /* This check is to avoid Prevent Issue */ + break; + freq_list = kmalloc(nla_len(attr), GFP_KERNEL); if (!freq_list) { SLSI_ERR(sdev, "No memory for frequency list!"); diff --git a/drivers/net/wireless/scsc/nl80211_vendor.h b/drivers/net/wireless/scsc/nl80211_vendor.h index 2d456372e790..7237219ca1b2 100755 --- a/drivers/net/wireless/scsc/nl80211_vendor.h +++ b/drivers/net/wireless/scsc/nl80211_vendor.h @@ -1689,9 +1689,7 @@ void slsi_rx_range_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_ 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); -#endif void slsi_nan_event(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); void slsi_nan_followup_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); void slsi_nan_service_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); diff --git a/drivers/net/wireless/scsc/procfs.c b/drivers/net/wireless/scsc/procfs.c index 2b3a402eb3fa..030a79a83c5f 100755 --- a/drivers/net/wireless/scsc/procfs.c +++ b/drivers/net/wireless/scsc/procfs.c @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ @@ -110,46 +110,56 @@ static ssize_t slsi_procfs_throughput_stats_read(struct file *file, char __user const size_t bufsz = sizeof(buf); struct slsi_dev *sdev = (struct slsi_dev *)file->private_data; struct net_device *dev; + struct netdev_vif *ndev_vif; 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 } }, + struct slsi_mib_get_entry get_values[] = {{ 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_PSID_UNIFI_THROUGHPUT_DEBUG, { 5, 0 } }, + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 25, 0 } }, + { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 30, 0 } } }; SLSI_UNUSED_PARAMETER(file); dev = slsi_get_netdev(sdev, 1); + ndev_vif = netdev_priv(dev); - 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) { + if (ndev_vif->activated) { + 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 -EINVAL; + } else { + pos += scnprintf(buf, bufsz, "RX FCS: %d\n", 0); + pos += scnprintf(buf + pos, bufsz - pos, "RX bad SIG: %d\n", 0); + pos += scnprintf(buf + pos, bufsz - pos, "RX dot11 error: %d\n", 0); + pos += scnprintf(buf + pos, bufsz - pos, "TX MPDU no ACK: %d\n", 0); + pos += scnprintf(buf + pos, bufsz - pos, "TX A-MPDU no ACK: %d\n", 0); } - 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); } @@ -385,7 +395,9 @@ static int slsi_procfs_build_show(struct seq_file *m, void *v) #else seq_puts(m, "CONFIG_SCSC_WLAN_ENHANCED_LOGGING : n\n"); #endif +#ifdef CONFIG_SCSC_AP_INTERFACE_NAME seq_printf(m, "CONFIG_SCSC_AP_INTERFACE_NAME : %s\n", CONFIG_SCSC_AP_INTERFACE_NAME); +#endif return 0; } diff --git a/drivers/net/wireless/scsc/rx.c b/drivers/net/wireless/scsc/rx.c index ded0e3a6271d..0d6599c9d2ff 100755 --- a/drivers/net/wireless/scsc/rx.c +++ b/drivers/net/wireless/scsc/rx.c @@ -527,7 +527,7 @@ void slsi_scan_complete(struct slsi_dev *sdev, struct net_device *dev, u16 scan_ if (scan_id == SLSI_SCAN_SCHED_ID) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) - cfg80211_sched_scan_results(sdev->wiphy, SLSI_SCAN_SCHED_ID); + cfg80211_sched_scan_results(sdev->wiphy, ndev_vif->scan[scan_id].sched_req->reqid); #else cfg80211_sched_scan_results(sdev->wiphy); #endif @@ -1247,6 +1247,7 @@ void slsi_rx_roamed_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk SLSI_MUTEX_LOCK(ndev_vif->vif_mutex); + SLSI_INFO(sdev, "Received Association Response\n"); SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_roamed_ind(vif:%d) Roaming to %pM\n", fapi_get_vif(skb), mgmt->bssid); @@ -1408,7 +1409,7 @@ void slsi_rx_roam_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_b SLSI_UNUSED_PARAMETER(sdev); - SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_roam_ind(vif:%d, aid:0, result:%d )\n", + SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_roam_ind(vif:%d, aid:0, result:0x%04x )\n", fapi_get_vif(skb), fapi_get_u16(skb, u.mlme_roam_ind.result_code)); @@ -1680,7 +1681,7 @@ void slsi_rx_reassoc_ind(struct slsi_dev *sdev, struct net_device *dev, struct s u8 *reassoc_rsp_ie = NULL; int reassoc_rsp_ie_len = 0; - SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_reassoc_ind(vif:%d, result:0x%2x)\n", + SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_reassoc_ind(vif:%d, result:0x%04x)\n", fapi_get_vif(skb), fapi_get_u16(skb, u.mlme_reassociate_ind.result_code)); @@ -1796,7 +1797,7 @@ void slsi_rx_connect_ind(struct slsi_dev *sdev, struct net_device *dev, struct s fw_result_code = fapi_get_u16(skb, u.mlme_connect_ind.result_code); - SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_connect_ind(vif:%d, result:%d)\n", + SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_connect_ind(vif:%d, result:0x%04x)\n", fapi_get_vif(skb), fw_result_code); SLSI_INFO(sdev, "Received Association Response\n"); @@ -1822,7 +1823,12 @@ void slsi_rx_connect_ind(struct slsi_dev *sdev, struct net_device *dev, struct s } sdev->assoc_result_code = fw_result_code; if (fw_result_code != FAPI_RESULTCODE_SUCCESS) { - SLSI_NET_ERR(dev, "Connect failed. FAPI code:%d\n", fw_result_code); + if (fw_result_code == FAPI_RESULTCODE_AUTH_NO_ACK) + SLSI_INFO(sdev, "Connect failed,Result code:AUTH_NO_ACK\n"); + else if (fw_result_code == FAPI_RESULTCODE_ASSOC_NO_ACK) + SLSI_INFO(sdev, "Connect failed,Result code:ASSOC_NO_ACK\n"); + else + SLSI_INFO(sdev, "Connect failed,Result code:0x%04x\n", fw_result_code); #ifdef CONFIG_SCSC_LOG_COLLECTION /* Trigger log collection if fw result code is not success */ scsc_log_collector_schedule_collection(SCSC_LOG_HOST_WLAN, SCSC_LOG_HOST_WLAN_REASON_CONNECT_ERR); @@ -2302,6 +2308,7 @@ void slsi_rx_received_frame_ind(struct slsi_dev *sdev, struct net_device *dev, s u16 data_unit_descriptor = fapi_get_u16(skb, u.mlme_received_frame_ind.data_unit_descriptor); u16 frequency = SLSI_FREQ_FW_TO_HOST(fapi_get_u16(skb, u.mlme_received_frame_ind.channel_frequency)); u8 *eapol = NULL; + u8 *eap = NULL; u16 protocol = 0; u32 dhcp_message_type = SLSI_DHCP_MESSAGE_TYPE_INVALID; @@ -2412,13 +2419,15 @@ void slsi_rx_received_frame_ind(struct slsi_dev *sdev, struct net_device *dev, s /* Storing Data for Logging Information */ if ((skb->len + sizeof(struct ethhdr)) >= 99) eapol = skb->data + sizeof(struct ethhdr); + if ((skb->len + sizeof(struct ethhdr)) >= 5) + eap = skb->data + sizeof(struct ethhdr); if (skb->len >= 285 && slsi_is_dhcp_packet(skb->data) != SLSI_TX_IS_NOT_DHCP) dhcp_message_type = skb->data[284]; skb->protocol = eth_type_trans(skb, dev); protocol = ntohs(skb->protocol); - if (protocol == ETH_P_PAE && eapol) { - if (eapol[SLSI_EAPOL_IEEE8021X_TYPE_POS] == SLSI_IEEE8021X_TYPE_EAPOL_KEY) { + if (protocol == ETH_P_PAE) { + if (eapol && eapol[SLSI_EAPOL_IEEE8021X_TYPE_POS] == SLSI_IEEE8021X_TYPE_EAPOL_KEY) { if ((eapol[SLSI_EAPOL_TYPE_POS] == SLSI_EAPOL_TYPE_RSN_KEY || eapol[SLSI_EAPOL_TYPE_POS] == SLSI_EAPOL_TYPE_WPA_KEY) && (eapol[SLSI_EAPOL_KEY_INFO_LOWER_BYTE_POS] & @@ -2437,6 +2446,15 @@ void slsi_rx_received_frame_ind(struct slsi_dev *sdev, struct net_device *dev, s } else { SLSI_INFO(sdev, "Received 4way-H/S, M2\n"); } + } else if (eap && eap[SLSI_EAPOL_IEEE8021X_TYPE_POS] == SLSI_IEEE8021X_TYPE_EAP_PACKET) { + if (eap[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_REQUEST) + SLSI_INFO(sdev, "Received EAP-Request\n"); + else if (eap[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_RESPONSE) + SLSI_INFO(sdev, "Received EAP-Response\n"); + else if (eap[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_SUCCESS) + SLSI_INFO(sdev, "Received EAP-Success\n"); + else if (eap[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_FAILURE) + SLSI_INFO(sdev, "Received EAP-Failure\n"); } } else if (protocol == ETH_P_IP) { if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_DISCOVER) diff --git a/drivers/net/wireless/scsc/sap_mlme.c b/drivers/net/wireless/scsc/sap_mlme.c index 64939c32ccc5..2610eb0f3fac 100755 --- a/drivers/net/wireless/scsc/sap_mlme.c +++ b/drivers/net/wireless/scsc/sap_mlme.c @@ -174,11 +174,9 @@ static int slsi_rx_netdev_mlme(struct slsi_dev *sdev, struct net_device *dev, st 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); diff --git a/drivers/net/wireless/scsc/tx.c b/drivers/net/wireless/scsc/tx.c index c35ae12b9274..24a0b8b0d071 100755 --- a/drivers/net/wireless/scsc/tx.c +++ b/drivers/net/wireless/scsc/tx.c @@ -82,6 +82,18 @@ static int slsi_tx_eapol(struct slsi_dev *sdev, struct net_device *dev, struct s } } else { msg_type = FAPI_MESSAGETYPE_EAP_MESSAGE; + if ((skb->len + sizeof(struct ethhdr)) >= 5) + eapol = skb->data + sizeof(struct ethhdr); + if (eapol && eapol[SLSI_EAPOL_IEEE8021X_TYPE_POS] == SLSI_IEEE8021X_TYPE_EAP_PACKET) { + if (eapol[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_REQUEST) + SLSI_INFO(sdev, "Send EAP-Request\n"); + else if (eapol[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_RESPONSE) + SLSI_INFO(sdev, "Send EAP-Response\n"); + else if (eapol[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_SUCCESS) + SLSI_INFO(sdev, "Send EAP-Success\n"); + else if (eapol[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_FAILURE) + SLSI_INFO(sdev, "Send EAP-Failure\n"); + } dwell_time = 0; } break; diff --git a/drivers/net/wireless/scsc/utils.h b/drivers/net/wireless/scsc/utils.h index 2a353728c9ae..57d937f104d6 100755 --- a/drivers/net/wireless/scsc/utils.h +++ b/drivers/net/wireless/scsc/utils.h @@ -26,6 +26,19 @@ struct slsi_skb_cb { struct sk_buff *skb_addr; }; +static inline u32 slsi_convert_tlv_data_to_value(u8 *data, u16 length) +{ + u32 value = 0; + int i; + + if (length > 4) + return 0; + for (i = 0; i < length; i++) + value |= ((u32)data[i]) << i * 8; + + return value; +} + static inline struct slsi_skb_cb *slsi_skb_cb_get(struct sk_buff *skb) { return (struct slsi_skb_cb *)skb->cb; diff --git a/include/scsc/scsc_log_collector.h b/include/scsc/scsc_log_collector.h index 33cb9bdbc8ae..13429ed7db4c 100644 --- a/include/scsc/scsc_log_collector.h +++ b/include/scsc/scsc_log_collector.h @@ -80,6 +80,7 @@ enum scsc_log_chunk_type { #define SCSC_LOG_USER_REASON_PROC 0x0000 /* Reason codes for SCSC_LOG_DUMPSTATE */ #define SCSC_LOG_DUMPSTATE_REASON 0x0000 +#define SCSC_LOG_DUMPSTATE_REASON_DRIVERDEBUGDUMP 0x0001 /* Reason codes for SCSC_LOG_HOST_WLAN */ #define SCSC_LOG_HOST_WLAN_REASON_DISCONNECT 0x0000 #define SCSC_LOG_HOST_WLAN_REASON_DISCONNECT_IND 0x0001 diff --git a/include/scsc/scsc_mx.h b/include/scsc/scsc_mx.h index af99136a6d37..46ae99d10eb8 100755 --- a/include/scsc/scsc_mx.h +++ b/include/scsc/scsc_mx.h @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ @@ -104,6 +104,12 @@ struct fm_ldo_conf { uint32_t version; /* FM_LDO_CONFIG_VERSION */ uint32_t ldo_on; }; + +/* Parameters to pass from FM radio client driver to WLBT drivers */ +struct wlbt_fm_params { + u32 freq; /* Frequency (Hz) in use by FM radio */ +}; + #endif #define PANIC_RECORD_SIZE 64 @@ -152,6 +158,7 @@ void scsc_mx_service_service_failed(struct scsc_service *service, const char *re */ void scsc_service_on_halt_ldos_on(struct scsc_service *service); void scsc_service_on_halt_ldos_off(struct scsc_service *service); +int scsc_service_fm_set_params(struct scsc_service *service, struct wlbt_fm_params *params); #endif /* MEMORY Interface*/ @@ -221,6 +228,16 @@ struct device *scsc_service_get_device_by_mx(struct scsc_mx *mx); int scsc_service_force_panic(struct scsc_service *service); +/* + * API to share /sys/wifi kobject between core and wifi driver modules. + * Depending upon the order of loading respective drivers, a kobject is + * created and shared with the other driver. This convoluted implementation + * is required as we need the common kobject associated with "/sys/wifi" directory + * when creating a file underneth. core driver (mxman.c) need to create "memdump" + * and wifi driver (dev.c,mgt.c) needs to create "mac_addr" files respectively. + */ +struct kobject *mxman_wifi_kobject_ref_get(void); +void mxman_wifi_kobject_ref_put(void); #ifdef CONFIG_SCSC_SMAPPER /* SMAPPER Interface */ @@ -392,6 +409,15 @@ int mx250_fm_request(void); int mx250_fm_release(void); +/* FM client informs of parameter change. + * + * mx250_fm_request() must have been called first. + * + * Returns: + * None + */ +void mx250_fm_set_params(struct wlbt_fm_params *info); + /* * for set test mode. * @@ -406,4 +432,28 @@ void mxman_get_driver_version(char *version, size_t ver_sz); int mxman_register_firmware_notifier(struct notifier_block *nb); int mxman_unregister_firmware_notifier(struct notifier_block *nb); +/* Status of WLBT autorecovery on the platform + * + * Returns: + * false - enabled, true disabled + */ +bool mxman_recovery_disabled(void); + +/* function to provide string representation of uint8 trigger code */ +static inline const char *scsc_get_trigger_str(int code) +{ + switch (code) { + case 1: return "scsc_log_fw_panic"; + case 2: return "scsc_log_user"; + case 3: return "scsc_log_fw"; + case 4: return "scsc_log_dumpstate"; + case 5: return "scsc_log_host_wlan"; + case 6: return "scsc_log_host_bt"; + case 7: return "scsc_log_host_common"; + case 0: + default: + return "unknown"; + } +}; + #endif diff --git a/include/scsc/scsc_release.h b/include/scsc/scsc_release.h index 39eec60d897c..a27e635bca33 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 60 +#define SCSC_RELEASE_ITERATION 62 #define SCSC_RELEASE_CANDIDATE 1 #define SCSC_RELEASE_POINT 0 -- 2.20.1