boot_cfg: syscon@14C60000 {
compatible = "boot_cfg", "syscon";
- reg = <0x0 0x14C60000 0x1100>;
+ reg = <0x0 0x14C60000 0x1200>;
};
/* MAILBOX_AP2WLBT */
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 = 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;
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 *);
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);
}
+/*
+ * FM Radio is starting, tell WLBT drivers
+ */
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__);
}
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)
{
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;
}
mx250_fm_request();
else if (val == 0)
mx250_fm_release();
- else
- SCSC_TAG_INFO(FM_TEST, "val %ld is not valid, 1 - on, 0 - off\n", val);
+ else {
+ /* All other values are frequency info */
+ params.freq = (u32)val;
+
+ SCSC_TAG_INFO(FM_TEST, "FM freq=%u\n", params.freq);
+
+ mx250_fm_set_params(¶ms);
+ }
error:
return len;
}
/* 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;
}
/****************************************************************************
*
- * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
#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);
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);
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;
MM_HOST_RESUME = 4,
MM_FW_CONFIG = 5,
MM_HALT_RSP = 6,
+ MM_FM_RADIO_CONFIG = 7,
} ma_msg;
/**
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;
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
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
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;
}
case 0x00b2:
return "S620";
case 0x0000:
+#ifndef CONFIG_SOC_EXYNOS9610
return "Error: check if RF chip is present";
+#else
+ return "Unknown";
+#endif
}
return "Unknown";
}
/* 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;
}
/* 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;
/* 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));
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;
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);
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)
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");
}
}
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);
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;
}
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);
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);
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);
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)
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);
/****************************************************************************
*
- * Copyright (c) 2014 - 2017 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
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 {
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);
/* 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);
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;
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);
* 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
0x019e7522,
0x75cfc175,
0xc375a4c2,
- 0x47c4750a,
+ 0x47c4754a,
0x75a4c575,
- 0xc7756cc6,
+ 0xc7756dc6,
0x03d27540,
0x7510d375,
0xca7500c9,
0x78009d75,
0x12827402,
0xc6438b80,
- 0x74057802,
- 0x8b8012d0,
+ 0x74097802,
+ 0x8b8012e7,
0x75d09075,
0x9e750291,
0x01a97502,
/********************************************************************************
*
- * 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>
#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;
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();
#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)));
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;
}
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;
}
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)
/****************************************************************************
*
- * 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>
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);
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);
};
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[] = {
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;
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) {
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;
}
/* 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);
/****************************************************************************
*
- * 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,
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);
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;
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);
}
ret = bt_fs->release(NULL, NULL);
+ if (wq != NULL) {
+ destroy_workqueue(wq);
+ wq = NULL;
+ }
+
SCSC_TAG_INFO(BT_COMMON, "done\n");
return ret;
{
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);
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;
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");
}
#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)
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
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,
bhcs->bluetooth_address_nap,
bhcs->bluetooth_address_uap,
bhcs->bluetooth_address_lap);
+#endif /* CONFIG_SCSC_DEBUG */
return err;
}
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
*/
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
*/
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");
}
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");
}
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);
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);
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";
return ret;
}
+#endif
static ssize_t scsc_iq_report_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) {
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
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.
/***************************************************************************
*
- * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
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))
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);
}
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);
* 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;
}
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.
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*/
*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;
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;
}
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 {
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");
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;
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);
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");
/****************************************************************************
*
- * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
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;
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
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]);
/*****************************************************************************
*
- * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
#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
#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;
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
#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
/******************************************************************************
*
- * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
*****************************************************************************/
#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
}
/* 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];
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;
}
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;
}
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);
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;
}
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);
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;
}
#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;
}
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);
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]);
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;
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();
}
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);
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;
}
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);
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;
}
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)) {
#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"
}
#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;
}
{
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)
{
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,
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);
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;
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;
(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
/******************************************************************************
*
- * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
*****************************************************************************/
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;
};
#endif
-#define SLSI_SM_WLAN_SERVICE_RECOVERY_COMPLETED_TIMEOUT 20000
int slsi_start(struct slsi_dev *sdev)
{
#ifndef CONFIG_SCSC_DOWNLOAD_FILE
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");
} 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");
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
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 };
/******************************************************************************
*
- * 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
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,
/****************************************************************************
*
- * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
* 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
*******************************************************************************/
#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)
* 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
* 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
*******************************************************************************/
#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)
* 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
*******************************************************************************/
#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)
#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
* 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
* 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
* 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
*******************************************************************************/
#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)
*******************************************************************************/
#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)
*******************************************************************************/
#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)
* PER INTERFACE?: NO
* TYPE : SlsiUint16
* MIN : 0
- * MAX : 65535
+ * MAX : 255
* DEFAULT : 5
* DESCRIPTION :
* Number of retries of probe response frame.
* 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
* 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
* 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
/*******************************************************************************
* NAME : UnifiCcaMasterSwitch
* PSID : 5102 (0x13EE)
* PER INTERFACE?: NO
- * TYPE : SlsiUint16
+ * TYPE : SlsiUint32
* MIN : 0
- * MAX : 65535
- * DEFAULT :
+ * MAX : 4294967295
+ * DEFAULT : 0X00540050
* DESCRIPTION :
* Enables CCA
*******************************************************************************/
* 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
* 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
* 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
* 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
* 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)
* 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
* TYPE : SlsiUint16
* MIN : 0
* MAX : 65535
- * DEFAULT : 0XFFFF
+ * DEFAULT : 0X03DD
* DESCRIPTION :
* Bitfield to enable Control Plane Tx Power processing. MLME/Macrame use
* only.
* 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
* 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.
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);
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;
}
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)) {
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;
}
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;
}
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;
}
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;
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;
}
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;
}
}
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;
}
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;
}
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;
}
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;
}
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);
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 {
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);
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;
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;
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);
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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);
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);
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;
}
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;
}
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;
}
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;
}
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;
}
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);
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;
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;
}
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);
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;
}
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;
}
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;
}
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;
}
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;
}
}
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;
}
/*
*
- * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
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;
}
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;
}
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]);
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;
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);
}
}
/*****************************************************************************
*
- * 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
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
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)
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;
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");
}
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!");
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);
/*****************************************************************************
*
- * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
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);
}
#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;
}
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
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);
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));
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));
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");
}
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);
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;
/* 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] &
} 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)
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);
}
} 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;
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;
#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
/****************************************************************************
*
- * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
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
*/
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*/
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 */
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.
*
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
#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