[RAMEN9610-12050][common][9610] wlbt : enable NAPI & RPS with update host version...
authorYoungsoo <youngss.kim@samsung.com>
Tue, 12 Feb 2019 05:02:08 +0000 (14:02 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:23:15 +0000 (20:23 +0300)
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

41 files changed:
arch/arm64/boot/dts/exynos/exynos9610.dtsi
arch/arm64/configs/erd9610_defconfig
drivers/misc/samsung/scsc/miframman.c
drivers/misc/samsung/scsc/mx250_fm.c
drivers/misc/samsung/scsc/mx250_fm_test.c
drivers/misc/samsung/scsc/mxlogger.c
drivers/misc/samsung/scsc/mxman.c
drivers/misc/samsung/scsc/mxman.h
drivers/misc/samsung/scsc/mxmgmt_transport.c
drivers/misc/samsung/scsc/mxproc.c
drivers/misc/samsung/scsc/platform_mif.c
drivers/misc/samsung/scsc/scsc_log_collector.c
drivers/misc/samsung/scsc/scsc_service.c
drivers/misc/samsung/scsc/scsc_wlbtd.c
drivers/misc/samsung/scsc/scsc_wlbtd.h
drivers/misc/samsung/scsc_bt/scsc_bluez.c
drivers/misc/samsung/scsc_bt/scsc_bt_module.c
drivers/misc/samsung/scsc_bt/scsc_shm.c
drivers/net/wireless/scsc/Kconfig
drivers/net/wireless/scsc/cfg80211_ops.c
drivers/net/wireless/scsc/cm_if.c
drivers/net/wireless/scsc/dev.c
drivers/net/wireless/scsc/dev.h
drivers/net/wireless/scsc/fapi.h
drivers/net/wireless/scsc/hip4.c
drivers/net/wireless/scsc/ioctl.c
drivers/net/wireless/scsc/mgt.c
drivers/net/wireless/scsc/mgt.h
drivers/net/wireless/scsc/mib.h
drivers/net/wireless/scsc/mlme.c
drivers/net/wireless/scsc/netif.c
drivers/net/wireless/scsc/nl80211_vendor.c
drivers/net/wireless/scsc/nl80211_vendor.h
drivers/net/wireless/scsc/procfs.c
drivers/net/wireless/scsc/rx.c
drivers/net/wireless/scsc/sap_mlme.c
drivers/net/wireless/scsc/tx.c
drivers/net/wireless/scsc/utils.h
include/scsc/scsc_log_collector.h
include/scsc/scsc_mx.h
include/scsc/scsc_release.h

index 03b9ca9daa95232b5ef58e83db7938d475ae5607..ef9ed3c8ad633bb23beccfd8dd0d69694ac0afc3 100644 (file)
 
        boot_cfg: syscon@14C60000 {
                compatible = "boot_cfg", "syscon";
-               reg = <0x0 0x14C60000 0x1100>;
+               reg = <0x0 0x14C60000 0x1200>;
        };
 
        /* MAILBOX_AP2WLBT */
index 926ad16e711116750f9e07844739edf344b53886..88c3d22d9fec4b90aa51a4daa216e43279b6fba3 100755 (executable)
@@ -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
index ba6253cec887d741cecad0ad4e8e813086653dc6..3663b657d6090f7be0286c9066d138a5237a47ce 100644 (file)
@@ -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 *);
index cb21ab7b14dff6aa6f994894482c5e228b1271b4..93c5f695082b64a1cd06a8dc81895d11165f1963 100755 (executable)
@@ -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)
 {
index 70706628ee070284a0b64798adb766634aa16e08..7132367ef303e8be14b970ee84902cb05ee2930f 100644 (file)
@@ -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(&params);
+       }
 error:
        return len;
 }
index fa7baec3f3d01e9d764cdbb9363c651a7f250636..4d46c8b8b70e6a5be444f0b11ca79bc8ad460950 100644 (file)
@@ -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;
        }
 
index 3b1b33b32fab5e2ed3ef753a0cc2d609a0023bd1..38d44c8085c16ac168da3b332118a0459841e44b 100755 (executable)
@@ -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 : "<null>");
        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);
 
index df4a18f3e237b139236a9fb8050b060ebb1a7c4f..f5bcda69f34dfbde9ed48c563d6c425f63ef4d62 100755 (executable)
@@ -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);
index a45506194c61a24c8b64c68a300c61bd7c05ddf2..ec4f95c82b8fc883ad6e12ae15687dce74c2158d 100644 (file)
@@ -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;
index 2bca3b7ce41b7c89065a34f743b432c85906d97f..464aa3c00b3e5444820f2f9df28fac0b231c9f37 100644 (file)
@@ -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);
 
index 2ea092387a92ab75e681a84d5b92682e27f93f8e..61d56b8760a0dd84fd6866e1645532302762f34d 100755 (executable)
@@ -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,
index f7df7e51dde14c6852f2f5a41fb6c29614445c73..08d51e0faf17a9164304fa3577e4bb447b02399a 100644 (file)
@@ -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 <linux/uaccess.h>
@@ -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;
                }
index 9f28ea9c52e073f526a1de781fbc28ee5091f4e8..f4d31035c93732f361e1e75418e58add11099568 100755 (executable)
@@ -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)
index 207dd878ef3125f0420a56f3c1e34103d52e14e9..34003a677cad3a057996dfdc6445babccf2aea86 100755 (executable)
@@ -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 <linux/mutex.h>
@@ -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);
index 51b821af65af6c0f82a8b10c0cb6a4e51e4122c2..746c12d4d0902b2030e80bfc2b7d86f735c64162 100644 (file)
@@ -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 <net/genetlink.h>
 #include <scsc/scsc_logring.h>
+#include <scsc/scsc_mx.h>
+
+/* 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.
  * 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);
index cb20ab7569481ff4d941b2700f8ffc67ed508482..1c58f95c19f0e298619be5e582b84e9e4e9c39ea 100755 (executable)
@@ -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");
 }
 
index 67f3dca83ad83cab7eb673e982b545e393087544..49c8f9cef2ddd31804ee51911019233161243cb4 100755 (executable)
@@ -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);
index 4490936c48c6587a1dae5854277586b6d1dece96..d1cdd2c6fde6b5cbcd424b1944236c03e6f27104 100755 (executable)
@@ -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) {
index daeb6f02cf825f421fafc5a7c5dfd0722c9e3d58..fea09567667881dcf053c98227ce93b6fa5b104b 100644 (file)
@@ -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.
index 39f404951c1b93846ec12d4388dfcd1086a41211..67d67c4f8cdbc506ebaee76535910074abe78bc9 100755 (executable)
@@ -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;
 }
 
index ea0a0744152813d949877bb0578ad09a1a6ef01c..0f3447ee243ee5be0a581c032a41b378e2c3a5e3 100755 (executable)
@@ -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");
 
index fa4a70d09d295fdfb0fcb75b9e22c2f7bc717b98..4701f88e8fd345933609219f9deb85c4f99e6295 100644 (file)
@@ -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]);
 
index eb27876c45a838d0242ea48b5dd4b8bb57e2de7f..11f8a55b31614eb0e287f59dfc25a53fb51a8cfb 100755 (executable)
@@ -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
index b726062af1f609f57007617b6537db7162802d29..b72e3a9dffbd84337e5c4614fde3db4b1f6df135 100644 (file)
@@ -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
index 3ae77329d489adb1823b9fa9dc7acffa182cd9d3..8d80f4142217de9e730414b0e4e2b6edf890532d 100755 (executable)
@@ -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)) {
index bc4e8e521177626f0b657beeebf51b12c0bf90e6..7d6395af8379f0091bcb13070b89cf70bd35bbd8 100755 (executable)
 #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
index d5d444682f15ce2f1856a1827dc7af8ebd40877c..f80ca486d438a1947bdfa920e3dcb10af45363c9 100755 (executable)
@@ -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 };
index 31c909a692c99ca16505b274930ac586bb9965c5..631a975d4bc40551e1c64a47f552874fcb6fa513 100755 (executable)
@@ -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
  *
  *****************************************************************************/
 
 #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,
index 2200988c2e69026b74165ff5d8ac247eb5f0d431..cc6f5ab3dddd04f072319be69026c6755a5ab840 100644 (file)
@@ -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.
index 127ce2e6a1876d9f42a8f4c5fb3f2454be15ff9b..4d8d3a793737b33f989e8ef952e87ff673526247 100755 (executable)
@@ -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;
        }
 
index 9bb0f622ff30d052a8e1f69ac63e207f8e9ff4ce..2dfcc8b653c11c68141eb9528faa18e6b9e7025d 100755 (executable)
@@ -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);
        }
 }
 
index 50679c5ed3dfc3a8a5f6668e232a0e36253c3693..869c98832967103886c0a757f4fff8cae7a0fa9b 100755 (executable)
@@ -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 <linux/version.h>
 #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!");
index 2d456372e790a1dbfcca7cc6964625ad527d4cc9..7237219ca1b2ec314058e4689825a3e2ea208d52 100755 (executable)
@@ -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);
index 2b3a402eb3fac863fcabdd967e43bc38f47f552f..030a79a83c5f8a30a57f3ec03ebe5c12e49814b1 100755 (executable)
@@ -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;
 }
index ded0e3a6271d757d6b40ea7b707a093b3504e2b4..0d6599c9d2ffd788a02c94bb3ec2c7b8d35221f1 100755 (executable)
@@ -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)
index 64939c32ccc5ceca884e895313dba94f64ab4cc7..2610eb0f3facab4910896dc9e7064ab698d143cd 100755 (executable)
@@ -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);
index c35ae12b92741ea61c2ae6bf3f25232b775c49b6..24a0b8b0d0710d55a4eaf2ed2b182f37ea2eac97 100755 (executable)
@@ -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;
index 2a353728c9ae1a55e1841b7e3d231d011a882b54..57d937f104d6b8d5e63e9a0ae8a946dfe624906d 100755 (executable)
@@ -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;
index 33cb9bdbc8ae04dbc93fd134cdd07b4c952799b9..13429ed7db4c9e2bb7db743c06ceea9e10df5143 100644 (file)
@@ -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
index af99136a6d37af52fc2e2fe34f3162e922981343..46ae99d10eb8403a94d401f11d95bdd327faa971 100755 (executable)
@@ -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
index 39eec60d897ce7e6e8e09f7f586a5c682ca62a0c..a27e635bca33feb08b7e560e58bc5e562ff5825e 100644 (file)
@@ -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