// SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "core.h" #include "debugfs.h" #include "debugfs_htt_stats.h" static ssize_t ath12k_write_simulate_radar(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct ath12k *ar = file->private_data; int ret; mutex_lock(&ar->conf_mutex); ret = ath12k_wmi_simulate_radar(ar); if (ret) goto exit; ret = count; exit: mutex_unlock(&ar->conf_mutex); return ret; } static const struct file_operations fops_simulate_radar = { .write = ath12k_write_simulate_radar, .open = simple_open }; void ath12k_debugfs_soc_create(struct ath12k_base *ab) { bool dput_needed; char soc_name[64] = { 0 }; struct dentry *debugfs_ath12k; debugfs_ath12k = debugfs_lookup("ath12k", NULL); if (debugfs_ath12k) { /* a dentry from lookup() needs dput() after we don't use it */ dput_needed = true; } else { debugfs_ath12k = debugfs_create_dir("ath12k", NULL); if (IS_ERR_OR_NULL(debugfs_ath12k)) return; dput_needed = false; } scnprintf(soc_name, sizeof(soc_name), "%s-%s", ath12k_bus_str(ab->hif.bus), dev_name(ab->dev)); ab->debugfs_soc = debugfs_create_dir(soc_name, debugfs_ath12k); if (dput_needed) dput(debugfs_ath12k); } void ath12k_debugfs_soc_destroy(struct ath12k_base *ab) { debugfs_remove_recursive(ab->debugfs_soc); ab->debugfs_soc = NULL; /* We are not removing ath12k directory on purpose, even if it * would be empty. This simplifies the directory handling and it's * a minor cosmetic issue to leave an empty ath12k directory to * debugfs. */ } void ath12k_debugfs_register(struct ath12k *ar) { struct ath12k_base *ab = ar->ab; struct ieee80211_hw *hw = ar->ah->hw; char pdev_name[5]; char buf[100] = {0}; scnprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx); ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc); /* Create a symlink under ieee80211/phy* */ scnprintf(buf, sizeof(buf), "../../ath12k/%pd2", ar->debug.debugfs_pdev); ar->debug.debugfs_pdev_symlink = debugfs_create_symlink("ath12k", hw->wiphy->debugfsdir, buf); if (ar->mac.sbands[NL80211_BAND_5GHZ].channels) { debugfs_create_file("dfs_simulate_radar", 0200, ar->debug.debugfs_pdev, ar, &fops_simulate_radar); } ath12k_debugfs_htt_stats_register(ar); } void ath12k_debugfs_unregister(struct ath12k *ar) { if (!ar->debug.debugfs_pdev) return; /* Remove symlink under ieee80211/phy* */ debugfs_remove(ar->debug.debugfs_pdev_symlink); debugfs_remove_recursive(ar->debug.debugfs_pdev); ar->debug.debugfs_pdev_symlink = NULL; ar->debug.debugfs_pdev = NULL; }