Commit 8c656992 authored by Marek Puzyniak's avatar Marek Puzyniak Committed by Kalle Valo

ath10k: add soft/hard firmware crash option to simulate_fw_crash

Command WMI_FORCE_FW_HANG_CMDID is not supported in firmware 10.1.
In order to have firmware crash simulation functionality also
in firmware 10.1 driver can force firmware crash by performing not allowed
operation. Driver can deliberately crash firmware when setting vdev param for
vdev id out of range.  This patch introduces two keywords to simulate_fw_crash:

'soft' which will cause firmware crash that is recoverable
       by warm firmware reset but supported only in main firmware.
'hard' which will cause firmware crash recoverable by cold
       firmware reset, this option works for both firmwares.

Commands to trigger firmware soft/hard crash:

echo 'soft' > /sys/kernel/debug/ieee80211/phyX/ath10k/simulate_fw_crash
echo 'hard' > /sys/kernel/debug/ieee80211/phyX/ath10k/simulate_fw_crash

kvalo: remove '\n' before checking the command and simplify how buf is null
terminated
Signed-off-by: default avatarMarek Puzyniak <marek.puzyniak@tieto.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent e8dc1a96
...@@ -451,27 +451,37 @@ static ssize_t ath10k_read_simulate_fw_crash(struct file *file, ...@@ -451,27 +451,37 @@ static ssize_t ath10k_read_simulate_fw_crash(struct file *file,
char __user *user_buf, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
const char buf[] = "To simulate firmware crash write the keyword" const char buf[] = "To simulate firmware crash write one of the"
" `crash` to this file.\nThis will force firmware" " keywords to this file:\n `soft` - this will send"
" to report a crash to the host system.\n"; " WMI_FORCE_FW_HANG_ASSERT to firmware if FW"
" supports that command.\n `hard` - this will send"
" to firmware command with illegal parameters"
" causing firmware crash.\n";
return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
} }
/* Simulate firmware crash:
* 'soft': Call wmi command causing firmware hang. This firmware hang is
* recoverable by warm firmware reset.
* 'hard': Force firmware crash by setting any vdev parameter for not allowed
* vdev id. This is hard firmware crash because it is recoverable only by cold
* firmware reset.
*/
static ssize_t ath10k_write_simulate_fw_crash(struct file *file, static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
const char __user *user_buf, const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct ath10k *ar = file->private_data; struct ath10k *ar = file->private_data;
char buf[32] = {}; char buf[32];
int ret; int ret;
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
if (strcmp(buf, "crash") && strcmp(buf, "crash\n")) {
ret = -EINVAL; /* make sure that buf is null terminated */
goto exit; buf[sizeof(buf) - 1] = 0;
}
if (ar->state != ATH10K_STATE_ON && if (ar->state != ATH10K_STATE_ON &&
ar->state != ATH10K_STATE_RESTARTED) { ar->state != ATH10K_STATE_RESTARTED) {
...@@ -479,13 +489,29 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file, ...@@ -479,13 +489,29 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
goto exit; goto exit;
} }
ath10k_info("simulating firmware crash\n"); /* drop the possible '\n' from the end */
if (buf[count - 1] == '\n') {
buf[count - 1] = 0;
count--;
}
if (!strcmp(buf, "soft")) {
ath10k_info("simulating soft firmware crash\n");
ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0); ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0);
if (ret) } else if (!strcmp(buf, "hard")) {
ath10k_warn("failed to force fw hang (%d)\n", ret); ath10k_info("simulating hard firmware crash\n");
ret = ath10k_wmi_vdev_set_param(ar, TARGET_NUM_VDEVS + 1,
ar->wmi.vdev_param->rts_threshold, 0);
} else {
ret = -EINVAL;
goto exit;
}
if (ret) {
ath10k_warn("failed to simulate firmware crash: %d\n", ret);
goto exit;
}
if (ret == 0)
ret = count; ret = count;
exit: exit:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment