0001
0002
0003 #include "mt7615.h"
0004
0005 static int
0006 mt7615_reg_set(void *data, u64 val)
0007 {
0008 struct mt7615_dev *dev = data;
0009
0010 mt7615_mutex_acquire(dev);
0011 mt76_wr(dev, dev->mt76.debugfs_reg, val);
0012 mt7615_mutex_release(dev);
0013
0014 return 0;
0015 }
0016
0017 static int
0018 mt7615_reg_get(void *data, u64 *val)
0019 {
0020 struct mt7615_dev *dev = data;
0021
0022 mt7615_mutex_acquire(dev);
0023 *val = mt76_rr(dev, dev->mt76.debugfs_reg);
0024 mt7615_mutex_release(dev);
0025
0026 return 0;
0027 }
0028
0029 DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mt7615_reg_get, mt7615_reg_set,
0030 "0x%08llx\n");
0031
0032 static int
0033 mt7615_radar_pattern_set(void *data, u64 val)
0034 {
0035 struct mt7615_dev *dev = data;
0036 int err;
0037
0038 if (!mt7615_wait_for_mcu_init(dev))
0039 return 0;
0040
0041 mt7615_mutex_acquire(dev);
0042 err = mt7615_mcu_rdd_send_pattern(dev);
0043 mt7615_mutex_release(dev);
0044
0045 return err;
0046 }
0047
0048 DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL,
0049 mt7615_radar_pattern_set, "%lld\n");
0050
0051 static int mt7615_config(void *data, u64 val)
0052 {
0053 struct mt7615_dev *dev = data;
0054 int ret;
0055
0056 mt7615_mutex_acquire(dev);
0057 ret = mt76_connac_mcu_chip_config(&dev->mt76);
0058 mt7615_mutex_release(dev);
0059
0060 return ret;
0061 }
0062
0063 DEFINE_DEBUGFS_ATTRIBUTE(fops_config, NULL, mt7615_config, "%lld\n");
0064
0065 static int
0066 mt7615_scs_set(void *data, u64 val)
0067 {
0068 struct mt7615_dev *dev = data;
0069 struct mt7615_phy *ext_phy;
0070
0071 if (!mt7615_wait_for_mcu_init(dev))
0072 return 0;
0073
0074 mt7615_mac_set_scs(&dev->phy, val);
0075 ext_phy = mt7615_ext_phy(dev);
0076 if (ext_phy)
0077 mt7615_mac_set_scs(ext_phy, val);
0078
0079 return 0;
0080 }
0081
0082 static int
0083 mt7615_scs_get(void *data, u64 *val)
0084 {
0085 struct mt7615_dev *dev = data;
0086
0087 *val = dev->phy.scs_en;
0088
0089 return 0;
0090 }
0091
0092 DEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get,
0093 mt7615_scs_set, "%lld\n");
0094
0095 static int
0096 mt7615_pm_set(void *data, u64 val)
0097 {
0098 struct mt7615_dev *dev = data;
0099 struct mt76_connac_pm *pm = &dev->pm;
0100 int ret = 0;
0101
0102 if (!mt7615_wait_for_mcu_init(dev))
0103 return 0;
0104
0105 if (!mt7615_firmware_offload(dev) || mt76_is_usb(&dev->mt76))
0106 return -EOPNOTSUPP;
0107
0108 mutex_lock(&dev->mt76.mutex);
0109
0110 if (val == pm->enable)
0111 goto out;
0112
0113 if (dev->phy.n_beacon_vif) {
0114 ret = -EBUSY;
0115 goto out;
0116 }
0117
0118 if (!pm->enable) {
0119 pm->stats.last_wake_event = jiffies;
0120 pm->stats.last_doze_event = jiffies;
0121 }
0122
0123
0124
0125 pm->enable = false;
0126 mt76_connac_pm_wake(&dev->mphy, pm);
0127
0128 pm->enable = val;
0129 mt76_connac_power_save_sched(&dev->mphy, pm);
0130 out:
0131 mutex_unlock(&dev->mt76.mutex);
0132
0133 return ret;
0134 }
0135
0136 static int
0137 mt7615_pm_get(void *data, u64 *val)
0138 {
0139 struct mt7615_dev *dev = data;
0140
0141 *val = dev->pm.enable;
0142
0143 return 0;
0144 }
0145
0146 DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7615_pm_get, mt7615_pm_set, "%lld\n");
0147
0148 static int
0149 mt7615_pm_stats(struct seq_file *s, void *data)
0150 {
0151 struct mt7615_dev *dev = dev_get_drvdata(s->private);
0152 struct mt76_connac_pm *pm = &dev->pm;
0153 unsigned long awake_time = pm->stats.awake_time;
0154 unsigned long doze_time = pm->stats.doze_time;
0155
0156 if (!test_bit(MT76_STATE_PM, &dev->mphy.state))
0157 awake_time += jiffies - pm->stats.last_wake_event;
0158 else
0159 doze_time += jiffies - pm->stats.last_doze_event;
0160
0161 seq_printf(s, "awake time: %14u\ndoze time: %15u\n",
0162 jiffies_to_msecs(awake_time),
0163 jiffies_to_msecs(doze_time));
0164
0165 return 0;
0166 }
0167
0168 static int
0169 mt7615_pm_idle_timeout_set(void *data, u64 val)
0170 {
0171 struct mt7615_dev *dev = data;
0172
0173 dev->pm.idle_timeout = msecs_to_jiffies(val);
0174
0175 return 0;
0176 }
0177
0178 static int
0179 mt7615_pm_idle_timeout_get(void *data, u64 *val)
0180 {
0181 struct mt7615_dev *dev = data;
0182
0183 *val = jiffies_to_msecs(dev->pm.idle_timeout);
0184
0185 return 0;
0186 }
0187
0188 DEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt7615_pm_idle_timeout_get,
0189 mt7615_pm_idle_timeout_set, "%lld\n");
0190
0191 static int
0192 mt7615_dbdc_set(void *data, u64 val)
0193 {
0194 struct mt7615_dev *dev = data;
0195
0196 if (!mt7615_wait_for_mcu_init(dev))
0197 return 0;
0198
0199 if (val)
0200 mt7615_register_ext_phy(dev);
0201 else
0202 mt7615_unregister_ext_phy(dev);
0203
0204 return 0;
0205 }
0206
0207 static int
0208 mt7615_dbdc_get(void *data, u64 *val)
0209 {
0210 struct mt7615_dev *dev = data;
0211
0212 *val = !!mt7615_ext_phy(dev);
0213
0214 return 0;
0215 }
0216
0217 DEFINE_DEBUGFS_ATTRIBUTE(fops_dbdc, mt7615_dbdc_get,
0218 mt7615_dbdc_set, "%lld\n");
0219
0220 static int
0221 mt7615_fw_debug_set(void *data, u64 val)
0222 {
0223 struct mt7615_dev *dev = data;
0224
0225 if (!mt7615_wait_for_mcu_init(dev))
0226 return 0;
0227
0228 dev->fw_debug = val;
0229
0230 mt7615_mutex_acquire(dev);
0231 mt7615_mcu_fw_log_2_host(dev, dev->fw_debug ? 2 : 0);
0232 mt7615_mutex_release(dev);
0233
0234 return 0;
0235 }
0236
0237 static int
0238 mt7615_fw_debug_get(void *data, u64 *val)
0239 {
0240 struct mt7615_dev *dev = data;
0241
0242 *val = dev->fw_debug;
0243
0244 return 0;
0245 }
0246
0247 DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7615_fw_debug_get,
0248 mt7615_fw_debug_set, "%lld\n");
0249
0250 static int
0251 mt7615_reset_test_set(void *data, u64 val)
0252 {
0253 struct mt7615_dev *dev = data;
0254 struct sk_buff *skb;
0255
0256 if (!mt7615_wait_for_mcu_init(dev))
0257 return 0;
0258
0259 skb = alloc_skb(1, GFP_KERNEL);
0260 if (!skb)
0261 return -ENOMEM;
0262
0263 skb_put(skb, 1);
0264
0265 mt7615_mutex_acquire(dev);
0266 mt76_tx_queue_skb_raw(dev, dev->mphy.q_tx[0], skb, 0);
0267 mt7615_mutex_release(dev);
0268
0269 return 0;
0270 }
0271
0272 DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_test, NULL,
0273 mt7615_reset_test_set, "%lld\n");
0274
0275 static void
0276 mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy,
0277 struct seq_file *file)
0278 {
0279 struct mt7615_dev *dev = file->private;
0280 u32 reg = is_mt7663(&dev->mt76) ? MT_MIB_ARNG(0) : MT_AGG_ASRCR0;
0281 bool ext_phy = phy != &dev->phy;
0282 int bound[7], i, range;
0283
0284 if (!phy)
0285 return;
0286
0287 range = mt76_rr(dev, reg);
0288 for (i = 0; i < 4; i++)
0289 bound[i] = MT_AGG_ASRCR_RANGE(range, i) + 1;
0290
0291 range = mt76_rr(dev, reg + 4);
0292 for (i = 0; i < 3; i++)
0293 bound[i + 4] = MT_AGG_ASRCR_RANGE(range, i) + 1;
0294
0295 seq_printf(file, "\nPhy %d\n", ext_phy);
0296
0297 seq_printf(file, "Length: %8d | ", bound[0]);
0298 for (i = 0; i < ARRAY_SIZE(bound) - 1; i++)
0299 seq_printf(file, "%3d -%3d | ",
0300 bound[i], bound[i + 1]);
0301 seq_puts(file, "\nCount: ");
0302
0303 range = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
0304 for (i = 0; i < ARRAY_SIZE(bound); i++)
0305 seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i + range]);
0306 seq_puts(file, "\n");
0307
0308 seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt);
0309 seq_printf(file, "PER: %ld.%1ld%%\n",
0310 phy->mib.aggr_per / 10, phy->mib.aggr_per % 10);
0311 }
0312
0313 static int
0314 mt7615_ampdu_stat_show(struct seq_file *file, void *data)
0315 {
0316 struct mt7615_dev *dev = file->private;
0317
0318 mt7615_mutex_acquire(dev);
0319
0320 mt7615_ampdu_stat_read_phy(&dev->phy, file);
0321 mt7615_ampdu_stat_read_phy(mt7615_ext_phy(dev), file);
0322
0323 mt7615_mutex_release(dev);
0324
0325 return 0;
0326 }
0327
0328 DEFINE_SHOW_ATTRIBUTE(mt7615_ampdu_stat);
0329
0330 static void
0331 mt7615_radio_read_phy(struct mt7615_phy *phy, struct seq_file *s)
0332 {
0333 struct mt7615_dev *dev = dev_get_drvdata(s->private);
0334 bool ext_phy = phy != &dev->phy;
0335
0336 if (!phy)
0337 return;
0338
0339 seq_printf(s, "Radio %d sensitivity: ofdm=%d cck=%d\n", ext_phy,
0340 phy->ofdm_sensitivity, phy->cck_sensitivity);
0341 seq_printf(s, "Radio %d false CCA: ofdm=%d cck=%d\n", ext_phy,
0342 phy->false_cca_ofdm, phy->false_cca_cck);
0343 }
0344
0345 static int
0346 mt7615_radio_read(struct seq_file *s, void *data)
0347 {
0348 struct mt7615_dev *dev = dev_get_drvdata(s->private);
0349
0350 mt7615_radio_read_phy(&dev->phy, s);
0351 mt7615_radio_read_phy(mt7615_ext_phy(dev), s);
0352
0353 return 0;
0354 }
0355
0356 static int
0357 mt7615_queues_acq(struct seq_file *s, void *data)
0358 {
0359 struct mt7615_dev *dev = dev_get_drvdata(s->private);
0360 int i;
0361
0362 mt7615_mutex_acquire(dev);
0363
0364 for (i = 0; i < 16; i++) {
0365 int j, wmm_idx = i % MT7615_MAX_WMM_SETS;
0366 int acs = i / MT7615_MAX_WMM_SETS;
0367 u32 ctrl, val, qlen = 0;
0368
0369 if (wmm_idx == 3 && is_mt7663(&dev->mt76))
0370 continue;
0371
0372 val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, wmm_idx));
0373 ctrl = BIT(31) | BIT(15) | (acs << 8);
0374
0375 for (j = 0; j < 32; j++) {
0376 if (val & BIT(j))
0377 continue;
0378
0379 mt76_wr(dev, MT_PLE_FL_Q0_CTRL,
0380 ctrl | (j + (wmm_idx << 5)));
0381 qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL,
0382 GENMASK(11, 0));
0383 }
0384 seq_printf(s, "AC%d%d: queued=%d\n", wmm_idx, acs, qlen);
0385 }
0386
0387 mt7615_mutex_release(dev);
0388
0389 return 0;
0390 }
0391
0392 static int
0393 mt7615_queues_read(struct seq_file *s, void *data)
0394 {
0395 struct mt7615_dev *dev = dev_get_drvdata(s->private);
0396 struct {
0397 struct mt76_queue *q;
0398 char *queue;
0399 } queue_map[] = {
0400 { dev->mphy.q_tx[MT_TXQ_BE], "PDMA0" },
0401 { dev->mt76.q_mcu[MT_MCUQ_WM], "MCUQ" },
0402 { dev->mt76.q_mcu[MT_MCUQ_FWDL], "MCUFWQ" },
0403 };
0404 int i;
0405
0406 for (i = 0; i < ARRAY_SIZE(queue_map); i++) {
0407 struct mt76_queue *q = queue_map[i].q;
0408
0409 seq_printf(s,
0410 "%s: queued=%d head=%d tail=%d\n",
0411 queue_map[i].queue, q->queued, q->head,
0412 q->tail);
0413 }
0414
0415 return 0;
0416 }
0417
0418 static int
0419 mt7615_rf_reg_set(void *data, u64 val)
0420 {
0421 struct mt7615_dev *dev = data;
0422
0423 mt7615_rf_wr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg, val);
0424
0425 return 0;
0426 }
0427
0428 static int
0429 mt7615_rf_reg_get(void *data, u64 *val)
0430 {
0431 struct mt7615_dev *dev = data;
0432
0433 *val = mt7615_rf_rr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg);
0434
0435 return 0;
0436 }
0437
0438 DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_reg, mt7615_rf_reg_get, mt7615_rf_reg_set,
0439 "0x%08llx\n");
0440
0441 static ssize_t
0442 mt7615_ext_mac_addr_read(struct file *file, char __user *userbuf,
0443 size_t count, loff_t *ppos)
0444 {
0445 struct mt7615_dev *dev = file->private_data;
0446 u32 len = 32 * ((ETH_ALEN * 3) + 4) + 1;
0447 u8 addr[ETH_ALEN];
0448 char *buf;
0449 int ofs = 0;
0450 int i;
0451
0452 buf = kzalloc(len, GFP_KERNEL);
0453 if (!buf)
0454 return -ENOMEM;
0455
0456 for (i = 0; i < 32; i++) {
0457 if (!(dev->muar_mask & BIT(i)))
0458 continue;
0459
0460 mt76_wr(dev, MT_WF_RMAC_MAR1,
0461 FIELD_PREP(MT_WF_RMAC_MAR1_IDX, i * 2) |
0462 MT_WF_RMAC_MAR1_START);
0463 put_unaligned_le32(mt76_rr(dev, MT_WF_RMAC_MAR0), addr);
0464 put_unaligned_le16((mt76_rr(dev, MT_WF_RMAC_MAR1) &
0465 MT_WF_RMAC_MAR1_ADDR), addr + 4);
0466 ofs += snprintf(buf + ofs, len - ofs, "%d=%pM\n", i, addr);
0467 }
0468
0469 ofs = simple_read_from_buffer(userbuf, count, ppos, buf, ofs);
0470
0471 kfree(buf);
0472 return ofs;
0473 }
0474
0475 static ssize_t
0476 mt7615_ext_mac_addr_write(struct file *file, const char __user *userbuf,
0477 size_t count, loff_t *ppos)
0478 {
0479 struct mt7615_dev *dev = file->private_data;
0480 unsigned long idx = 0;
0481 u8 addr[ETH_ALEN];
0482 char buf[32];
0483 char *p;
0484
0485 if (count > sizeof(buf))
0486 return -EINVAL;
0487
0488 if (copy_from_user(buf, userbuf, count))
0489 return -EFAULT;
0490
0491 buf[sizeof(buf) - 1] = '\0';
0492
0493 p = strchr(buf, '=');
0494 if (p) {
0495 *p = 0;
0496 p++;
0497
0498 if (kstrtoul(buf, 0, &idx) || idx > 31)
0499 return -EINVAL;
0500 } else {
0501 idx = 0;
0502 p = buf;
0503 }
0504
0505 if (!mac_pton(p, addr))
0506 return -EINVAL;
0507
0508 if (is_valid_ether_addr(addr)) {
0509 dev->muar_mask |= BIT(idx);
0510 } else {
0511 memset(addr, 0, sizeof(addr));
0512 dev->muar_mask &= ~BIT(idx);
0513 }
0514
0515 mt76_rmw_field(dev, MT_WF_RMAC_MORE(0), MT_WF_RMAC_MORE_MUAR_MODE, 1);
0516 mt76_wr(dev, MT_WF_RMAC_MAR0, get_unaligned_le32(addr));
0517 mt76_wr(dev, MT_WF_RMAC_MAR1,
0518 get_unaligned_le16(addr + 4) |
0519 FIELD_PREP(MT_WF_RMAC_MAR1_IDX, idx * 2) |
0520 MT_WF_RMAC_MAR1_START |
0521 MT_WF_RMAC_MAR1_WRITE);
0522
0523 mt76_rmw_field(dev, MT_WF_RMAC_MORE(0), MT_WF_RMAC_MORE_MUAR_MODE, !!dev->muar_mask);
0524
0525 return count;
0526 }
0527
0528 static const struct file_operations fops_ext_mac_addr = {
0529 .open = simple_open,
0530 .llseek = generic_file_llseek,
0531 .read = mt7615_ext_mac_addr_read,
0532 .write = mt7615_ext_mac_addr_write,
0533 .owner = THIS_MODULE,
0534 };
0535
0536 static int
0537 mt7663s_sched_quota_read(struct seq_file *s, void *data)
0538 {
0539 struct mt7615_dev *dev = dev_get_drvdata(s->private);
0540 struct mt76_sdio *sdio = &dev->mt76.sdio;
0541
0542 seq_printf(s, "pse_data_quota\t%d\n", sdio->sched.pse_data_quota);
0543 seq_printf(s, "ple_data_quota\t%d\n", sdio->sched.ple_data_quota);
0544 seq_printf(s, "pse_mcu_quota\t%d\n", sdio->sched.pse_mcu_quota);
0545 seq_printf(s, "sched_deficit\t%d\n", sdio->sched.deficit);
0546
0547 return 0;
0548 }
0549
0550 int mt7615_init_debugfs(struct mt7615_dev *dev)
0551 {
0552 struct dentry *dir;
0553
0554 dir = mt76_register_debugfs_fops(&dev->mphy, &fops_regval);
0555 if (!dir)
0556 return -ENOMEM;
0557
0558 if (is_mt7615(&dev->mt76))
0559 debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir,
0560 mt7615_queues_read);
0561 else
0562 debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir,
0563 mt76_queues_read);
0564 debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir,
0565 mt7615_queues_acq);
0566 debugfs_create_file("ampdu_stat", 0400, dir, dev, &mt7615_ampdu_stat_fops);
0567 debugfs_create_file("scs", 0600, dir, dev, &fops_scs);
0568 debugfs_create_file("dbdc", 0600, dir, dev, &fops_dbdc);
0569 debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug);
0570 debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm);
0571 debugfs_create_file("idle-timeout", 0600, dir, dev,
0572 &fops_pm_idle_timeout);
0573 debugfs_create_devm_seqfile(dev->mt76.dev, "runtime_pm_stats", dir,
0574 mt7615_pm_stats);
0575 debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir,
0576 mt7615_radio_read);
0577
0578 if (is_mt7615(&dev->mt76)) {
0579 debugfs_create_u32("dfs_hw_pattern", 0400, dir,
0580 &dev->hw_pattern);
0581
0582 debugfs_create_u8("pattern_len", 0600, dir,
0583 &dev->radar_pattern.n_pulses);
0584 debugfs_create_u32("pulse_period", 0600, dir,
0585 &dev->radar_pattern.period);
0586 debugfs_create_u16("pulse_width", 0600, dir,
0587 &dev->radar_pattern.width);
0588 debugfs_create_u16("pulse_power", 0600, dir,
0589 &dev->radar_pattern.power);
0590 debugfs_create_file("radar_trigger", 0200, dir, dev,
0591 &fops_radar_pattern);
0592 }
0593
0594 debugfs_create_file("reset_test", 0200, dir, dev,
0595 &fops_reset_test);
0596 debugfs_create_file("ext_mac_addr", 0600, dir, dev, &fops_ext_mac_addr);
0597
0598 debugfs_create_u32("rf_wfidx", 0600, dir, &dev->debugfs_rf_wf);
0599 debugfs_create_u32("rf_regidx", 0600, dir, &dev->debugfs_rf_reg);
0600 debugfs_create_file_unsafe("rf_regval", 0600, dir, dev,
0601 &fops_rf_reg);
0602 if (is_mt7663(&dev->mt76))
0603 debugfs_create_file("chip_config", 0600, dir, dev,
0604 &fops_config);
0605 if (mt76_is_sdio(&dev->mt76))
0606 debugfs_create_devm_seqfile(dev->mt76.dev, "sched-quota", dir,
0607 mt7663s_sched_quota_read);
0608
0609 return 0;
0610 }
0611 EXPORT_SYMBOL_GPL(mt7615_init_debugfs);