1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 */ 6 7 #include "core.h" 8 #include "debugfs.h" 9 #include "debugfs_htt_stats.h" 10 11 static ssize_t ath12k_write_simulate_radar(struct file *file, 12 const char __user *user_buf, 13 size_t count, loff_t *ppos) 14 { 15 struct ath12k *ar = file->private_data; 16 int ret; 17 18 wiphy_lock(ath12k_ar_to_hw(ar)->wiphy); 19 ret = ath12k_wmi_simulate_radar(ar); 20 if (ret) 21 goto exit; 22 23 ret = count; 24 exit: 25 wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy); 26 return ret; 27 } 28 29 static const struct file_operations fops_simulate_radar = { 30 .write = ath12k_write_simulate_radar, 31 .open = simple_open 32 }; 33 34 void ath12k_debugfs_soc_create(struct ath12k_base *ab) 35 { 36 bool dput_needed; 37 char soc_name[64] = { 0 }; 38 struct dentry *debugfs_ath12k; 39 40 debugfs_ath12k = debugfs_lookup("ath12k", NULL); 41 if (debugfs_ath12k) { 42 /* a dentry from lookup() needs dput() after we don't use it */ 43 dput_needed = true; 44 } else { 45 debugfs_ath12k = debugfs_create_dir("ath12k", NULL); 46 if (IS_ERR_OR_NULL(debugfs_ath12k)) 47 return; 48 dput_needed = false; 49 } 50 51 scnprintf(soc_name, sizeof(soc_name), "%s-%s", ath12k_bus_str(ab->hif.bus), 52 dev_name(ab->dev)); 53 54 ab->debugfs_soc = debugfs_create_dir(soc_name, debugfs_ath12k); 55 56 if (dput_needed) 57 dput(debugfs_ath12k); 58 } 59 60 void ath12k_debugfs_soc_destroy(struct ath12k_base *ab) 61 { 62 debugfs_remove_recursive(ab->debugfs_soc); 63 ab->debugfs_soc = NULL; 64 /* We are not removing ath12k directory on purpose, even if it 65 * would be empty. This simplifies the directory handling and it's 66 * a minor cosmetic issue to leave an empty ath12k directory to 67 * debugfs. 68 */ 69 } 70 71 void ath12k_debugfs_register(struct ath12k *ar) 72 { 73 struct ath12k_base *ab = ar->ab; 74 struct ieee80211_hw *hw = ar->ah->hw; 75 char pdev_name[5]; 76 char buf[100] = {0}; 77 78 scnprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx); 79 80 ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc); 81 82 /* Create a symlink under ieee80211/phy* */ 83 scnprintf(buf, sizeof(buf), "../../ath12k/%pd2", ar->debug.debugfs_pdev); 84 ar->debug.debugfs_pdev_symlink = debugfs_create_symlink("ath12k", 85 hw->wiphy->debugfsdir, 86 buf); 87 88 if (ar->mac.sbands[NL80211_BAND_5GHZ].channels) { 89 debugfs_create_file("dfs_simulate_radar", 0200, 90 ar->debug.debugfs_pdev, ar, 91 &fops_simulate_radar); 92 } 93 94 ath12k_debugfs_htt_stats_register(ar); 95 } 96 97 void ath12k_debugfs_unregister(struct ath12k *ar) 98 { 99 if (!ar->debug.debugfs_pdev) 100 return; 101 102 /* Remove symlink under ieee80211/phy* */ 103 debugfs_remove(ar->debug.debugfs_pdev_symlink); 104 debugfs_remove_recursive(ar->debug.debugfs_pdev); 105 ar->debug.debugfs_pdev_symlink = NULL; 106 ar->debug.debugfs_pdev = NULL; 107 } 108