wil6210: manual FW error recovery mode
Introduce manual FW recovery mode. It is activated if module parameter @no_fw_recovery set to true. May be changed at runtime. Recovery information provided by new "recovery" debugfs file. It prints: mode = [auto|manual] state = [idle|pending|running] In manual mode, after FW error, recovery won't start automatically. Instead, after notification to user space, recovery waits in "pending" state, as indicated by the "recovery" debugfs file. User space tools may perform data collection and allow to continue recovery by writing "run" to the "recovery" debugfs file. Alternatively, recovery pending may be canceled by stopping network interface i.e. 'ifconfig wlan0 down' Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:

committed by
John W. Linville

parent
e6664dff06
commit
c33407a8c5
@@ -1041,6 +1041,71 @@ static const struct file_operations fops_info = {
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
|
||||
/*---------recovery------------*/
|
||||
/* mode = [manual|auto]
|
||||
* state = [idle|pending|running]
|
||||
*/
|
||||
static ssize_t wil_read_file_recovery(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct wil6210_priv *wil = file->private_data;
|
||||
char buf[80];
|
||||
int n;
|
||||
static const char * const sstate[] = {"idle", "pending", "running"};
|
||||
|
||||
n = snprintf(buf, sizeof(buf), "mode = %s\nstate = %s\n",
|
||||
no_fw_recovery ? "manual" : "auto",
|
||||
sstate[wil->recovery_state]);
|
||||
|
||||
n = min_t(int, n, sizeof(buf));
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos,
|
||||
buf, n);
|
||||
}
|
||||
|
||||
static ssize_t wil_write_file_recovery(struct file *file,
|
||||
const char __user *buf_,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct wil6210_priv *wil = file->private_data;
|
||||
static const char run_command[] = "run";
|
||||
char buf[sizeof(run_command) + 1]; /* to detect "runx" */
|
||||
ssize_t rc;
|
||||
|
||||
if (wil->recovery_state != fw_recovery_pending) {
|
||||
wil_err(wil, "No recovery pending\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (*ppos != 0) {
|
||||
wil_err(wil, "Offset [%d]\n", (int)*ppos);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (count > sizeof(buf)) {
|
||||
wil_err(wil, "Input too long, len = %d\n", (int)count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, buf_, count);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
buf[rc] = '\0';
|
||||
if (0 == strcmp(buf, run_command))
|
||||
wil_set_recovery_state(wil, fw_recovery_running);
|
||||
else
|
||||
wil_err(wil, "Bad recovery command \"%s\"\n", buf);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_recovery = {
|
||||
.read = wil_read_file_recovery,
|
||||
.write = wil_write_file_recovery,
|
||||
.open = simple_open,
|
||||
};
|
||||
|
||||
/*---------Station matrix------------*/
|
||||
static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
|
||||
{
|
||||
@@ -1152,6 +1217,7 @@ static const struct {
|
||||
{"freq", S_IRUGO, &fops_freq},
|
||||
{"link", S_IRUGO, &fops_link},
|
||||
{"info", S_IRUGO, &fops_info},
|
||||
{"recovery", S_IRUGO | S_IWUSR, &fops_recovery},
|
||||
};
|
||||
|
||||
static void wil6210_debugfs_init_files(struct wil6210_priv *wil,
|
||||
@@ -1194,6 +1260,7 @@ static const struct dbg_off dbg_wil_off[] = {
|
||||
WIL_FIELD(status, S_IRUGO | S_IWUSR, doff_ulong),
|
||||
WIL_FIELD(fw_version, S_IRUGO, doff_u32),
|
||||
WIL_FIELD(hw_version, S_IRUGO, doff_x32),
|
||||
WIL_FIELD(recovery_count, S_IRUGO, doff_u32),
|
||||
{},
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user