162306a36Sopenharmony_ci// SPDX-License-Identifier: ISC 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#include "mt7615.h" 462306a36Sopenharmony_ci 562306a36Sopenharmony_cistatic int 662306a36Sopenharmony_cimt7615_reg_set(void *data, u64 val) 762306a36Sopenharmony_ci{ 862306a36Sopenharmony_ci struct mt7615_dev *dev = data; 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci mt7615_mutex_acquire(dev); 1162306a36Sopenharmony_ci mt76_wr(dev, dev->mt76.debugfs_reg, val); 1262306a36Sopenharmony_ci mt7615_mutex_release(dev); 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci return 0; 1562306a36Sopenharmony_ci} 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cistatic int 1862306a36Sopenharmony_cimt7615_reg_get(void *data, u64 *val) 1962306a36Sopenharmony_ci{ 2062306a36Sopenharmony_ci struct mt7615_dev *dev = data; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci mt7615_mutex_acquire(dev); 2362306a36Sopenharmony_ci *val = mt76_rr(dev, dev->mt76.debugfs_reg); 2462306a36Sopenharmony_ci mt7615_mutex_release(dev); 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci return 0; 2762306a36Sopenharmony_ci} 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mt7615_reg_get, mt7615_reg_set, 3062306a36Sopenharmony_ci "0x%08llx\n"); 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistatic int 3362306a36Sopenharmony_cimt7615_radar_pattern_set(void *data, u64 val) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci struct mt7615_dev *dev = data; 3662306a36Sopenharmony_ci int err; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci if (!mt7615_wait_for_mcu_init(dev)) 3962306a36Sopenharmony_ci return 0; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci mt7615_mutex_acquire(dev); 4262306a36Sopenharmony_ci err = mt7615_mcu_rdd_send_pattern(dev); 4362306a36Sopenharmony_ci mt7615_mutex_release(dev); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci return err; 4662306a36Sopenharmony_ci} 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL, 4962306a36Sopenharmony_ci mt7615_radar_pattern_set, "%lld\n"); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic int mt7615_config(void *data, u64 val) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci struct mt7615_dev *dev = data; 5462306a36Sopenharmony_ci int ret; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci mt7615_mutex_acquire(dev); 5762306a36Sopenharmony_ci ret = mt76_connac_mcu_chip_config(&dev->mt76); 5862306a36Sopenharmony_ci mt7615_mutex_release(dev); 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci return ret; 6162306a36Sopenharmony_ci} 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(fops_config, NULL, mt7615_config, "%lld\n"); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistatic int 6662306a36Sopenharmony_cimt7615_scs_set(void *data, u64 val) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci struct mt7615_dev *dev = data; 6962306a36Sopenharmony_ci struct mt7615_phy *ext_phy; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci if (!mt7615_wait_for_mcu_init(dev)) 7262306a36Sopenharmony_ci return 0; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci mt7615_mac_set_scs(&dev->phy, val); 7562306a36Sopenharmony_ci ext_phy = mt7615_ext_phy(dev); 7662306a36Sopenharmony_ci if (ext_phy) 7762306a36Sopenharmony_ci mt7615_mac_set_scs(ext_phy, val); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci return 0; 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistatic int 8362306a36Sopenharmony_cimt7615_scs_get(void *data, u64 *val) 8462306a36Sopenharmony_ci{ 8562306a36Sopenharmony_ci struct mt7615_dev *dev = data; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci *val = dev->phy.scs_en; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci return 0; 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get, 9362306a36Sopenharmony_ci mt7615_scs_set, "%lld\n"); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cistatic int 9662306a36Sopenharmony_cimt7615_pm_set(void *data, u64 val) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci struct mt7615_dev *dev = data; 9962306a36Sopenharmony_ci struct mt76_connac_pm *pm = &dev->pm; 10062306a36Sopenharmony_ci int ret = 0; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci if (!mt7615_wait_for_mcu_init(dev)) 10362306a36Sopenharmony_ci return 0; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci if (!mt7615_firmware_offload(dev) || mt76_is_usb(&dev->mt76)) 10662306a36Sopenharmony_ci return -EOPNOTSUPP; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci mutex_lock(&dev->mt76.mutex); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci if (val == pm->enable) 11162306a36Sopenharmony_ci goto out; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci if (dev->phy.n_beacon_vif) { 11462306a36Sopenharmony_ci ret = -EBUSY; 11562306a36Sopenharmony_ci goto out; 11662306a36Sopenharmony_ci } 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci if (!pm->enable) { 11962306a36Sopenharmony_ci pm->stats.last_wake_event = jiffies; 12062306a36Sopenharmony_ci pm->stats.last_doze_event = jiffies; 12162306a36Sopenharmony_ci } 12262306a36Sopenharmony_ci /* make sure the chip is awake here and ps_work is scheduled 12362306a36Sopenharmony_ci * just at end of the this routine. 12462306a36Sopenharmony_ci */ 12562306a36Sopenharmony_ci pm->enable = false; 12662306a36Sopenharmony_ci mt76_connac_pm_wake(&dev->mphy, pm); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci pm->enable = val; 12962306a36Sopenharmony_ci mt76_connac_power_save_sched(&dev->mphy, pm); 13062306a36Sopenharmony_ciout: 13162306a36Sopenharmony_ci mutex_unlock(&dev->mt76.mutex); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci return ret; 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cistatic int 13762306a36Sopenharmony_cimt7615_pm_get(void *data, u64 *val) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci struct mt7615_dev *dev = data; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci *val = dev->pm.enable; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci return 0; 14462306a36Sopenharmony_ci} 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7615_pm_get, mt7615_pm_set, "%lld\n"); 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistatic int 14962306a36Sopenharmony_cimt7615_pm_stats(struct seq_file *s, void *data) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci struct mt7615_dev *dev = dev_get_drvdata(s->private); 15262306a36Sopenharmony_ci struct mt76_connac_pm *pm = &dev->pm; 15362306a36Sopenharmony_ci unsigned long awake_time = pm->stats.awake_time; 15462306a36Sopenharmony_ci unsigned long doze_time = pm->stats.doze_time; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci if (!test_bit(MT76_STATE_PM, &dev->mphy.state)) 15762306a36Sopenharmony_ci awake_time += jiffies - pm->stats.last_wake_event; 15862306a36Sopenharmony_ci else 15962306a36Sopenharmony_ci doze_time += jiffies - pm->stats.last_doze_event; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci seq_printf(s, "awake time: %14u\ndoze time: %15u\n", 16262306a36Sopenharmony_ci jiffies_to_msecs(awake_time), 16362306a36Sopenharmony_ci jiffies_to_msecs(doze_time)); 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci return 0; 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_cistatic int 16962306a36Sopenharmony_cimt7615_pm_idle_timeout_set(void *data, u64 val) 17062306a36Sopenharmony_ci{ 17162306a36Sopenharmony_ci struct mt7615_dev *dev = data; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci dev->pm.idle_timeout = msecs_to_jiffies(val); 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci return 0; 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistatic int 17962306a36Sopenharmony_cimt7615_pm_idle_timeout_get(void *data, u64 *val) 18062306a36Sopenharmony_ci{ 18162306a36Sopenharmony_ci struct mt7615_dev *dev = data; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci *val = jiffies_to_msecs(dev->pm.idle_timeout); 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci return 0; 18662306a36Sopenharmony_ci} 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt7615_pm_idle_timeout_get, 18962306a36Sopenharmony_ci mt7615_pm_idle_timeout_set, "%lld\n"); 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_cistatic int 19262306a36Sopenharmony_cimt7615_dbdc_set(void *data, u64 val) 19362306a36Sopenharmony_ci{ 19462306a36Sopenharmony_ci struct mt7615_dev *dev = data; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci if (!mt7615_wait_for_mcu_init(dev)) 19762306a36Sopenharmony_ci return 0; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci if (val) 20062306a36Sopenharmony_ci mt7615_register_ext_phy(dev); 20162306a36Sopenharmony_ci else 20262306a36Sopenharmony_ci mt7615_unregister_ext_phy(dev); 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci return 0; 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistatic int 20862306a36Sopenharmony_cimt7615_dbdc_get(void *data, u64 *val) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci struct mt7615_dev *dev = data; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci *val = !!mt7615_ext_phy(dev); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci return 0; 21562306a36Sopenharmony_ci} 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(fops_dbdc, mt7615_dbdc_get, 21862306a36Sopenharmony_ci mt7615_dbdc_set, "%lld\n"); 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_cistatic int 22162306a36Sopenharmony_cimt7615_fw_debug_set(void *data, u64 val) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci struct mt7615_dev *dev = data; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci if (!mt7615_wait_for_mcu_init(dev)) 22662306a36Sopenharmony_ci return 0; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci dev->fw_debug = val; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci mt7615_mutex_acquire(dev); 23162306a36Sopenharmony_ci mt7615_mcu_fw_log_2_host(dev, dev->fw_debug ? 2 : 0); 23262306a36Sopenharmony_ci mt7615_mutex_release(dev); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci return 0; 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistatic int 23862306a36Sopenharmony_cimt7615_fw_debug_get(void *data, u64 *val) 23962306a36Sopenharmony_ci{ 24062306a36Sopenharmony_ci struct mt7615_dev *dev = data; 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci *val = dev->fw_debug; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci return 0; 24562306a36Sopenharmony_ci} 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7615_fw_debug_get, 24862306a36Sopenharmony_ci mt7615_fw_debug_set, "%lld\n"); 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cistatic int 25162306a36Sopenharmony_cimt7615_reset_test_set(void *data, u64 val) 25262306a36Sopenharmony_ci{ 25362306a36Sopenharmony_ci struct mt7615_dev *dev = data; 25462306a36Sopenharmony_ci struct sk_buff *skb; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci if (!mt7615_wait_for_mcu_init(dev)) 25762306a36Sopenharmony_ci return 0; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci skb = alloc_skb(1, GFP_KERNEL); 26062306a36Sopenharmony_ci if (!skb) 26162306a36Sopenharmony_ci return -ENOMEM; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci skb_put(skb, 1); 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci mt7615_mutex_acquire(dev); 26662306a36Sopenharmony_ci mt76_tx_queue_skb_raw(dev, dev->mphy.q_tx[0], skb, 0); 26762306a36Sopenharmony_ci mt7615_mutex_release(dev); 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci return 0; 27062306a36Sopenharmony_ci} 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(fops_reset_test, NULL, 27362306a36Sopenharmony_ci mt7615_reset_test_set, "%lld\n"); 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_cistatic void 27662306a36Sopenharmony_cimt7615_ampdu_stat_read_phy(struct mt7615_phy *phy, 27762306a36Sopenharmony_ci struct seq_file *file) 27862306a36Sopenharmony_ci{ 27962306a36Sopenharmony_ci struct mt7615_dev *dev = file->private; 28062306a36Sopenharmony_ci u32 reg = is_mt7663(&dev->mt76) ? MT_MIB_ARNG(0) : MT_AGG_ASRCR0; 28162306a36Sopenharmony_ci int bound[7], i, range; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci if (!phy) 28462306a36Sopenharmony_ci return; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci range = mt76_rr(dev, reg); 28762306a36Sopenharmony_ci for (i = 0; i < 4; i++) 28862306a36Sopenharmony_ci bound[i] = MT_AGG_ASRCR_RANGE(range, i) + 1; 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci range = mt76_rr(dev, reg + 4); 29162306a36Sopenharmony_ci for (i = 0; i < 3; i++) 29262306a36Sopenharmony_ci bound[i + 4] = MT_AGG_ASRCR_RANGE(range, i) + 1; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci seq_printf(file, "\nPhy %d\n", phy != &dev->phy); 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci seq_printf(file, "Length: %8d | ", bound[0]); 29762306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(bound) - 1; i++) 29862306a36Sopenharmony_ci seq_printf(file, "%3d -%3d | ", 29962306a36Sopenharmony_ci bound[i], bound[i + 1]); 30062306a36Sopenharmony_ci seq_puts(file, "\nCount: "); 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(bound); i++) 30362306a36Sopenharmony_ci seq_printf(file, "%8d | ", phy->mt76->aggr_stats[i]); 30462306a36Sopenharmony_ci seq_puts(file, "\n"); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt); 30762306a36Sopenharmony_ci seq_printf(file, "PER: %ld.%1ld%%\n", 30862306a36Sopenharmony_ci phy->mib.aggr_per / 10, phy->mib.aggr_per % 10); 30962306a36Sopenharmony_ci} 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_cistatic int 31262306a36Sopenharmony_cimt7615_ampdu_stat_show(struct seq_file *file, void *data) 31362306a36Sopenharmony_ci{ 31462306a36Sopenharmony_ci struct mt7615_dev *dev = file->private; 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci mt7615_mutex_acquire(dev); 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci mt7615_ampdu_stat_read_phy(&dev->phy, file); 31962306a36Sopenharmony_ci mt7615_ampdu_stat_read_phy(mt7615_ext_phy(dev), file); 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci mt7615_mutex_release(dev); 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci return 0; 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mt7615_ampdu_stat); 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_cistatic void 32962306a36Sopenharmony_cimt7615_radio_read_phy(struct mt7615_phy *phy, struct seq_file *s) 33062306a36Sopenharmony_ci{ 33162306a36Sopenharmony_ci struct mt7615_dev *dev = dev_get_drvdata(s->private); 33262306a36Sopenharmony_ci bool ext_phy = phy != &dev->phy; 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci if (!phy) 33562306a36Sopenharmony_ci return; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci seq_printf(s, "Radio %d sensitivity: ofdm=%d cck=%d\n", ext_phy, 33862306a36Sopenharmony_ci phy->ofdm_sensitivity, phy->cck_sensitivity); 33962306a36Sopenharmony_ci seq_printf(s, "Radio %d false CCA: ofdm=%d cck=%d\n", ext_phy, 34062306a36Sopenharmony_ci phy->false_cca_ofdm, phy->false_cca_cck); 34162306a36Sopenharmony_ci} 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_cistatic int 34462306a36Sopenharmony_cimt7615_radio_read(struct seq_file *s, void *data) 34562306a36Sopenharmony_ci{ 34662306a36Sopenharmony_ci struct mt7615_dev *dev = dev_get_drvdata(s->private); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci mt7615_radio_read_phy(&dev->phy, s); 34962306a36Sopenharmony_ci mt7615_radio_read_phy(mt7615_ext_phy(dev), s); 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci return 0; 35262306a36Sopenharmony_ci} 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_cistatic int 35562306a36Sopenharmony_cimt7615_queues_acq(struct seq_file *s, void *data) 35662306a36Sopenharmony_ci{ 35762306a36Sopenharmony_ci struct mt7615_dev *dev = dev_get_drvdata(s->private); 35862306a36Sopenharmony_ci int i; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci mt7615_mutex_acquire(dev); 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci for (i = 0; i < 16; i++) { 36362306a36Sopenharmony_ci int j, wmm_idx = i % MT7615_MAX_WMM_SETS; 36462306a36Sopenharmony_ci int acs = i / MT7615_MAX_WMM_SETS; 36562306a36Sopenharmony_ci u32 ctrl, val, qlen = 0; 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci if (wmm_idx == 3 && is_mt7663(&dev->mt76)) 36862306a36Sopenharmony_ci continue; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, wmm_idx)); 37162306a36Sopenharmony_ci ctrl = BIT(31) | BIT(15) | (acs << 8); 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci for (j = 0; j < 32; j++) { 37462306a36Sopenharmony_ci if (val & BIT(j)) 37562306a36Sopenharmony_ci continue; 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci mt76_wr(dev, MT_PLE_FL_Q0_CTRL, 37862306a36Sopenharmony_ci ctrl | (j + (wmm_idx << 5))); 37962306a36Sopenharmony_ci qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL, 38062306a36Sopenharmony_ci GENMASK(11, 0)); 38162306a36Sopenharmony_ci } 38262306a36Sopenharmony_ci seq_printf(s, "AC%d%d: queued=%d\n", wmm_idx, acs, qlen); 38362306a36Sopenharmony_ci } 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci mt7615_mutex_release(dev); 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci return 0; 38862306a36Sopenharmony_ci} 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_cistatic int 39162306a36Sopenharmony_cimt7615_queues_read(struct seq_file *s, void *data) 39262306a36Sopenharmony_ci{ 39362306a36Sopenharmony_ci struct mt7615_dev *dev = dev_get_drvdata(s->private); 39462306a36Sopenharmony_ci struct { 39562306a36Sopenharmony_ci struct mt76_queue *q; 39662306a36Sopenharmony_ci char *queue; 39762306a36Sopenharmony_ci } queue_map[] = { 39862306a36Sopenharmony_ci { dev->mphy.q_tx[MT_TXQ_BE], "PDMA0" }, 39962306a36Sopenharmony_ci { dev->mt76.q_mcu[MT_MCUQ_WM], "MCUQ" }, 40062306a36Sopenharmony_ci { dev->mt76.q_mcu[MT_MCUQ_FWDL], "MCUFWQ" }, 40162306a36Sopenharmony_ci }; 40262306a36Sopenharmony_ci int i; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(queue_map); i++) { 40562306a36Sopenharmony_ci struct mt76_queue *q = queue_map[i].q; 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci seq_printf(s, 40862306a36Sopenharmony_ci "%s: queued=%d head=%d tail=%d\n", 40962306a36Sopenharmony_ci queue_map[i].queue, q->queued, q->head, 41062306a36Sopenharmony_ci q->tail); 41162306a36Sopenharmony_ci } 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci return 0; 41462306a36Sopenharmony_ci} 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_cistatic int 41762306a36Sopenharmony_cimt7615_rf_reg_set(void *data, u64 val) 41862306a36Sopenharmony_ci{ 41962306a36Sopenharmony_ci struct mt7615_dev *dev = data; 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci mt7615_rf_wr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg, val); 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci return 0; 42462306a36Sopenharmony_ci} 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_cistatic int 42762306a36Sopenharmony_cimt7615_rf_reg_get(void *data, u64 *val) 42862306a36Sopenharmony_ci{ 42962306a36Sopenharmony_ci struct mt7615_dev *dev = data; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci *val = mt7615_rf_rr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg); 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci return 0; 43462306a36Sopenharmony_ci} 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(fops_rf_reg, mt7615_rf_reg_get, mt7615_rf_reg_set, 43762306a36Sopenharmony_ci "0x%08llx\n"); 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_cistatic ssize_t 44062306a36Sopenharmony_cimt7615_ext_mac_addr_read(struct file *file, char __user *userbuf, 44162306a36Sopenharmony_ci size_t count, loff_t *ppos) 44262306a36Sopenharmony_ci{ 44362306a36Sopenharmony_ci struct mt7615_dev *dev = file->private_data; 44462306a36Sopenharmony_ci u32 len = 32 * ((ETH_ALEN * 3) + 4) + 1; 44562306a36Sopenharmony_ci u8 addr[ETH_ALEN]; 44662306a36Sopenharmony_ci char *buf; 44762306a36Sopenharmony_ci int ofs = 0; 44862306a36Sopenharmony_ci int i; 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci buf = kzalloc(len, GFP_KERNEL); 45162306a36Sopenharmony_ci if (!buf) 45262306a36Sopenharmony_ci return -ENOMEM; 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci for (i = 0; i < 32; i++) { 45562306a36Sopenharmony_ci if (!(dev->muar_mask & BIT(i))) 45662306a36Sopenharmony_ci continue; 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci mt76_wr(dev, MT_WF_RMAC_MAR1, 45962306a36Sopenharmony_ci FIELD_PREP(MT_WF_RMAC_MAR1_IDX, i * 2) | 46062306a36Sopenharmony_ci MT_WF_RMAC_MAR1_START); 46162306a36Sopenharmony_ci put_unaligned_le32(mt76_rr(dev, MT_WF_RMAC_MAR0), addr); 46262306a36Sopenharmony_ci put_unaligned_le16((mt76_rr(dev, MT_WF_RMAC_MAR1) & 46362306a36Sopenharmony_ci MT_WF_RMAC_MAR1_ADDR), addr + 4); 46462306a36Sopenharmony_ci ofs += snprintf(buf + ofs, len - ofs, "%d=%pM\n", i, addr); 46562306a36Sopenharmony_ci } 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci ofs = simple_read_from_buffer(userbuf, count, ppos, buf, ofs); 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci kfree(buf); 47062306a36Sopenharmony_ci return ofs; 47162306a36Sopenharmony_ci} 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_cistatic ssize_t 47462306a36Sopenharmony_cimt7615_ext_mac_addr_write(struct file *file, const char __user *userbuf, 47562306a36Sopenharmony_ci size_t count, loff_t *ppos) 47662306a36Sopenharmony_ci{ 47762306a36Sopenharmony_ci struct mt7615_dev *dev = file->private_data; 47862306a36Sopenharmony_ci unsigned long idx = 0; 47962306a36Sopenharmony_ci u8 addr[ETH_ALEN]; 48062306a36Sopenharmony_ci char buf[32]; 48162306a36Sopenharmony_ci char *p; 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci if (count > sizeof(buf)) 48462306a36Sopenharmony_ci return -EINVAL; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci if (copy_from_user(buf, userbuf, count)) 48762306a36Sopenharmony_ci return -EFAULT; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci buf[sizeof(buf) - 1] = '\0'; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci p = strchr(buf, '='); 49262306a36Sopenharmony_ci if (p) { 49362306a36Sopenharmony_ci *p = 0; 49462306a36Sopenharmony_ci p++; 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci if (kstrtoul(buf, 0, &idx) || idx > 31) 49762306a36Sopenharmony_ci return -EINVAL; 49862306a36Sopenharmony_ci } else { 49962306a36Sopenharmony_ci idx = 0; 50062306a36Sopenharmony_ci p = buf; 50162306a36Sopenharmony_ci } 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci if (!mac_pton(p, addr)) 50462306a36Sopenharmony_ci return -EINVAL; 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci if (is_valid_ether_addr(addr)) { 50762306a36Sopenharmony_ci dev->muar_mask |= BIT(idx); 50862306a36Sopenharmony_ci } else { 50962306a36Sopenharmony_ci memset(addr, 0, sizeof(addr)); 51062306a36Sopenharmony_ci dev->muar_mask &= ~BIT(idx); 51162306a36Sopenharmony_ci } 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci mt76_rmw_field(dev, MT_WF_RMAC_MORE(0), MT_WF_RMAC_MORE_MUAR_MODE, 1); 51462306a36Sopenharmony_ci mt76_wr(dev, MT_WF_RMAC_MAR0, get_unaligned_le32(addr)); 51562306a36Sopenharmony_ci mt76_wr(dev, MT_WF_RMAC_MAR1, 51662306a36Sopenharmony_ci get_unaligned_le16(addr + 4) | 51762306a36Sopenharmony_ci FIELD_PREP(MT_WF_RMAC_MAR1_IDX, idx * 2) | 51862306a36Sopenharmony_ci MT_WF_RMAC_MAR1_START | 51962306a36Sopenharmony_ci MT_WF_RMAC_MAR1_WRITE); 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci mt76_rmw_field(dev, MT_WF_RMAC_MORE(0), MT_WF_RMAC_MORE_MUAR_MODE, !!dev->muar_mask); 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci return count; 52462306a36Sopenharmony_ci} 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_cistatic const struct file_operations fops_ext_mac_addr = { 52762306a36Sopenharmony_ci .open = simple_open, 52862306a36Sopenharmony_ci .llseek = generic_file_llseek, 52962306a36Sopenharmony_ci .read = mt7615_ext_mac_addr_read, 53062306a36Sopenharmony_ci .write = mt7615_ext_mac_addr_write, 53162306a36Sopenharmony_ci .owner = THIS_MODULE, 53262306a36Sopenharmony_ci}; 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_cistatic int 53562306a36Sopenharmony_cimt7663s_sched_quota_read(struct seq_file *s, void *data) 53662306a36Sopenharmony_ci{ 53762306a36Sopenharmony_ci struct mt7615_dev *dev = dev_get_drvdata(s->private); 53862306a36Sopenharmony_ci struct mt76_sdio *sdio = &dev->mt76.sdio; 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci seq_printf(s, "pse_data_quota\t%d\n", sdio->sched.pse_data_quota); 54162306a36Sopenharmony_ci seq_printf(s, "ple_data_quota\t%d\n", sdio->sched.ple_data_quota); 54262306a36Sopenharmony_ci seq_printf(s, "pse_mcu_quota\t%d\n", sdio->sched.pse_mcu_quota); 54362306a36Sopenharmony_ci seq_printf(s, "sched_deficit\t%d\n", sdio->sched.deficit); 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci return 0; 54662306a36Sopenharmony_ci} 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ciint mt7615_init_debugfs(struct mt7615_dev *dev) 54962306a36Sopenharmony_ci{ 55062306a36Sopenharmony_ci struct dentry *dir; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci dir = mt76_register_debugfs_fops(&dev->mphy, &fops_regval); 55362306a36Sopenharmony_ci if (!dir) 55462306a36Sopenharmony_ci return -ENOMEM; 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci if (is_mt7615(&dev->mt76)) 55762306a36Sopenharmony_ci debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir, 55862306a36Sopenharmony_ci mt7615_queues_read); 55962306a36Sopenharmony_ci else 56062306a36Sopenharmony_ci debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir, 56162306a36Sopenharmony_ci mt76_queues_read); 56262306a36Sopenharmony_ci debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir, 56362306a36Sopenharmony_ci mt7615_queues_acq); 56462306a36Sopenharmony_ci debugfs_create_file("ampdu_stat", 0400, dir, dev, &mt7615_ampdu_stat_fops); 56562306a36Sopenharmony_ci debugfs_create_file("scs", 0600, dir, dev, &fops_scs); 56662306a36Sopenharmony_ci debugfs_create_file("dbdc", 0600, dir, dev, &fops_dbdc); 56762306a36Sopenharmony_ci debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug); 56862306a36Sopenharmony_ci debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm); 56962306a36Sopenharmony_ci debugfs_create_file("idle-timeout", 0600, dir, dev, 57062306a36Sopenharmony_ci &fops_pm_idle_timeout); 57162306a36Sopenharmony_ci debugfs_create_devm_seqfile(dev->mt76.dev, "runtime_pm_stats", dir, 57262306a36Sopenharmony_ci mt7615_pm_stats); 57362306a36Sopenharmony_ci debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir, 57462306a36Sopenharmony_ci mt7615_radio_read); 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci if (is_mt7615(&dev->mt76)) { 57762306a36Sopenharmony_ci debugfs_create_u32("dfs_hw_pattern", 0400, dir, 57862306a36Sopenharmony_ci &dev->hw_pattern); 57962306a36Sopenharmony_ci /* test pattern knobs */ 58062306a36Sopenharmony_ci debugfs_create_u8("pattern_len", 0600, dir, 58162306a36Sopenharmony_ci &dev->radar_pattern.n_pulses); 58262306a36Sopenharmony_ci debugfs_create_u32("pulse_period", 0600, dir, 58362306a36Sopenharmony_ci &dev->radar_pattern.period); 58462306a36Sopenharmony_ci debugfs_create_u16("pulse_width", 0600, dir, 58562306a36Sopenharmony_ci &dev->radar_pattern.width); 58662306a36Sopenharmony_ci debugfs_create_u16("pulse_power", 0600, dir, 58762306a36Sopenharmony_ci &dev->radar_pattern.power); 58862306a36Sopenharmony_ci debugfs_create_file("radar_trigger", 0200, dir, dev, 58962306a36Sopenharmony_ci &fops_radar_pattern); 59062306a36Sopenharmony_ci } 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci debugfs_create_file("reset_test", 0200, dir, dev, 59362306a36Sopenharmony_ci &fops_reset_test); 59462306a36Sopenharmony_ci debugfs_create_file("ext_mac_addr", 0600, dir, dev, &fops_ext_mac_addr); 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci debugfs_create_u32("rf_wfidx", 0600, dir, &dev->debugfs_rf_wf); 59762306a36Sopenharmony_ci debugfs_create_u32("rf_regidx", 0600, dir, &dev->debugfs_rf_reg); 59862306a36Sopenharmony_ci debugfs_create_file_unsafe("rf_regval", 0600, dir, dev, 59962306a36Sopenharmony_ci &fops_rf_reg); 60062306a36Sopenharmony_ci if (is_mt7663(&dev->mt76)) 60162306a36Sopenharmony_ci debugfs_create_file("chip_config", 0600, dir, dev, 60262306a36Sopenharmony_ci &fops_config); 60362306a36Sopenharmony_ci if (mt76_is_sdio(&dev->mt76)) 60462306a36Sopenharmony_ci debugfs_create_devm_seqfile(dev->mt76.dev, "sched-quota", dir, 60562306a36Sopenharmony_ci mt7663s_sched_quota_read); 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci return 0; 60862306a36Sopenharmony_ci} 60962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(mt7615_init_debugfs); 610