ath10k: add debugfs file warm_hw_reset

Debugfs support to do hardware warm reset with WMI command
WMI_PDEV_PARAM_PDEV_RESET for 10.4 and 10.2.4(if wmi
service is enabled in the firmware for backward compatibility).

This change is purely for debugging purpose when hardware hangs/mutes.

This hardware reset won't affect the connectivity but there will be small
pause in data traffic. Here we are doing BB/MAC level reset and hence
whenever the BB/MAC watchdog is triggered, it does a hardware_chip_reset.
So the target will be in the active state.

Below command used to warm reset the hardware.
echo 1 > /sys/kernel/debug/ieee80211/phyX/ath10k/warm_hw_reset

Tested in QCA988X with firmware ver 10.2.4.70.45
Tested in QCA4019 with firmware ver 10.4-3.2.1.1-00011

Signed-off-by: Maharaja Kennadyrajan <mkenna@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Maharaja Kennadyrajan 2018-07-18 19:04:20 +05:30 committed by Kalle Valo
parent e82f57c8b9
commit db251d7df4
3 changed files with 65 additions and 2 deletions

View File

@ -2297,6 +2297,52 @@ static const struct file_operations fops_tpc_stats_final = {
.llseek = default_llseek,
};
static ssize_t ath10k_write_warm_hw_reset(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
int ret;
bool val;
if (kstrtobool_from_user(user_buf, count, &val))
return -EFAULT;
if (!val)
return -EINVAL;
mutex_lock(&ar->conf_mutex);
if (ar->state != ATH10K_STATE_ON) {
ret = -ENETDOWN;
goto exit;
}
if (!(test_bit(WMI_SERVICE_RESET_CHIP, ar->wmi.svc_map)))
ath10k_warn(ar, "wmi service for reset chip is not available\n");
ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pdev_reset,
WMI_RST_MODE_WARM_RESET);
if (ret) {
ath10k_warn(ar, "failed to enable warm hw reset: %d\n", ret);
goto exit;
}
ret = count;
exit:
mutex_unlock(&ar->conf_mutex);
return ret;
}
static const struct file_operations fops_warm_hw_reset = {
.write = ath10k_write_warm_hw_reset,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
int ath10k_debug_create(struct ath10k *ar)
{
ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN);
@ -2425,6 +2471,9 @@ int ath10k_debug_register(struct ath10k *ar)
ar->debug.debugfs_phy, ar,
&fops_tpc_stats_final);
debugfs_create_file("warm_hw_reset", 0600, ar->debug.debugfs_phy, ar,
&fops_warm_hw_reset);
return 0;
}

View File

@ -1333,7 +1333,7 @@ static struct wmi_pdev_param_map wmi_10_2_4_pdev_param_map = {
.enable_per_tid_ampdu = WMI_PDEV_PARAM_UNSUPPORTED,
.cca_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
.rts_fixed_rate = WMI_PDEV_PARAM_UNSUPPORTED,
.pdev_reset = WMI_PDEV_PARAM_UNSUPPORTED,
.pdev_reset = WMI_10X_PDEV_PARAM_PDEV_RESET,
.wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED,
.arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED,
.arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED,

View File

@ -462,6 +462,7 @@ static inline char *wmi_service_name(int service_id)
SVCSTR(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS);
SVCSTR(WMI_SERVICE_HOST_DFS_CHECK_SUPPORT);
SVCSTR(WMI_SERVICE_TPC_STATS_FINAL);
SVCSTR(WMI_SERVICE_RESET_CHIP);
default:
return NULL;
}
@ -3934,7 +3935,11 @@ enum wmi_10x_pdev_param {
WMI_10X_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER,
WMI_10X_PDEV_PARAM_PEER_STA_PS_STATECHG_ENABLE,
WMI_10X_PDEV_PARAM_RTS_FIXED_RATE,
WMI_10X_PDEV_PARAM_CAL_PERIOD
WMI_10X_PDEV_PARAM_CAL_PERIOD,
WMI_10X_PDEV_PARAM_ATF_STRICT_SCH,
WMI_10X_PDEV_PARAM_ATF_SCHED_DURATION,
WMI_10X_PDEV_PARAM_SET_PROMISC_MODE_CMDID,
WMI_10X_PDEV_PARAM_PDEV_RESET
};
enum wmi_10_4_pdev_param {
@ -6501,6 +6506,15 @@ struct wmi_force_fw_hang_cmd {
__le32 delay_ms;
} __packed;
enum wmi_pdev_reset_mode_type {
WMI_RST_MODE_TX_FLUSH = 1,
WMI_RST_MODE_WARM_RESET,
WMI_RST_MODE_COLD_RESET,
WMI_RST_MODE_WARM_RESET_RESTORE_CAL,
WMI_RST_MODE_COLD_RESET_RESTORE_CAL,
WMI_RST_MODE_MAX,
};
enum ath10k_dbglog_level {
ATH10K_DBGLOG_LEVEL_VERBOSE = 0,
ATH10K_DBGLOG_LEVEL_INFO = 1,