Skip to content

Commit

Permalink
wifi: mt76: mt7915: add full system reset into debugfs
Browse files Browse the repository at this point in the history
Trigger firmware crash and enable full system recovery through debugfs.
This also renames knob "fw_ser" to a clear-cut name "sys_recovery".

Signed-off-by: Ryder Lee <[email protected]>
Signed-off-by: Felix Fietkau <[email protected]>
  • Loading branch information
ryderlee1110 authored and nbd168 committed Nov 11, 2022
1 parent 1ad31c3 commit 6b0668d
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 14 deletions.
81 changes: 67 additions & 14 deletions mt7915/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_implicit_txbf, mt7915_implicit_txbf_get,

/* test knob of system error recovery */
static ssize_t
mt7915_fw_ser_set(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
mt7915_sys_recovery_set(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct mt7915_phy *phy = file->private_data;
struct mt7915_dev *dev = phy->dev;
Expand All @@ -71,8 +71,18 @@ mt7915_fw_ser_set(struct file *file, const char __user *user_buf,
return -EINVAL;

switch (val) {
/*
* 0: grab firmware current SER state.
* 1: trigger & enable system error L1 recovery.
* 2: trigger & enable system error L2 recovery.
* 3: trigger & enable system error L3 rx abort.
* 4: trigger & enable system error L3 tx abort
* 5: trigger & enable system error L3 tx disable.
* 6: trigger & enable system error L3 bf recovery.
* 7: trigger & enable system error full recovery.
* 8: trigger firmware crash.
*/
case SER_QUERY:
/* grab firmware SER stats */
ret = mt7915_mcu_set_ser(dev, 0, 0, ext_phy);
break;
case SER_SET_RECOVER_L1:
Expand All @@ -87,6 +97,23 @@ mt7915_fw_ser_set(struct file *file, const char __user *user_buf,

ret = mt7915_mcu_set_ser(dev, SER_RECOVER, val, ext_phy);
break;

/* enable full chip reset */
case SER_SET_RECOVER_FULL:
mt76_set(dev, MT_WFDMA0_MCU_HOST_INT_ENA, MT_MCU_CMD_WDT_MASK);
ret = mt7915_mcu_set_ser(dev, 1, 3, ext_phy);
if (ret)
return ret;

dev->recovery.state |= MT_MCU_CMD_WDT_MASK;
mt7915_reset(dev);
break;

/* WARNING: trigger firmware crash */
case SER_SET_SYSTEM_ASSERT:
mt76_wr(dev, MT_MCU_WM_CIRQ_EINT_MASK_CLR_ADDR, BIT(18));
mt76_wr(dev, MT_MCU_WM_CIRQ_EINT_SOFT_ADDR, BIT(18));
break;
default:
break;
}
Expand All @@ -95,20 +122,45 @@ mt7915_fw_ser_set(struct file *file, const char __user *user_buf,
}

static ssize_t
mt7915_fw_ser_get(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
mt7915_sys_recovery_get(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct mt7915_phy *phy = file->private_data;
struct mt7915_dev *dev = phy->dev;
char *buff;
int desc = 0;
ssize_t ret;
static const size_t bufsz = 400;
static const size_t bufsz = 1024;

buff = kmalloc(bufsz, GFP_KERNEL);
if (!buff)
return -ENOMEM;

/* HELP */
desc += scnprintf(buff + desc, bufsz - desc,
"Please echo the correct value ...\n");
desc += scnprintf(buff + desc, bufsz - desc,
"0: grab firmware transient SER state\n");
desc += scnprintf(buff + desc, bufsz - desc,
"1: trigger system error L1 recovery\n");
desc += scnprintf(buff + desc, bufsz - desc,
"2: trigger system error L2 recovery\n");
desc += scnprintf(buff + desc, bufsz - desc,
"3: trigger system error L3 rx abort\n");
desc += scnprintf(buff + desc, bufsz - desc,
"4: trigger system error L3 tx abort\n");
desc += scnprintf(buff + desc, bufsz - desc,
"5: trigger system error L3 tx disable\n");
desc += scnprintf(buff + desc, bufsz - desc,
"6: trigger system error L3 bf recovery\n");
desc += scnprintf(buff + desc, bufsz - desc,
"7: trigger system error full recovery\n");
desc += scnprintf(buff + desc, bufsz - desc,
"8: trigger firmware crash\n");

/* SER statistics */
desc += scnprintf(buff + desc, bufsz - desc,
"\nlet's dump firmware SER statistics...\n");
desc += scnprintf(buff + desc, bufsz - desc,
"::E R , SER_STATUS = 0x%08x\n",
mt76_rr(dev, MT_SWDEF_SER_STATS));
Expand Down Expand Up @@ -139,15 +191,19 @@ mt7915_fw_ser_get(struct file *file, char __user *user_buf,
desc += scnprintf(buff + desc, bufsz - desc,
"::E R , SER_LMAC_WISR7_B1 = 0x%08x\n",
mt76_rr(dev, MT_SWDEF_LAMC_WISR7_BN1_STATS));
desc += scnprintf(buff + desc, bufsz - desc,
"\nSYS_RESET_COUNT: WM %d, WA %d\n",
dev->recovery.wm_reset_count,
dev->recovery.wa_reset_count);

ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
kfree(buff);
return ret;
}

static const struct file_operations mt7915_fw_ser_ops = {
.write = mt7915_fw_ser_set,
.read = mt7915_fw_ser_get,
static const struct file_operations mt7915_sys_recovery_ops = {
.write = mt7915_sys_recovery_set,
.read = mt7915_sys_recovery_get,
.open = simple_open,
.llseek = default_llseek,
};
Expand Down Expand Up @@ -598,10 +654,6 @@ mt7915_fw_util_wm_show(struct seq_file *file, void *data)
struct mt7915_dev *dev = file->private;

seq_printf(file, "Program counter: 0x%x\n", mt76_rr(dev, MT_WM_MCU_PC));
seq_printf(file, "Exception state: 0x%x\n",
is_mt7915(&dev->mt76) ?
(u32)mt76_get_field(dev, MT_FW_EXCEPTION, GENMASK(15, 8)) :
(u32)mt76_get_field(dev, MT_FW_EXCEPTION, GENMASK(7, 0)));

if (dev->fw.debug_wm) {
seq_printf(file, "Busy: %u%% Peak busy: %u%%\n",
Expand Down Expand Up @@ -1009,7 +1061,8 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
debugfs_create_file("xmit-queues", 0400, dir, phy,
&mt7915_xmit_queues_fops);
debugfs_create_file("tx_stats", 0400, dir, phy, &mt7915_tx_stats_fops);
debugfs_create_file("fw_ser", 0600, dir, phy, &mt7915_fw_ser_ops);
debugfs_create_file("sys_recovery", 0600, dir, phy,
&mt7915_sys_recovery_ops);
debugfs_create_file("fw_debug_wm", 0600, dir, dev, &fops_fw_debug_wm);
debugfs_create_file("fw_debug_wa", 0600, dir, dev, &fops_fw_debug_wa);
debugfs_create_file("fw_debug_bin", 0600, dir, dev, &fops_fw_debug_bin);
Expand Down
5 changes: 5 additions & 0 deletions mt7915/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1529,6 +1529,11 @@ void mt7915_mac_reset_work(struct work_struct *work)
mt76_clear(dev, MT_WFDMA0_MCU_HOST_INT_ENA,
MT_MCU_CMD_WDT_MASK);

if (READ_ONCE(dev->recovery.state) & MT_MCU_CMD_WA_WDT)
dev->recovery.wa_reset_count++;
else
dev->recovery.wm_reset_count++;

mt7915_mac_full_reset(dev);

/* enable mcu irq */
Expand Down
2 changes: 2 additions & 0 deletions mt7915/mcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ enum {
SER_SET_RECOVER_L3_TX_ABORT,
SER_SET_RECOVER_L3_TX_DISABLE,
SER_SET_RECOVER_L3_BF,
SER_SET_RECOVER_FULL,
SER_SET_SYSTEM_ASSERT,
/* action */
SER_ENABLE = 2,
SER_RECOVER
Expand Down
2 changes: 2 additions & 0 deletions mt7915/mt7915.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ struct mt7915_dev {

struct {
u32 state;
u32 wa_reset_count;
u32 wm_reset_count;
bool hw_full_reset:1;
bool hw_init_done:1;
bool restart:1;
Expand Down
4 changes: 4 additions & 0 deletions mt7915/regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,8 @@ enum offs_rev {
#define MT_MCU_CMD_NORMAL_STATE BIT(5)
#define MT_MCU_CMD_ERROR_MASK GENMASK(5, 1)

#define MT_MCU_CMD_WA_WDT BIT(31)
#define MT_MCU_CMD_WM_WDT BIT(30)
#define MT_MCU_CMD_WDT_MASK GENMASK(31, 30)

/* TOP RGU */
Expand Down Expand Up @@ -1151,5 +1153,7 @@ enum offs_rev {
#define MT_MCU_WM_CIRQ(ofs) (MT_MCU_WM_CIRQ_BASE + (ofs))
#define MT_MCU_WM_CIRQ_IRQ_MASK_CLR_ADDR MT_MCU_WM_CIRQ(0x80)
#define MT_MCU_WM_CIRQ_IRQ_SOFT_ADDR MT_MCU_WM_CIRQ(0xc0)
#define MT_MCU_WM_CIRQ_EINT_MASK_CLR_ADDR MT_MCU_WM_CIRQ(0x108)
#define MT_MCU_WM_CIRQ_EINT_SOFT_ADDR MT_MCU_WM_CIRQ(0x118)

#endif

0 comments on commit 6b0668d

Please sign in to comment.