1 // SPDX-License-Identifier: ISC 2 3 #include "mt7615.h" 4 5 static int 6 mt7615_radar_pattern_set(void *data, u64 val) 7 { 8 struct mt7615_dev *dev = data; 9 10 if (!mt7615_wait_for_mcu_init(dev)) 11 return 0; 12 13 return mt7615_mcu_rdd_send_pattern(dev); 14 } 15 16 DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL, 17 mt7615_radar_pattern_set, "%lld\n"); 18 19 static int 20 mt7615_scs_set(void *data, u64 val) 21 { 22 struct mt7615_dev *dev = data; 23 struct mt7615_phy *ext_phy; 24 25 if (!mt7615_wait_for_mcu_init(dev)) 26 return 0; 27 28 mt7615_mac_set_scs(&dev->phy, val); 29 ext_phy = mt7615_ext_phy(dev); 30 if (ext_phy) 31 mt7615_mac_set_scs(ext_phy, val); 32 33 return 0; 34 } 35 36 static int 37 mt7615_scs_get(void *data, u64 *val) 38 { 39 struct mt7615_dev *dev = data; 40 41 *val = dev->phy.scs_en; 42 43 return 0; 44 } 45 46 DEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get, 47 mt7615_scs_set, "%lld\n"); 48 49 static int 50 mt7615_dbdc_set(void *data, u64 val) 51 { 52 struct mt7615_dev *dev = data; 53 54 if (!mt7615_wait_for_mcu_init(dev)) 55 return 0; 56 57 if (val) 58 mt7615_register_ext_phy(dev); 59 else 60 mt7615_unregister_ext_phy(dev); 61 62 return 0; 63 } 64 65 static int 66 mt7615_dbdc_get(void *data, u64 *val) 67 { 68 struct mt7615_dev *dev = data; 69 70 *val = !!mt7615_ext_phy(dev); 71 72 return 0; 73 } 74 75 DEFINE_DEBUGFS_ATTRIBUTE(fops_dbdc, mt7615_dbdc_get, 76 mt7615_dbdc_set, "%lld\n"); 77 78 static int 79 mt7615_fw_debug_set(void *data, u64 val) 80 { 81 struct mt7615_dev *dev = data; 82 83 if (!mt7615_wait_for_mcu_init(dev)) 84 return 0; 85 86 dev->fw_debug = val; 87 mt7615_mcu_fw_log_2_host(dev, dev->fw_debug ? 2 : 0); 88 89 return 0; 90 } 91 92 static int 93 mt7615_fw_debug_get(void *data, u64 *val) 94 { 95 struct mt7615_dev *dev = data; 96 97 *val = dev->fw_debug; 98 99 return 0; 100 } 101 102 DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7615_fw_debug_get, 103 mt7615_fw_debug_set, "%lld\n"); 104 105 static int 106 mt7615_reset_test_set(void *data, u64 val) 107 { 108 struct mt7615_dev *dev = data; 109 struct sk_buff *skb; 110 111 if (!mt7615_wait_for_mcu_init(dev)) 112 return 0; 113 114 skb = alloc_skb(1, GFP_KERNEL); 115 if (!skb) 116 return -ENOMEM; 117 118 skb_put(skb, 1); 119 mt76_tx_queue_skb_raw(dev, 0, skb, 0); 120 121 return 0; 122 } 123 124 DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_test, NULL, 125 mt7615_reset_test_set, "%lld\n"); 126 127 static void 128 mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy, 129 struct seq_file *file) 130 { 131 struct mt7615_dev *dev = file->private; 132 u32 reg = is_mt7663(&dev->mt76) ? MT_MIB_ARNG(0) : MT_AGG_ASRCR0; 133 bool ext_phy = phy != &dev->phy; 134 int bound[7], i, range; 135 136 if (!phy) 137 return; 138 139 range = mt76_rr(dev, reg); 140 for (i = 0; i < 4; i++) 141 bound[i] = MT_AGG_ASRCR_RANGE(range, i) + 1; 142 143 range = mt76_rr(dev, reg + 4); 144 for (i = 0; i < 3; i++) 145 bound[i + 4] = MT_AGG_ASRCR_RANGE(range, i) + 1; 146 147 seq_printf(file, "\nPhy %d\n", ext_phy); 148 149 seq_printf(file, "Length: %8d | ", bound[0]); 150 for (i = 0; i < ARRAY_SIZE(bound) - 1; i++) 151 seq_printf(file, "%3d -%3d | ", 152 bound[i], bound[i + 1]); 153 seq_puts(file, "\nCount: "); 154 155 range = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0; 156 for (i = 0; i < ARRAY_SIZE(bound); i++) 157 seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i + range]); 158 seq_puts(file, "\n"); 159 160 seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt); 161 seq_printf(file, "PER: %ld.%1ld%%\n", 162 phy->mib.aggr_per / 10, phy->mib.aggr_per % 10); 163 } 164 165 static int 166 mt7615_ampdu_stat_read(struct seq_file *file, void *data) 167 { 168 struct mt7615_dev *dev = file->private; 169 170 mt7615_ampdu_stat_read_phy(&dev->phy, file); 171 mt7615_ampdu_stat_read_phy(mt7615_ext_phy(dev), file); 172 173 return 0; 174 } 175 176 static int 177 mt7615_ampdu_stat_open(struct inode *inode, struct file *f) 178 { 179 return single_open(f, mt7615_ampdu_stat_read, inode->i_private); 180 } 181 182 static const struct file_operations fops_ampdu_stat = { 183 .open = mt7615_ampdu_stat_open, 184 .read = seq_read, 185 .llseek = seq_lseek, 186 .release = single_release, 187 }; 188 189 static void 190 mt7615_radio_read_phy(struct mt7615_phy *phy, struct seq_file *s) 191 { 192 struct mt7615_dev *dev = dev_get_drvdata(s->private); 193 bool ext_phy = phy != &dev->phy; 194 195 if (!phy) 196 return; 197 198 seq_printf(s, "Radio %d sensitivity: ofdm=%d cck=%d\n", ext_phy, 199 phy->ofdm_sensitivity, phy->cck_sensitivity); 200 seq_printf(s, "Radio %d false CCA: ofdm=%d cck=%d\n", ext_phy, 201 phy->false_cca_ofdm, phy->false_cca_cck); 202 } 203 204 static int 205 mt7615_radio_read(struct seq_file *s, void *data) 206 { 207 struct mt7615_dev *dev = dev_get_drvdata(s->private); 208 209 mt7615_radio_read_phy(&dev->phy, s); 210 mt7615_radio_read_phy(mt7615_ext_phy(dev), s); 211 212 return 0; 213 } 214 215 static int mt7615_read_temperature(struct seq_file *s, void *data) 216 { 217 struct mt7615_dev *dev = dev_get_drvdata(s->private); 218 int temp; 219 220 if (!mt7615_wait_for_mcu_init(dev)) 221 return 0; 222 223 /* cpu */ 224 temp = mt7615_mcu_get_temperature(dev, 0); 225 seq_printf(s, "Temperature: %d\n", temp); 226 227 return 0; 228 } 229 230 static int 231 mt7615_queues_acq(struct seq_file *s, void *data) 232 { 233 struct mt7615_dev *dev = dev_get_drvdata(s->private); 234 int i; 235 236 for (i = 0; i < 16; i++) { 237 int j, acs = i / 4, index = i % 4; 238 u32 ctrl, val, qlen = 0; 239 240 val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, index)); 241 ctrl = BIT(31) | BIT(15) | (acs << 8); 242 243 for (j = 0; j < 32; j++) { 244 if (val & BIT(j)) 245 continue; 246 247 mt76_wr(dev, MT_PLE_FL_Q0_CTRL, 248 ctrl | (j + (index << 5))); 249 qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL, 250 GENMASK(11, 0)); 251 } 252 seq_printf(s, "AC%d%d: queued=%d\n", acs, index, qlen); 253 } 254 255 return 0; 256 } 257 258 static int 259 mt7615_queues_read(struct seq_file *s, void *data) 260 { 261 struct mt7615_dev *dev = dev_get_drvdata(s->private); 262 static const struct { 263 char *queue; 264 int id; 265 } queue_map[] = { 266 { "PDMA0", MT_TXQ_BE }, 267 { "MCUQ", MT_TXQ_MCU }, 268 { "MCUFWQ", MT_TXQ_FWDL }, 269 }; 270 int i; 271 272 for (i = 0; i < ARRAY_SIZE(queue_map); i++) { 273 struct mt76_sw_queue *q = &dev->mt76.q_tx[queue_map[i].id]; 274 275 if (!q->q) 276 continue; 277 278 seq_printf(s, 279 "%s: queued=%d head=%d tail=%d\n", 280 queue_map[i].queue, q->q->queued, q->q->head, 281 q->q->tail); 282 } 283 284 return 0; 285 } 286 287 int mt7615_init_debugfs(struct mt7615_dev *dev) 288 { 289 struct dentry *dir; 290 291 dir = mt76_register_debugfs(&dev->mt76); 292 if (!dir) 293 return -ENOMEM; 294 295 if (is_mt7615(&dev->mt76)) 296 debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir, 297 mt7615_queues_read); 298 else 299 debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir, 300 mt76_queues_read); 301 debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir, 302 mt7615_queues_acq); 303 debugfs_create_file("ampdu_stat", 0400, dir, dev, &fops_ampdu_stat); 304 debugfs_create_file("scs", 0600, dir, dev, &fops_scs); 305 debugfs_create_file("dbdc", 0600, dir, dev, &fops_dbdc); 306 debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug); 307 debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir, 308 mt7615_radio_read); 309 debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern); 310 /* test pattern knobs */ 311 debugfs_create_u8("pattern_len", 0600, dir, 312 &dev->radar_pattern.n_pulses); 313 debugfs_create_u32("pulse_period", 0600, dir, 314 &dev->radar_pattern.period); 315 debugfs_create_u16("pulse_width", 0600, dir, 316 &dev->radar_pattern.width); 317 debugfs_create_u16("pulse_power", 0600, dir, 318 &dev->radar_pattern.power); 319 debugfs_create_file("radar_trigger", 0200, dir, dev, 320 &fops_radar_pattern); 321 debugfs_create_file("reset_test", 0200, dir, dev, 322 &fops_reset_test); 323 debugfs_create_devm_seqfile(dev->mt76.dev, "temperature", dir, 324 mt7615_read_temperature); 325 326 return 0; 327 } 328 EXPORT_SYMBOL_GPL(mt7615_init_debugfs); 329