1// SPDX-License-Identifier: ISC 2 3#include "mt7615.h" 4 5static int 6mt7615_radar_pattern_set(void *data, u64 val) 7{ 8 struct mt7615_dev *dev = data; 9 int err; 10 11 if (!mt7615_wait_for_mcu_init(dev)) 12 return 0; 13 14 mt7615_mutex_acquire(dev); 15 err = mt7615_mcu_rdd_send_pattern(dev); 16 mt7615_mutex_release(dev); 17 18 return err; 19} 20 21DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL, 22 mt7615_radar_pattern_set, "%lld\n"); 23 24static int 25mt7615_scs_set(void *data, u64 val) 26{ 27 struct mt7615_dev *dev = data; 28 struct mt7615_phy *ext_phy; 29 30 if (!mt7615_wait_for_mcu_init(dev)) 31 return 0; 32 33 mt7615_mac_set_scs(&dev->phy, val); 34 ext_phy = mt7615_ext_phy(dev); 35 if (ext_phy) 36 mt7615_mac_set_scs(ext_phy, val); 37 38 return 0; 39} 40 41static int 42mt7615_scs_get(void *data, u64 *val) 43{ 44 struct mt7615_dev *dev = data; 45 46 *val = dev->phy.scs_en; 47 48 return 0; 49} 50 51DEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get, 52 mt7615_scs_set, "%lld\n"); 53 54static int 55mt7615_pm_set(void *data, u64 val) 56{ 57 struct mt7615_dev *dev = data; 58 59 if (!mt7615_wait_for_mcu_init(dev)) 60 return 0; 61 62 return mt7615_pm_set_enable(dev, val); 63} 64 65static int 66mt7615_pm_get(void *data, u64 *val) 67{ 68 struct mt7615_dev *dev = data; 69 70 *val = dev->pm.enable; 71 72 return 0; 73} 74 75DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7615_pm_get, mt7615_pm_set, "%lld\n"); 76 77static int 78mt7615_pm_idle_timeout_set(void *data, u64 val) 79{ 80 struct mt7615_dev *dev = data; 81 82 dev->pm.idle_timeout = msecs_to_jiffies(val); 83 84 return 0; 85} 86 87static int 88mt7615_pm_idle_timeout_get(void *data, u64 *val) 89{ 90 struct mt7615_dev *dev = data; 91 92 *val = jiffies_to_msecs(dev->pm.idle_timeout); 93 94 return 0; 95} 96 97DEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt7615_pm_idle_timeout_get, 98 mt7615_pm_idle_timeout_set, "%lld\n"); 99 100static int 101mt7615_dbdc_set(void *data, u64 val) 102{ 103 struct mt7615_dev *dev = data; 104 105 if (!mt7615_wait_for_mcu_init(dev)) 106 return 0; 107 108 if (val) 109 mt7615_register_ext_phy(dev); 110 else 111 mt7615_unregister_ext_phy(dev); 112 113 return 0; 114} 115 116static int 117mt7615_dbdc_get(void *data, u64 *val) 118{ 119 struct mt7615_dev *dev = data; 120 121 *val = !!mt7615_ext_phy(dev); 122 123 return 0; 124} 125 126DEFINE_DEBUGFS_ATTRIBUTE(fops_dbdc, mt7615_dbdc_get, 127 mt7615_dbdc_set, "%lld\n"); 128 129static int 130mt7615_fw_debug_set(void *data, u64 val) 131{ 132 struct mt7615_dev *dev = data; 133 134 if (!mt7615_wait_for_mcu_init(dev)) 135 return 0; 136 137 dev->fw_debug = val; 138 139 mt7615_mutex_acquire(dev); 140 mt7615_mcu_fw_log_2_host(dev, dev->fw_debug ? 2 : 0); 141 mt7615_mutex_release(dev); 142 143 return 0; 144} 145 146static int 147mt7615_fw_debug_get(void *data, u64 *val) 148{ 149 struct mt7615_dev *dev = data; 150 151 *val = dev->fw_debug; 152 153 return 0; 154} 155 156DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7615_fw_debug_get, 157 mt7615_fw_debug_set, "%lld\n"); 158 159static int 160mt7615_reset_test_set(void *data, u64 val) 161{ 162 struct mt7615_dev *dev = data; 163 struct sk_buff *skb; 164 165 if (!mt7615_wait_for_mcu_init(dev)) 166 return 0; 167 168 skb = alloc_skb(1, GFP_KERNEL); 169 if (!skb) 170 return -ENOMEM; 171 172 skb_put(skb, 1); 173 174 mt7615_mutex_acquire(dev); 175 mt76_tx_queue_skb_raw(dev, 0, skb, 0); 176 mt7615_mutex_release(dev); 177 178 return 0; 179} 180 181DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_test, NULL, 182 mt7615_reset_test_set, "%lld\n"); 183 184static void 185mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy, 186 struct seq_file *file) 187{ 188 struct mt7615_dev *dev = file->private; 189 u32 reg = is_mt7663(&dev->mt76) ? MT_MIB_ARNG(0) : MT_AGG_ASRCR0; 190 bool ext_phy = phy != &dev->phy; 191 int bound[7], i, range; 192 193 if (!phy) 194 return; 195 196 range = mt76_rr(dev, reg); 197 for (i = 0; i < 4; i++) 198 bound[i] = MT_AGG_ASRCR_RANGE(range, i) + 1; 199 200 range = mt76_rr(dev, reg + 4); 201 for (i = 0; i < 3; i++) 202 bound[i + 4] = MT_AGG_ASRCR_RANGE(range, i) + 1; 203 204 seq_printf(file, "\nPhy %d\n", ext_phy); 205 206 seq_printf(file, "Length: %8d | ", bound[0]); 207 for (i = 0; i < ARRAY_SIZE(bound) - 1; i++) 208 seq_printf(file, "%3d -%3d | ", 209 bound[i], bound[i + 1]); 210 seq_puts(file, "\nCount: "); 211 212 range = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0; 213 for (i = 0; i < ARRAY_SIZE(bound); i++) 214 seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i + range]); 215 seq_puts(file, "\n"); 216 217 seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt); 218 seq_printf(file, "PER: %ld.%1ld%%\n", 219 phy->mib.aggr_per / 10, phy->mib.aggr_per % 10); 220} 221 222static int 223mt7615_ampdu_stat_show(struct seq_file *file, void *data) 224{ 225 struct mt7615_dev *dev = file->private; 226 227 mt7615_mutex_acquire(dev); 228 229 mt7615_ampdu_stat_read_phy(&dev->phy, file); 230 mt7615_ampdu_stat_read_phy(mt7615_ext_phy(dev), file); 231 232 mt7615_mutex_release(dev); 233 234 return 0; 235} 236 237DEFINE_SHOW_ATTRIBUTE(mt7615_ampdu_stat); 238 239static void 240mt7615_radio_read_phy(struct mt7615_phy *phy, struct seq_file *s) 241{ 242 struct mt7615_dev *dev = dev_get_drvdata(s->private); 243 bool ext_phy = phy != &dev->phy; 244 245 if (!phy) 246 return; 247 248 seq_printf(s, "Radio %d sensitivity: ofdm=%d cck=%d\n", ext_phy, 249 phy->ofdm_sensitivity, phy->cck_sensitivity); 250 seq_printf(s, "Radio %d false CCA: ofdm=%d cck=%d\n", ext_phy, 251 phy->false_cca_ofdm, phy->false_cca_cck); 252} 253 254static int 255mt7615_radio_read(struct seq_file *s, void *data) 256{ 257 struct mt7615_dev *dev = dev_get_drvdata(s->private); 258 259 mt7615_radio_read_phy(&dev->phy, s); 260 mt7615_radio_read_phy(mt7615_ext_phy(dev), s); 261 262 return 0; 263} 264 265static int mt7615_read_temperature(struct seq_file *s, void *data) 266{ 267 struct mt7615_dev *dev = dev_get_drvdata(s->private); 268 int temp; 269 270 if (!mt7615_wait_for_mcu_init(dev)) 271 return 0; 272 273 /* cpu */ 274 mt7615_mutex_acquire(dev); 275 temp = mt7615_mcu_get_temperature(dev, 0); 276 mt7615_mutex_release(dev); 277 278 seq_printf(s, "Temperature: %d\n", temp); 279 280 return 0; 281} 282 283static int 284mt7615_queues_acq(struct seq_file *s, void *data) 285{ 286 struct mt7615_dev *dev = dev_get_drvdata(s->private); 287 int i; 288 289 mt7615_mutex_acquire(dev); 290 291 for (i = 0; i < 16; i++) { 292 int j, wmm_idx = i % MT7615_MAX_WMM_SETS; 293 int acs = i / MT7615_MAX_WMM_SETS; 294 u32 ctrl, val, qlen = 0; 295 296 val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, wmm_idx)); 297 ctrl = BIT(31) | BIT(15) | (acs << 8); 298 299 for (j = 0; j < 32; j++) { 300 if (val & BIT(j)) 301 continue; 302 303 mt76_wr(dev, MT_PLE_FL_Q0_CTRL, 304 ctrl | (j + (wmm_idx << 5))); 305 qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL, 306 GENMASK(11, 0)); 307 } 308 seq_printf(s, "AC%d%d: queued=%d\n", wmm_idx, acs, qlen); 309 } 310 311 mt7615_mutex_release(dev); 312 313 return 0; 314} 315 316static int 317mt7615_queues_read(struct seq_file *s, void *data) 318{ 319 struct mt7615_dev *dev = dev_get_drvdata(s->private); 320 static const struct { 321 char *queue; 322 int id; 323 } queue_map[] = { 324 { "PDMA0", MT_TXQ_BE }, 325 { "MCUQ", MT_TXQ_MCU }, 326 { "MCUFWQ", MT_TXQ_FWDL }, 327 }; 328 int i; 329 330 for (i = 0; i < ARRAY_SIZE(queue_map); i++) { 331 struct mt76_queue *q = dev->mt76.q_tx[queue_map[i].id]; 332 333 if (!q) 334 continue; 335 336 seq_printf(s, 337 "%s: queued=%d head=%d tail=%d\n", 338 queue_map[i].queue, q->queued, q->head, 339 q->tail); 340 } 341 342 return 0; 343} 344 345static int 346mt7615_rf_reg_set(void *data, u64 val) 347{ 348 struct mt7615_dev *dev = data; 349 350 mt7615_rf_wr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg, val); 351 352 return 0; 353} 354 355static int 356mt7615_rf_reg_get(void *data, u64 *val) 357{ 358 struct mt7615_dev *dev = data; 359 360 *val = mt7615_rf_rr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg); 361 362 return 0; 363} 364 365DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_reg, mt7615_rf_reg_get, mt7615_rf_reg_set, 366 "0x%08llx\n"); 367 368int mt7615_init_debugfs(struct mt7615_dev *dev) 369{ 370 struct dentry *dir; 371 372 dir = mt76_register_debugfs(&dev->mt76); 373 if (!dir) 374 return -ENOMEM; 375 376 if (is_mt7615(&dev->mt76)) 377 debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir, 378 mt7615_queues_read); 379 else 380 debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir, 381 mt76_queues_read); 382 debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir, 383 mt7615_queues_acq); 384 debugfs_create_file("ampdu_stat", 0400, dir, dev, &mt7615_ampdu_stat_fops); 385 debugfs_create_file("scs", 0600, dir, dev, &fops_scs); 386 debugfs_create_file("dbdc", 0600, dir, dev, &fops_dbdc); 387 debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug); 388 debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm); 389 debugfs_create_file("idle-timeout", 0600, dir, dev, 390 &fops_pm_idle_timeout); 391 debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir, 392 mt7615_radio_read); 393 debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern); 394 /* test pattern knobs */ 395 debugfs_create_u8("pattern_len", 0600, dir, 396 &dev->radar_pattern.n_pulses); 397 debugfs_create_u32("pulse_period", 0600, dir, 398 &dev->radar_pattern.period); 399 debugfs_create_u16("pulse_width", 0600, dir, 400 &dev->radar_pattern.width); 401 debugfs_create_u16("pulse_power", 0600, dir, 402 &dev->radar_pattern.power); 403 debugfs_create_file("radar_trigger", 0200, dir, dev, 404 &fops_radar_pattern); 405 debugfs_create_file("reset_test", 0200, dir, dev, 406 &fops_reset_test); 407 debugfs_create_devm_seqfile(dev->mt76.dev, "temperature", dir, 408 mt7615_read_temperature); 409 410 debugfs_create_u32("rf_wfidx", 0600, dir, &dev->debugfs_rf_wf); 411 debugfs_create_u32("rf_regidx", 0600, dir, &dev->debugfs_rf_reg); 412 debugfs_create_file_unsafe("rf_regval", 0600, dir, dev, 413 &fops_rf_reg); 414 415 return 0; 416} 417EXPORT_SYMBOL_GPL(mt7615_init_debugfs); 418