]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
ath10k: add debugfs file warm_hw_reset
authorMaharaja Kennadyrajan <mkenna@codeaurora.org>
Wed, 18 Jul 2018 13:34:20 +0000 (19:04 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 30 Jul 2018 17:59:32 +0000 (20:59 +0300)
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>
drivers/net/wireless/ath/ath10k/debug.c
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath10k/wmi.h

index 4926722e0c0d3333cf5a93bdbce747c6cbbef6cf..0baaad90b8d18708ae2058076e04c1f5627128e2 100644 (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;
 }
 
index 6d20baf5ae5cfc7811806d2eca7b8bd0abaace0a..fd612d2905b055f5654019a5ee6b3d4820ad1086 100644 (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,
index 2c96380d80215badd3149d03b515f7cc871f79e8..36220258e3c7e686af0ffb5a2ab82869b8be5b01 100644 (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,