summaryrefslogtreecommitdiff
path: root/scenes_fsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'scenes_fsm.c')
-rw-r--r--scenes_fsm.c171
1 files changed, 136 insertions, 35 deletions
diff --git a/scenes_fsm.c b/scenes_fsm.c
index 991863e..768c75d 100644
--- a/scenes_fsm.c
+++ b/scenes_fsm.c
@@ -6,12 +6,12 @@
*
* Author: Star Chang <starchang@google.com>
*/
+#include <linux/debugfs.h>
#include "core.h"
-#define fsm_to_core(fsm) \
- (container_of(fsm, struct wlan_ptracker_core, fsm))
+#define fsm_to_core(fsm) (container_of(fsm, struct wlan_ptracker_core, fsm))
-static const struct wlan_state_condition conditions[FSM_STATE_MAX] = {
+static struct wlan_state_condition conditions[FSM_STATE_MAX] = {
{
.scene = WLAN_SCENE_IDLE,
.ac_mask = WMM_AC_ALL_MASK,
@@ -22,14 +22,13 @@ static const struct wlan_state_condition conditions[FSM_STATE_MAX] = {
.scene = WLAN_SCENE_WEB,
.ac_mask = WMM_AC_ALL_MASK,
.min_tp_threshold = 1000,
- .max_tp_threshold = 10000,
+ .max_tp_threshold = 9000,
},
{
.scene = WLAN_SCENE_YOUTUBE,
.ac_mask = WMM_AC_ALL_MASK,
- /* Total >= 10 Mbps && < 50 Mbps */
- .min_tp_threshold = 10000,
- .max_tp_threshold = 50000,
+ .min_tp_threshold = 9000,
+ .max_tp_threshold = 60000,
},
{
.scene = WLAN_SCENE_LOW_LATENCY,
@@ -41,8 +40,7 @@ static const struct wlan_state_condition conditions[FSM_STATE_MAX] = {
{
.scene = WLAN_SCENE_TPUT,
.ac_mask = WMM_AC_ALL_MASK,
- /* Total >= 50 Mbps */
- .min_tp_threshold = 50000,
+ .min_tp_threshold = 60000,
.max_tp_threshold = __INT_MAX__,
},
};
@@ -53,7 +51,7 @@ static int fsm_thread(void *param)
struct wlan_scene_event *msg = &fsm->msg;
struct wlan_ptracker_core *core = fsm_to_core(fsm);
- while (1) {
+ while (fsm->thread_run) {
set_current_state(TASK_INTERRUPTIBLE);
if (kthread_should_stop()) {
ptracker_info(core, "kthread is stopped\n");
@@ -61,26 +59,14 @@ static int fsm_thread(void *param)
}
wait_for_completion(&fsm->event);
ptracker_dbg(core, "state: %d, trans state %d -> %d, rate %llu\n",
- msg->state, msg->src, msg->dst, msg->rate);
-
- /*
- * Request twice of transmit events are happing then trans state,
- * to make sure the state is stable enough.
- * first time: confirm is false, send prepare first.
- * (ex: twt can tear down original setup first)
- * second time: confirm is true and change the state to dst.
- */
- if (fsm->confirm) {
- wlan_ptracker_call_chain(&core->notifier,
- WLAN_PTRACKER_NOTIFY_SCENE_CHANGE, core);
- msg->state = msg->dst;
- fsm->confirm = false;
- } else {
- /* call notifier chain */
- wlan_ptracker_call_chain(&core->notifier,
+ msg->state, msg->src, msg->dst, msg->rate);
+ wlan_ptracker_call_chain(&core->notifier,
WLAN_PTRACKER_NOTIFY_SCENE_CHANGE_PREPARE, core);
- fsm->confirm = true;
- }
+ fsm->confirm = true;
+ wlan_ptracker_call_chain(&core->notifier,
+ WLAN_PTRACKER_NOTIFY_SCENE_CHANGE, core);
+ msg->state = msg->dst;
+ fsm->confirm = false;
}
return 0;
}
@@ -149,15 +135,20 @@ static void scenes_fsm_decision(struct wlan_ptracker_core *core, u32 type)
/* reset check */
if (type == WLAN_PTRACKER_NOTIFY_SUSPEND) {
fsm->reset_cnt++;
- except = !(fsm->reset_cnt % RESET_THRESHOLD);
+ except = (fsm->reset_cnt >= RESET_THRESHOLD) ? true : false;
}
/* check state isn't change and not first time do nothing */
- if (new_state == msg->state && type != WLAN_PTRACKER_NOTIFY_STA_CHANGE)
+ if (new_state == msg->state &&
+ type != WLAN_PTRACKER_NOTIFY_STA_CONNECT)
return;
/* new state must higher then current state */
- if (new_state < msg->state && !except)
+ if (new_state < msg->state && !except) {
+ ptracker_dbg(core,
+ "state not change since new state %d < old state %d and reset_cnt is %d\n",
+ new_state, msg->state, fsm->reset_cnt);
return;
+ }
ptracker_dbg(core, "type %d, reset_cnt %d, %d -> %d\n",
type, fsm->reset_cnt, msg->state, new_state);
@@ -180,6 +171,7 @@ static int scene_notifier_handler(struct notifier_block *nb,
{
struct wlan_ptracker_core *core = ptr;
struct wlan_ptracker_notifier *notifier = &core->notifier;
+ struct wlan_ptracker_fsm *fsm = &core->fsm;
/*
* Events of suspen and sta change will block wlan driver
@@ -187,11 +179,14 @@ static int scene_notifier_handler(struct notifier_block *nb,
*/
switch (event) {
case WLAN_PTRACKER_NOTIFY_SUSPEND:
+#ifdef TP_DEBUG
ptracker_dbg(core, "update time (%d)\n",
jiffies_to_msecs(jiffies - notifier->prev_event));
+#endif
notifier->prev_event = jiffies;
- case WLAN_PTRACKER_NOTIFY_STA_CHANGE:
+ case WLAN_PTRACKER_NOTIFY_STA_CONNECT:
case WLAN_PTRACKER_NOTIFY_TP:
+ fsm->confirm = true;
scenes_fsm_decision(core, event);
break;
default:
@@ -205,6 +200,107 @@ static struct notifier_block scene_nb = {
.notifier_call = scene_notifier_handler,
};
+static int scene_cond_set(struct wlan_ptracker_fsm *fsm)
+{
+ struct wlan_state_condition *param = &conditions[fsm->state];
+
+ param->ac_mask = fsm->ac_mask;
+ param->max_tp_threshold = fsm->max_tput;
+ param->min_tp_threshold = fsm->min_tput;
+ return 0;
+}
+
+static int scene_debugfs_action(struct wlan_ptracker_core *core, u32 action)
+{
+ struct wlan_ptracker_fsm *fsm = &core->fsm;
+ switch (action) {
+ case SCENE_TEST_SET_PARAM:
+ scene_cond_set(fsm);
+ break;
+ default:
+ ptracker_err(core, "action %d is not supported\n", action);
+ break;
+ }
+ return 0;
+}
+
+static ssize_t scene_params_write(struct file *file,
+ const char __user *buf, size_t len, loff_t *ppos)
+{
+ struct wlan_ptracker_core *core = file->private_data;
+ u32 action;
+
+ if (kstrtouint_from_user(buf, len, 10, &action))
+ return -EFAULT;
+
+ /* active action */
+ scene_debugfs_action(core, action);
+ return 0;
+}
+
+static int _scene_params_read(char *buf, int len)
+{
+ struct wlan_state_condition *param;
+ int count = 0;
+ int i;
+
+ count += scnprintf(buf + count, len - count,
+ "===================\n");
+ for (i = 0 ; i < FSM_STATE_MAX; i++) {
+ param = &conditions[i];
+ count += scnprintf(buf + count, len - count,
+ "state: %d, ac_mask: %#0X\n", i, param->ac_mask);
+ count += scnprintf(buf + count, len - count,
+ "min_tp_threshold: %u\n", param->min_tp_threshold);
+ count += scnprintf(buf + count, len - count,
+ "max_tp_threshold: %u\n", param->max_tp_threshold);
+ count += scnprintf(buf + count, len - count,
+ "===================\n");
+ }
+ return count;
+}
+
+#define SCENE_PARAM_BUF_SIZE 1024
+static ssize_t scene_params_read(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ char *buf;
+ int len;
+ int ret;
+
+ buf = vmalloc(SCENE_PARAM_BUF_SIZE);
+ if (!buf)
+ return -ENOMEM;
+ len = _scene_params_read(buf, SCENE_PARAM_BUF_SIZE);
+ ret = simple_read_from_buffer(userbuf, count, ppos, buf, len);
+ vfree(buf);
+ return ret;
+}
+
+static const struct file_operations scene_params_ops = {
+ .open = simple_open,
+ .read = scene_params_read,
+ .write = scene_params_write,
+ .llseek = generic_file_llseek,
+};
+
+static int scene_debugfs_init(struct wlan_ptracker_core *core)
+{
+ struct wlan_ptracker_debugfs *debugfs = &core->debugfs;
+ struct wlan_ptracker_fsm *fsm = &core->fsm;
+
+ fsm->dir = debugfs_create_dir("scene", debugfs->root);
+ if (!fsm->dir)
+ return -ENODEV;
+
+ debugfs_create_file("scene_params", 0600, fsm->dir, core, &scene_params_ops);
+ debugfs_create_u32("state", 0600, fsm->dir, &fsm->state);
+ debugfs_create_u32("min_tput", 0600, fsm->dir, &fsm->min_tput);
+ debugfs_create_u32("max_tput", 0600, fsm->dir, &fsm->max_tput);
+ debugfs_create_u32("ac_mask", 0600, fsm->dir, &fsm->ac_mask);
+ return 0;
+}
+
int scenes_fsm_init(struct wlan_ptracker_fsm *fsm)
{
struct wlan_scene_event *msg = &fsm->msg;
@@ -221,6 +317,7 @@ int scenes_fsm_init(struct wlan_ptracker_fsm *fsm)
msg->src = WLAN_SCENE_IDLE;
msg->state = WLAN_SCENE_IDLE;
mutex_init(&msg->lock);
+ scene_debugfs_init(core);
/*scene event notifier handler from client */
ret = wlan_ptracker_register_notifier(&core->notifier, &scene_nb);
@@ -236,6 +333,7 @@ int scenes_fsm_init(struct wlan_ptracker_fsm *fsm)
ptracker_err(core, "unable to start kernel thread %d\n", ret);
return ret;
}
+ fsm->thread_run = true;
wake_up_process(fsm->fsm_thread);
return 0;
}
@@ -244,15 +342,18 @@ void scenes_fsm_exit(struct wlan_ptracker_fsm *fsm)
{
struct wlan_ptracker_core *core = fsm_to_core(fsm);
+ if (fsm->dir)
+ debugfs_remove_recursive(fsm->dir);
+
wlan_ptracker_unregister_notifier(&core->notifier, &scene_nb);
+ fsm->thread_run = false;
+ complete(&fsm->event);
if (fsm->fsm_thread) {
int ret = kthread_stop(fsm->fsm_thread);
fsm->fsm_thread = NULL;
if (ret)
ptracker_err(core, "stop thread fail: %d\n", ret);
}
- complete(&fsm->event);
fsm->conditions = NULL;
fsm->reset_cnt = 0;
}
-