cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

debugfs.c (13716B)


      1// SPDX-License-Identifier: ISC
      2
      3#include "mt7615.h"
      4
      5static int
      6mt7615_reg_set(void *data, u64 val)
      7{
      8	struct mt7615_dev *dev = data;
      9
     10	mt7615_mutex_acquire(dev);
     11	mt76_wr(dev, dev->mt76.debugfs_reg, val);
     12	mt7615_mutex_release(dev);
     13
     14	return 0;
     15}
     16
     17static int
     18mt7615_reg_get(void *data, u64 *val)
     19{
     20	struct mt7615_dev *dev = data;
     21
     22	mt7615_mutex_acquire(dev);
     23	*val = mt76_rr(dev, dev->mt76.debugfs_reg);
     24	mt7615_mutex_release(dev);
     25
     26	return 0;
     27}
     28
     29DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mt7615_reg_get, mt7615_reg_set,
     30			 "0x%08llx\n");
     31
     32static int
     33mt7615_radar_pattern_set(void *data, u64 val)
     34{
     35	struct mt7615_dev *dev = data;
     36	int err;
     37
     38	if (!mt7615_wait_for_mcu_init(dev))
     39		return 0;
     40
     41	mt7615_mutex_acquire(dev);
     42	err = mt7615_mcu_rdd_send_pattern(dev);
     43	mt7615_mutex_release(dev);
     44
     45	return err;
     46}
     47
     48DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL,
     49			 mt7615_radar_pattern_set, "%lld\n");
     50
     51static int mt7615_config(void *data, u64 val)
     52{
     53	struct mt7615_dev *dev = data;
     54	int ret;
     55
     56	mt7615_mutex_acquire(dev);
     57	ret = mt76_connac_mcu_chip_config(&dev->mt76);
     58	mt7615_mutex_release(dev);
     59
     60	return ret;
     61}
     62
     63DEFINE_DEBUGFS_ATTRIBUTE(fops_config, NULL, mt7615_config, "%lld\n");
     64
     65static int
     66mt7615_scs_set(void *data, u64 val)
     67{
     68	struct mt7615_dev *dev = data;
     69	struct mt7615_phy *ext_phy;
     70
     71	if (!mt7615_wait_for_mcu_init(dev))
     72		return 0;
     73
     74	mt7615_mac_set_scs(&dev->phy, val);
     75	ext_phy = mt7615_ext_phy(dev);
     76	if (ext_phy)
     77		mt7615_mac_set_scs(ext_phy, val);
     78
     79	return 0;
     80}
     81
     82static int
     83mt7615_scs_get(void *data, u64 *val)
     84{
     85	struct mt7615_dev *dev = data;
     86
     87	*val = dev->phy.scs_en;
     88
     89	return 0;
     90}
     91
     92DEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get,
     93			 mt7615_scs_set, "%lld\n");
     94
     95static int
     96mt7615_pm_set(void *data, u64 val)
     97{
     98	struct mt7615_dev *dev = data;
     99	struct mt76_connac_pm *pm = &dev->pm;
    100	int ret = 0;
    101
    102	if (!mt7615_wait_for_mcu_init(dev))
    103		return 0;
    104
    105	if (!mt7615_firmware_offload(dev) || mt76_is_usb(&dev->mt76))
    106		return -EOPNOTSUPP;
    107
    108	mutex_lock(&dev->mt76.mutex);
    109
    110	if (val == pm->enable)
    111		goto out;
    112
    113	if (dev->phy.n_beacon_vif) {
    114		ret = -EBUSY;
    115		goto out;
    116	}
    117
    118	if (!pm->enable) {
    119		pm->stats.last_wake_event = jiffies;
    120		pm->stats.last_doze_event = jiffies;
    121	}
    122	/* make sure the chip is awake here and ps_work is scheduled
    123	 * just at end of the this routine.
    124	 */
    125	pm->enable = false;
    126	mt76_connac_pm_wake(&dev->mphy, pm);
    127
    128	pm->enable = val;
    129	mt76_connac_power_save_sched(&dev->mphy, pm);
    130out:
    131	mutex_unlock(&dev->mt76.mutex);
    132
    133	return ret;
    134}
    135
    136static int
    137mt7615_pm_get(void *data, u64 *val)
    138{
    139	struct mt7615_dev *dev = data;
    140
    141	*val = dev->pm.enable;
    142
    143	return 0;
    144}
    145
    146DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7615_pm_get, mt7615_pm_set, "%lld\n");
    147
    148static int
    149mt7615_pm_stats(struct seq_file *s, void *data)
    150{
    151	struct mt7615_dev *dev = dev_get_drvdata(s->private);
    152	struct mt76_connac_pm *pm = &dev->pm;
    153	unsigned long awake_time = pm->stats.awake_time;
    154	unsigned long doze_time = pm->stats.doze_time;
    155
    156	if (!test_bit(MT76_STATE_PM, &dev->mphy.state))
    157		awake_time += jiffies - pm->stats.last_wake_event;
    158	else
    159		doze_time += jiffies - pm->stats.last_doze_event;
    160
    161	seq_printf(s, "awake time: %14u\ndoze time: %15u\n",
    162		   jiffies_to_msecs(awake_time),
    163		   jiffies_to_msecs(doze_time));
    164
    165	return 0;
    166}
    167
    168static int
    169mt7615_pm_idle_timeout_set(void *data, u64 val)
    170{
    171	struct mt7615_dev *dev = data;
    172
    173	dev->pm.idle_timeout = msecs_to_jiffies(val);
    174
    175	return 0;
    176}
    177
    178static int
    179mt7615_pm_idle_timeout_get(void *data, u64 *val)
    180{
    181	struct mt7615_dev *dev = data;
    182
    183	*val = jiffies_to_msecs(dev->pm.idle_timeout);
    184
    185	return 0;
    186}
    187
    188DEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt7615_pm_idle_timeout_get,
    189			 mt7615_pm_idle_timeout_set, "%lld\n");
    190
    191static int
    192mt7615_dbdc_set(void *data, u64 val)
    193{
    194	struct mt7615_dev *dev = data;
    195
    196	if (!mt7615_wait_for_mcu_init(dev))
    197		return 0;
    198
    199	if (val)
    200		mt7615_register_ext_phy(dev);
    201	else
    202		mt7615_unregister_ext_phy(dev);
    203
    204	return 0;
    205}
    206
    207static int
    208mt7615_dbdc_get(void *data, u64 *val)
    209{
    210	struct mt7615_dev *dev = data;
    211
    212	*val = !!mt7615_ext_phy(dev);
    213
    214	return 0;
    215}
    216
    217DEFINE_DEBUGFS_ATTRIBUTE(fops_dbdc, mt7615_dbdc_get,
    218			 mt7615_dbdc_set, "%lld\n");
    219
    220static int
    221mt7615_fw_debug_set(void *data, u64 val)
    222{
    223	struct mt7615_dev *dev = data;
    224
    225	if (!mt7615_wait_for_mcu_init(dev))
    226		return 0;
    227
    228	dev->fw_debug = val;
    229
    230	mt7615_mutex_acquire(dev);
    231	mt7615_mcu_fw_log_2_host(dev, dev->fw_debug ? 2 : 0);
    232	mt7615_mutex_release(dev);
    233
    234	return 0;
    235}
    236
    237static int
    238mt7615_fw_debug_get(void *data, u64 *val)
    239{
    240	struct mt7615_dev *dev = data;
    241
    242	*val = dev->fw_debug;
    243
    244	return 0;
    245}
    246
    247DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7615_fw_debug_get,
    248			 mt7615_fw_debug_set, "%lld\n");
    249
    250static int
    251mt7615_reset_test_set(void *data, u64 val)
    252{
    253	struct mt7615_dev *dev = data;
    254	struct sk_buff *skb;
    255
    256	if (!mt7615_wait_for_mcu_init(dev))
    257		return 0;
    258
    259	skb = alloc_skb(1, GFP_KERNEL);
    260	if (!skb)
    261		return -ENOMEM;
    262
    263	skb_put(skb, 1);
    264
    265	mt7615_mutex_acquire(dev);
    266	mt76_tx_queue_skb_raw(dev, dev->mphy.q_tx[0], skb, 0);
    267	mt7615_mutex_release(dev);
    268
    269	return 0;
    270}
    271
    272DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_test, NULL,
    273			 mt7615_reset_test_set, "%lld\n");
    274
    275static void
    276mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy,
    277			   struct seq_file *file)
    278{
    279	struct mt7615_dev *dev = file->private;
    280	u32 reg = is_mt7663(&dev->mt76) ? MT_MIB_ARNG(0) : MT_AGG_ASRCR0;
    281	bool ext_phy = phy != &dev->phy;
    282	int bound[7], i, range;
    283
    284	if (!phy)
    285		return;
    286
    287	range = mt76_rr(dev, reg);
    288	for (i = 0; i < 4; i++)
    289		bound[i] = MT_AGG_ASRCR_RANGE(range, i) + 1;
    290
    291	range = mt76_rr(dev, reg + 4);
    292	for (i = 0; i < 3; i++)
    293		bound[i + 4] = MT_AGG_ASRCR_RANGE(range, i) + 1;
    294
    295	seq_printf(file, "\nPhy %d\n", ext_phy);
    296
    297	seq_printf(file, "Length: %8d | ", bound[0]);
    298	for (i = 0; i < ARRAY_SIZE(bound) - 1; i++)
    299		seq_printf(file, "%3d -%3d | ",
    300			   bound[i], bound[i + 1]);
    301	seq_puts(file, "\nCount:  ");
    302
    303	range = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
    304	for (i = 0; i < ARRAY_SIZE(bound); i++)
    305		seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i + range]);
    306	seq_puts(file, "\n");
    307
    308	seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt);
    309	seq_printf(file, "PER: %ld.%1ld%%\n",
    310		   phy->mib.aggr_per / 10, phy->mib.aggr_per % 10);
    311}
    312
    313static int
    314mt7615_ampdu_stat_show(struct seq_file *file, void *data)
    315{
    316	struct mt7615_dev *dev = file->private;
    317
    318	mt7615_mutex_acquire(dev);
    319
    320	mt7615_ampdu_stat_read_phy(&dev->phy, file);
    321	mt7615_ampdu_stat_read_phy(mt7615_ext_phy(dev), file);
    322
    323	mt7615_mutex_release(dev);
    324
    325	return 0;
    326}
    327
    328DEFINE_SHOW_ATTRIBUTE(mt7615_ampdu_stat);
    329
    330static void
    331mt7615_radio_read_phy(struct mt7615_phy *phy, struct seq_file *s)
    332{
    333	struct mt7615_dev *dev = dev_get_drvdata(s->private);
    334	bool ext_phy = phy != &dev->phy;
    335
    336	if (!phy)
    337		return;
    338
    339	seq_printf(s, "Radio %d sensitivity: ofdm=%d cck=%d\n", ext_phy,
    340		   phy->ofdm_sensitivity, phy->cck_sensitivity);
    341	seq_printf(s, "Radio %d false CCA: ofdm=%d cck=%d\n", ext_phy,
    342		   phy->false_cca_ofdm, phy->false_cca_cck);
    343}
    344
    345static int
    346mt7615_radio_read(struct seq_file *s, void *data)
    347{
    348	struct mt7615_dev *dev = dev_get_drvdata(s->private);
    349
    350	mt7615_radio_read_phy(&dev->phy, s);
    351	mt7615_radio_read_phy(mt7615_ext_phy(dev), s);
    352
    353	return 0;
    354}
    355
    356static int
    357mt7615_queues_acq(struct seq_file *s, void *data)
    358{
    359	struct mt7615_dev *dev = dev_get_drvdata(s->private);
    360	int i;
    361
    362	mt7615_mutex_acquire(dev);
    363
    364	for (i = 0; i < 16; i++) {
    365		int j, wmm_idx = i % MT7615_MAX_WMM_SETS;
    366		int acs = i / MT7615_MAX_WMM_SETS;
    367		u32 ctrl, val, qlen = 0;
    368
    369		if (wmm_idx == 3 && is_mt7663(&dev->mt76))
    370			continue;
    371
    372		val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, wmm_idx));
    373		ctrl = BIT(31) | BIT(15) | (acs << 8);
    374
    375		for (j = 0; j < 32; j++) {
    376			if (val & BIT(j))
    377				continue;
    378
    379			mt76_wr(dev, MT_PLE_FL_Q0_CTRL,
    380				ctrl | (j + (wmm_idx << 5)));
    381			qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL,
    382					       GENMASK(11, 0));
    383		}
    384		seq_printf(s, "AC%d%d: queued=%d\n", wmm_idx, acs, qlen);
    385	}
    386
    387	mt7615_mutex_release(dev);
    388
    389	return 0;
    390}
    391
    392static int
    393mt7615_queues_read(struct seq_file *s, void *data)
    394{
    395	struct mt7615_dev *dev = dev_get_drvdata(s->private);
    396	struct {
    397		struct mt76_queue *q;
    398		char *queue;
    399	} queue_map[] = {
    400		{ dev->mphy.q_tx[MT_TXQ_BE], "PDMA0" },
    401		{ dev->mt76.q_mcu[MT_MCUQ_WM], "MCUQ" },
    402		{ dev->mt76.q_mcu[MT_MCUQ_FWDL], "MCUFWQ" },
    403	};
    404	int i;
    405
    406	for (i = 0; i < ARRAY_SIZE(queue_map); i++) {
    407		struct mt76_queue *q = queue_map[i].q;
    408
    409		seq_printf(s,
    410			   "%s:	queued=%d head=%d tail=%d\n",
    411			   queue_map[i].queue, q->queued, q->head,
    412			   q->tail);
    413	}
    414
    415	return 0;
    416}
    417
    418static int
    419mt7615_rf_reg_set(void *data, u64 val)
    420{
    421	struct mt7615_dev *dev = data;
    422
    423	mt7615_rf_wr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg, val);
    424
    425	return 0;
    426}
    427
    428static int
    429mt7615_rf_reg_get(void *data, u64 *val)
    430{
    431	struct mt7615_dev *dev = data;
    432
    433	*val = mt7615_rf_rr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg);
    434
    435	return 0;
    436}
    437
    438DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_reg, mt7615_rf_reg_get, mt7615_rf_reg_set,
    439			 "0x%08llx\n");
    440
    441static ssize_t
    442mt7615_ext_mac_addr_read(struct file *file, char __user *userbuf,
    443			 size_t count, loff_t *ppos)
    444{
    445	struct mt7615_dev *dev = file->private_data;
    446	u32 len = 32 * ((ETH_ALEN * 3) + 4) + 1;
    447	u8 addr[ETH_ALEN];
    448	char *buf;
    449	int ofs = 0;
    450	int i;
    451
    452	buf = kzalloc(len, GFP_KERNEL);
    453	if (!buf)
    454		return -ENOMEM;
    455
    456	for (i = 0; i < 32; i++) {
    457		if (!(dev->muar_mask & BIT(i)))
    458			continue;
    459
    460		mt76_wr(dev, MT_WF_RMAC_MAR1,
    461			FIELD_PREP(MT_WF_RMAC_MAR1_IDX, i * 2) |
    462			MT_WF_RMAC_MAR1_START);
    463		put_unaligned_le32(mt76_rr(dev, MT_WF_RMAC_MAR0), addr);
    464		put_unaligned_le16((mt76_rr(dev, MT_WF_RMAC_MAR1) &
    465				    MT_WF_RMAC_MAR1_ADDR), addr + 4);
    466		ofs += snprintf(buf + ofs, len - ofs, "%d=%pM\n", i, addr);
    467	}
    468
    469	ofs = simple_read_from_buffer(userbuf, count, ppos, buf, ofs);
    470
    471	kfree(buf);
    472	return ofs;
    473}
    474
    475static ssize_t
    476mt7615_ext_mac_addr_write(struct file *file, const char __user *userbuf,
    477			  size_t count, loff_t *ppos)
    478{
    479	struct mt7615_dev *dev = file->private_data;
    480	unsigned long idx = 0;
    481	u8 addr[ETH_ALEN];
    482	char buf[32];
    483	char *p;
    484
    485	if (count > sizeof(buf))
    486		return -EINVAL;
    487
    488	if (copy_from_user(buf, userbuf, count))
    489		return -EFAULT;
    490
    491	buf[sizeof(buf) - 1] = '\0';
    492
    493	p = strchr(buf, '=');
    494	if (p) {
    495		*p = 0;
    496		p++;
    497
    498		if (kstrtoul(buf, 0, &idx) || idx > 31)
    499			return -EINVAL;
    500	} else {
    501		idx = 0;
    502		p = buf;
    503	}
    504
    505	if (!mac_pton(p, addr))
    506		return -EINVAL;
    507
    508	if (is_valid_ether_addr(addr)) {
    509		dev->muar_mask |= BIT(idx);
    510	} else {
    511		memset(addr, 0, sizeof(addr));
    512		dev->muar_mask &= ~BIT(idx);
    513	}
    514
    515	mt76_rmw_field(dev, MT_WF_RMAC_MORE(0), MT_WF_RMAC_MORE_MUAR_MODE, 1);
    516	mt76_wr(dev, MT_WF_RMAC_MAR0, get_unaligned_le32(addr));
    517	mt76_wr(dev, MT_WF_RMAC_MAR1,
    518		get_unaligned_le16(addr + 4) |
    519		FIELD_PREP(MT_WF_RMAC_MAR1_IDX, idx * 2) |
    520		MT_WF_RMAC_MAR1_START |
    521		MT_WF_RMAC_MAR1_WRITE);
    522
    523	mt76_rmw_field(dev, MT_WF_RMAC_MORE(0), MT_WF_RMAC_MORE_MUAR_MODE, !!dev->muar_mask);
    524
    525	return count;
    526}
    527
    528static const struct file_operations fops_ext_mac_addr = {
    529	.open = simple_open,
    530	.llseek = generic_file_llseek,
    531	.read = mt7615_ext_mac_addr_read,
    532	.write = mt7615_ext_mac_addr_write,
    533	.owner = THIS_MODULE,
    534};
    535
    536static int
    537mt7663s_sched_quota_read(struct seq_file *s, void *data)
    538{
    539	struct mt7615_dev *dev = dev_get_drvdata(s->private);
    540	struct mt76_sdio *sdio = &dev->mt76.sdio;
    541
    542	seq_printf(s, "pse_data_quota\t%d\n", sdio->sched.pse_data_quota);
    543	seq_printf(s, "ple_data_quota\t%d\n", sdio->sched.ple_data_quota);
    544	seq_printf(s, "pse_mcu_quota\t%d\n", sdio->sched.pse_mcu_quota);
    545	seq_printf(s, "sched_deficit\t%d\n", sdio->sched.deficit);
    546
    547	return 0;
    548}
    549
    550int mt7615_init_debugfs(struct mt7615_dev *dev)
    551{
    552	struct dentry *dir;
    553
    554	dir = mt76_register_debugfs_fops(&dev->mphy, &fops_regval);
    555	if (!dir)
    556		return -ENOMEM;
    557
    558	if (is_mt7615(&dev->mt76))
    559		debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir,
    560					    mt7615_queues_read);
    561	else
    562		debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir,
    563					    mt76_queues_read);
    564	debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir,
    565				    mt7615_queues_acq);
    566	debugfs_create_file("ampdu_stat", 0400, dir, dev, &mt7615_ampdu_stat_fops);
    567	debugfs_create_file("scs", 0600, dir, dev, &fops_scs);
    568	debugfs_create_file("dbdc", 0600, dir, dev, &fops_dbdc);
    569	debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug);
    570	debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm);
    571	debugfs_create_file("idle-timeout", 0600, dir, dev,
    572			    &fops_pm_idle_timeout);
    573	debugfs_create_devm_seqfile(dev->mt76.dev, "runtime_pm_stats", dir,
    574				    mt7615_pm_stats);
    575	debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir,
    576				    mt7615_radio_read);
    577
    578	if (is_mt7615(&dev->mt76)) {
    579		debugfs_create_u32("dfs_hw_pattern", 0400, dir,
    580				   &dev->hw_pattern);
    581		/* test pattern knobs */
    582		debugfs_create_u8("pattern_len", 0600, dir,
    583				  &dev->radar_pattern.n_pulses);
    584		debugfs_create_u32("pulse_period", 0600, dir,
    585				   &dev->radar_pattern.period);
    586		debugfs_create_u16("pulse_width", 0600, dir,
    587				   &dev->radar_pattern.width);
    588		debugfs_create_u16("pulse_power", 0600, dir,
    589				   &dev->radar_pattern.power);
    590		debugfs_create_file("radar_trigger", 0200, dir, dev,
    591				    &fops_radar_pattern);
    592	}
    593
    594	debugfs_create_file("reset_test", 0200, dir, dev,
    595			    &fops_reset_test);
    596	debugfs_create_file("ext_mac_addr", 0600, dir, dev, &fops_ext_mac_addr);
    597
    598	debugfs_create_u32("rf_wfidx", 0600, dir, &dev->debugfs_rf_wf);
    599	debugfs_create_u32("rf_regidx", 0600, dir, &dev->debugfs_rf_reg);
    600	debugfs_create_file_unsafe("rf_regval", 0600, dir, dev,
    601				   &fops_rf_reg);
    602	if (is_mt7663(&dev->mt76))
    603		debugfs_create_file("chip_config", 0600, dir, dev,
    604				    &fops_config);
    605	if (mt76_is_sdio(&dev->mt76))
    606		debugfs_create_devm_seqfile(dev->mt76.dev, "sched-quota", dir,
    607					    mt7663s_sched_quota_read);
    608
    609	return 0;
    610}
    611EXPORT_SYMBOL_GPL(mt7615_init_debugfs);