1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2020 MediaTek Inc. */
9 /* test knob of system layer 1/2 error recovery */
10 static int mt7915_ser_trigger_set(void *data
, u64 val
)
13 SER_SET_RECOVER_L1
= 1,
18 struct mt7915_dev
*dev
= data
;
22 case SER_SET_RECOVER_L1
:
23 case SER_SET_RECOVER_L2
:
24 ret
= mt7915_mcu_set_ser(dev
, SER_ENABLE
, BIT(val
), 0);
28 return mt7915_mcu_set_ser(dev
, SER_RECOVER
, val
, 0);
36 DEFINE_DEBUGFS_ATTRIBUTE(fops_ser_trigger
, NULL
,
37 mt7915_ser_trigger_set
, "%lld\n");
40 mt7915_radar_trigger(void *data
, u64 val
)
42 struct mt7915_dev
*dev
= data
;
44 return mt7915_mcu_rdd_cmd(dev
, RDD_RADAR_EMULATE
, 1, 0, 0);
47 DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_trigger
, NULL
,
48 mt7915_radar_trigger
, "%lld\n");
51 mt7915_fw_debug_set(void *data
, u64 val
)
53 struct mt7915_dev
*dev
= data
;
62 dev
->fw_debug
= !!val
;
64 mt7915_mcu_fw_log_2_host(dev
, dev
->fw_debug
? 2 : 0);
66 for (debug
= DEBUG_TXCMD
; debug
<= DEBUG_RPT_RX
; debug
++)
67 mt7915_mcu_fw_dbg_ctrl(dev
, debug
, dev
->fw_debug
);
73 mt7915_fw_debug_get(void *data
, u64
*val
)
75 struct mt7915_dev
*dev
= data
;
82 DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug
, mt7915_fw_debug_get
,
83 mt7915_fw_debug_set
, "%lld\n");
86 mt7915_ampdu_stat_read_phy(struct mt7915_phy
*phy
,
87 struct seq_file
*file
)
89 struct mt7915_dev
*dev
= file
->private;
90 bool ext_phy
= phy
!= &dev
->phy
;
91 int bound
[15], range
[4], i
, n
;
97 for (i
= 0; i
< ARRAY_SIZE(range
); i
++)
98 range
[i
] = mt76_rr(dev
, MT_MIB_ARNG(ext_phy
, i
));
100 for (i
= 0; i
< ARRAY_SIZE(bound
); i
++)
101 bound
[i
] = MT_MIB_ARNCR_RANGE(range
[i
/ 4], i
) + 1;
103 seq_printf(file
, "\nPhy %d\n", ext_phy
);
105 seq_printf(file
, "Length: %8d | ", bound
[0]);
106 for (i
= 0; i
< ARRAY_SIZE(bound
) - 1; i
++)
107 seq_printf(file
, "%3d -%3d | ",
108 bound
[i
] + 1, bound
[i
+ 1]);
110 seq_puts(file
, "\nCount: ");
111 n
= ext_phy
? ARRAY_SIZE(dev
->mt76
.aggr_stats
) / 2 : 0;
112 for (i
= 0; i
< ARRAY_SIZE(bound
); i
++)
113 seq_printf(file
, "%8d | ", dev
->mt76
.aggr_stats
[i
+ n
]);
114 seq_puts(file
, "\n");
116 seq_printf(file
, "BA miss count: %d\n", phy
->mib
.ba_miss_cnt
);
120 mt7915_txbf_stat_read_phy(struct mt7915_phy
*phy
, struct seq_file
*s
)
122 struct mt7915_dev
*dev
= s
->private;
123 bool ext_phy
= phy
!= &dev
->phy
;
129 /* Tx Beamformer monitor */
130 seq_puts(s
, "\nTx Beamformer applied PPDU counts: ");
132 cnt
= mt76_rr(dev
, MT_ETBF_TX_APP_CNT(ext_phy
));
133 seq_printf(s
, "iBF: %ld, eBF: %ld\n",
134 FIELD_GET(MT_ETBF_TX_IBF_CNT
, cnt
),
135 FIELD_GET(MT_ETBF_TX_EBF_CNT
, cnt
));
137 /* Tx Beamformer Rx feedback monitor */
138 seq_puts(s
, "Tx Beamformer Rx feedback statistics: ");
140 cnt
= mt76_rr(dev
, MT_ETBF_RX_FB_CNT(ext_phy
));
141 seq_printf(s
, "All: %ld, HE: %ld, VHT: %ld, HT: %ld\n",
142 FIELD_GET(MT_ETBF_RX_FB_ALL
, cnt
),
143 FIELD_GET(MT_ETBF_RX_FB_HE
, cnt
),
144 FIELD_GET(MT_ETBF_RX_FB_VHT
, cnt
),
145 FIELD_GET(MT_ETBF_RX_FB_HT
, cnt
));
147 /* Tx Beamformee Rx NDPA & Tx feedback report */
148 cnt
= mt76_rr(dev
, MT_ETBF_TX_NDP_BFRP(ext_phy
));
149 seq_printf(s
, "Tx Beamformee successful feedback frames: %ld\n",
150 FIELD_GET(MT_ETBF_TX_FB_CPL
, cnt
));
151 seq_printf(s
, "Tx Beamformee feedback triggered counts: %ld\n",
152 FIELD_GET(MT_ETBF_TX_FB_TRI
, cnt
));
154 /* Tx SU & MU counters */
155 cnt
= mt76_rr(dev
, MT_MIB_SDR34(ext_phy
));
156 seq_printf(s
, "Tx multi-user Beamforming counts: %ld\n",
157 FIELD_GET(MT_MIB_MU_BF_TX_CNT
, cnt
));
158 cnt
= mt76_rr(dev
, MT_MIB_DR8(ext_phy
));
159 seq_printf(s
, "Tx multi-user MPDU counts: %d\n", cnt
);
160 cnt
= mt76_rr(dev
, MT_MIB_DR9(ext_phy
));
161 seq_printf(s
, "Tx multi-user successful MPDU counts: %d\n", cnt
);
162 cnt
= mt76_rr(dev
, MT_MIB_DR11(ext_phy
));
163 seq_printf(s
, "Tx single-user successful MPDU counts: %d\n", cnt
);
169 mt7915_tx_stats_read(struct seq_file
*file
, void *data
)
171 struct mt7915_dev
*dev
= file
->private;
174 mt7915_ampdu_stat_read_phy(&dev
->phy
, file
);
175 mt7915_txbf_stat_read_phy(&dev
->phy
, file
);
177 mt7915_ampdu_stat_read_phy(mt7915_ext_phy(dev
), file
);
178 mt7915_txbf_stat_read_phy(mt7915_ext_phy(dev
), file
);
181 seq_puts(file
, "Tx MSDU stat:\n");
182 for (i
= 0, n
= 0; i
< ARRAY_SIZE(stat
); i
++) {
183 stat
[i
] = mt76_rr(dev
, MT_PLE_AMSDU_PACK_MSDU_CNT(i
));
187 for (i
= 0; i
< ARRAY_SIZE(stat
); i
++) {
188 seq_printf(file
, "AMSDU pack count of %d MSDU in TXD: 0x%x ",
191 seq_printf(file
, "(%d%%)\n", stat
[i
] * 100 / n
);
193 seq_puts(file
, "\n");
200 mt7915_tx_stats_open(struct inode
*inode
, struct file
*f
)
202 return single_open(f
, mt7915_tx_stats_read
, inode
->i_private
);
205 static const struct file_operations fops_tx_stats
= {
206 .open
= mt7915_tx_stats_open
,
209 .release
= single_release
,
210 .owner
= THIS_MODULE
,
213 static int mt7915_read_temperature(struct seq_file
*s
, void *data
)
215 struct mt7915_dev
*dev
= dev_get_drvdata(s
->private);
219 temp
= mt7915_mcu_get_temperature(dev
, 0);
220 seq_printf(s
, "Temperature: %d\n", temp
);
226 mt7915_queues_acq(struct seq_file
*s
, void *data
)
228 struct mt7915_dev
*dev
= dev_get_drvdata(s
->private);
231 for (i
= 0; i
< 16; i
++) {
232 int j
, acs
= i
/ 4, index
= i
% 4;
233 u32 ctrl
, val
, qlen
= 0;
235 val
= mt76_rr(dev
, MT_PLE_AC_QEMPTY(acs
, index
));
236 ctrl
= BIT(31) | BIT(15) | (acs
<< 8);
238 for (j
= 0; j
< 32; j
++) {
242 mt76_wr(dev
, MT_PLE_FL_Q0_CTRL
,
243 ctrl
| (j
+ (index
<< 5)));
244 qlen
+= mt76_get_field(dev
, MT_PLE_FL_Q3_CTRL
,
247 seq_printf(s
, "AC%d%d: queued=%d\n", acs
, index
, qlen
);
254 mt7915_queues_read(struct seq_file
*s
, void *data
)
256 struct mt7915_dev
*dev
= dev_get_drvdata(s
->private);
257 struct mt76_phy
*mphy_ext
= dev
->mt76
.phy2
;
258 struct mt76_queue
*ext_q
= mphy_ext
? mphy_ext
->q_tx
[MT_TXQ_BE
] : NULL
;
260 struct mt76_queue
*q
;
263 { dev
->mphy
.q_tx
[MT_TXQ_BE
], "WFDMA0" },
265 { dev
->mphy
.q_tx
[MT_TXQ_BE
], "WFDMA0" },
266 { dev
->mt76
.q_mcu
[MT_MCUQ_WM
], "MCUWM" },
267 { dev
->mt76
.q_mcu
[MT_MCUQ_WA
], "MCUWA" },
268 { dev
->mt76
.q_mcu
[MT_MCUQ_FWDL
], "MCUFWQ" },
272 for (i
= 0; i
< ARRAY_SIZE(queue_map
); i
++) {
273 struct mt76_queue
*q
= queue_map
[i
].q
;
279 "%s: queued=%d head=%d tail=%d\n",
280 queue_map
[i
].queue
, q
->queued
, q
->head
,
288 mt7915_puts_rate_txpower(struct seq_file
*s
, s8
*delta
,
289 s8 txpower_cur
, int band
)
291 static const char * const sku_group_name
[] = {
292 "CCK", "OFDM", "HT20", "HT40",
293 "VHT20", "VHT40", "VHT80", "VHT160",
294 "RU26", "RU52", "RU106", "RU242/SU20",
295 "RU484/SU40", "RU996/SU80", "RU2x996/SU160"
297 s8 txpower
[MT7915_SKU_RATE_NUM
];
300 for (i
= 0; i
< MT7915_SKU_RATE_NUM
; i
++)
301 txpower
[i
] = DIV_ROUND_UP(txpower_cur
+ delta
[i
], 2);
303 for (i
= 0; i
< MAX_SKU_RATE_GROUP_NUM
; i
++) {
304 const struct sku_group
*sku
= &mt7915_sku_groups
[i
];
305 u32 offset
= sku
->offset
[band
];
312 mt76_seq_puts_array(s
, sku_group_name
[i
],
313 txpower
+ idx
, sku
->len
);
319 mt7915_read_rate_txpower(struct seq_file
*s
, void *data
)
321 struct mt7915_dev
*dev
= dev_get_drvdata(s
->private);
322 struct mt76_phy
*mphy
= &dev
->mphy
;
323 enum nl80211_band band
= mphy
->chandef
.chan
->band
;
324 s8
*delta
= dev
->rate_power
[band
];
325 s8 txpower_base
= mphy
->txpower_cur
- delta
[MT7915_SKU_MAX_DELTA_IDX
];
327 seq_puts(s
, "Band 0:\n");
328 mt7915_puts_rate_txpower(s
, delta
, txpower_base
, band
);
330 if (dev
->mt76
.phy2
) {
331 mphy
= dev
->mt76
.phy2
;
332 band
= mphy
->chandef
.chan
->band
;
333 delta
= dev
->rate_power
[band
];
334 txpower_base
= mphy
->txpower_cur
-
335 delta
[MT7915_SKU_MAX_DELTA_IDX
];
337 seq_puts(s
, "Band 1:\n");
338 mt7915_puts_rate_txpower(s
, delta
, txpower_base
, band
);
344 int mt7915_init_debugfs(struct mt7915_dev
*dev
)
348 dir
= mt76_register_debugfs(&dev
->mt76
);
352 debugfs_create_devm_seqfile(dev
->mt76
.dev
, "queues", dir
,
354 debugfs_create_devm_seqfile(dev
->mt76
.dev
, "acq", dir
,
356 debugfs_create_file("tx_stats", 0400, dir
, dev
, &fops_tx_stats
);
357 debugfs_create_file("fw_debug", 0600, dir
, dev
, &fops_fw_debug
);
358 debugfs_create_u32("dfs_hw_pattern", 0400, dir
, &dev
->hw_pattern
);
360 debugfs_create_file("radar_trigger", 0200, dir
, dev
,
361 &fops_radar_trigger
);
362 debugfs_create_file("ser_trigger", 0200, dir
, dev
, &fops_ser_trigger
);
363 debugfs_create_devm_seqfile(dev
->mt76
.dev
, "temperature", dir
,
364 mt7915_read_temperature
);
365 debugfs_create_devm_seqfile(dev
->mt76
.dev
, "txpower_sku", dir
,
366 mt7915_read_rate_txpower
);
371 #ifdef CONFIG_MAC80211_DEBUGFS
372 /** per-station debugfs **/
374 /* usage: <tx mode> <ldpc> <stbc> <bw> <gi> <nss> <mcs> */
375 static int mt7915_sta_fixed_rate_set(void *data
, u64 rate
)
377 struct ieee80211_sta
*sta
= data
;
378 struct mt7915_sta
*msta
= (struct mt7915_sta
*)sta
->drv_priv
;
380 return mt7915_mcu_set_fixed_rate(msta
->vif
->phy
->dev
, sta
, rate
);
383 DEFINE_DEBUGFS_ATTRIBUTE(fops_fixed_rate
, NULL
,
384 mt7915_sta_fixed_rate_set
, "%llx\n");
387 mt7915_sta_stats_read(struct seq_file
*s
, void *data
)
389 struct ieee80211_sta
*sta
= s
->private;
390 struct mt7915_sta
*msta
= (struct mt7915_sta
*)sta
->drv_priv
;
391 struct mt7915_sta_stats
*stats
= &msta
->stats
;
392 struct rate_info
*rate
= &stats
->prob_rate
;
393 static const char * const bw
[] = {
394 "BW20", "BW5", "BW10", "BW40",
395 "BW80", "BW160", "BW_HE_RU"
398 if (!rate
->legacy
&& !rate
->flags
)
401 seq_puts(s
, "Probing rate - ");
402 if (rate
->flags
& RATE_INFO_FLAGS_MCS
)
404 else if (rate
->flags
& RATE_INFO_FLAGS_VHT_MCS
)
406 else if (rate
->flags
& RATE_INFO_FLAGS_HE_MCS
)
409 seq_printf(s
, "Bitrate %d\n", rate
->legacy
);
412 seq_printf(s
, "%s NSS%d MCS%d ",
413 bw
[rate
->bw
], rate
->nss
, rate
->mcs
);
415 if (rate
->flags
& RATE_INFO_FLAGS_SHORT_GI
)
417 else if (rate
->he_gi
)
418 seq_puts(s
, "HE GI ");
424 seq_printf(s
, "\nPPDU PER: %ld.%1ld%%\n",
425 stats
->per
/ 10, stats
->per
% 10);
431 mt7915_sta_stats_open(struct inode
*inode
, struct file
*f
)
433 return single_open(f
, mt7915_sta_stats_read
, inode
->i_private
);
436 static const struct file_operations fops_sta_stats
= {
437 .open
= mt7915_sta_stats_open
,
440 .release
= single_release
,
441 .owner
= THIS_MODULE
,
444 void mt7915_sta_add_debugfs(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
445 struct ieee80211_sta
*sta
, struct dentry
*dir
)
447 debugfs_create_file("fixed_rate", 0600, dir
, sta
, &fops_fixed_rate
);
448 debugfs_create_file("stats", 0400, dir
, sta
, &fops_sta_stats
);