1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * This file is part of wl18xx |
4 | * |
5 | * Copyright (C) 2009 Nokia Corporation |
6 | * Copyright (C) 2011-2012 Texas Instruments |
7 | */ |
8 | |
9 | #include <linux/pm_runtime.h> |
10 | |
11 | #include "../wlcore/debugfs.h" |
12 | #include "../wlcore/wlcore.h" |
13 | #include "../wlcore/debug.h" |
14 | #include "../wlcore/ps.h" |
15 | |
16 | #include "wl18xx.h" |
17 | #include "acx.h" |
18 | #include "cmd.h" |
19 | #include "debugfs.h" |
20 | |
21 | #define WL18XX_DEBUGFS_FWSTATS_FILE(a, b, c) \ |
22 | DEBUGFS_FWSTATS_FILE(a, b, c, wl18xx_acx_statistics) |
23 | #define WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(a, b, c) \ |
24 | DEBUGFS_FWSTATS_FILE_ARRAY(a, b, c, wl18xx_acx_statistics) |
25 | |
26 | |
27 | WL18XX_DEBUGFS_FWSTATS_FILE(error, error_frame_non_ctrl, "%u" ); |
28 | WL18XX_DEBUGFS_FWSTATS_FILE(error, error_frame_ctrl, "%u" ); |
29 | WL18XX_DEBUGFS_FWSTATS_FILE(error, error_frame_during_protection, "%u" ); |
30 | WL18XX_DEBUGFS_FWSTATS_FILE(error, null_frame_tx_start, "%u" ); |
31 | WL18XX_DEBUGFS_FWSTATS_FILE(error, null_frame_cts_start, "%u" ); |
32 | WL18XX_DEBUGFS_FWSTATS_FILE(error, bar_retry, "%u" ); |
33 | WL18XX_DEBUGFS_FWSTATS_FILE(error, num_frame_cts_nul_flid, "%u" ); |
34 | WL18XX_DEBUGFS_FWSTATS_FILE(error, tx_abort_failure, "%u" ); |
35 | WL18XX_DEBUGFS_FWSTATS_FILE(error, tx_resume_failure, "%u" ); |
36 | WL18XX_DEBUGFS_FWSTATS_FILE(error, rx_cmplt_db_overflow_cnt, "%u" ); |
37 | WL18XX_DEBUGFS_FWSTATS_FILE(error, elp_while_rx_exch, "%u" ); |
38 | WL18XX_DEBUGFS_FWSTATS_FILE(error, elp_while_tx_exch, "%u" ); |
39 | WL18XX_DEBUGFS_FWSTATS_FILE(error, elp_while_tx, "%u" ); |
40 | WL18XX_DEBUGFS_FWSTATS_FILE(error, elp_while_nvic_pending, "%u" ); |
41 | WL18XX_DEBUGFS_FWSTATS_FILE(error, rx_excessive_frame_len, "%u" ); |
42 | WL18XX_DEBUGFS_FWSTATS_FILE(error, burst_mismatch, "%u" ); |
43 | WL18XX_DEBUGFS_FWSTATS_FILE(error, tbc_exch_mismatch, "%u" ); |
44 | |
45 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_prepared_descs, "%u" ); |
46 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_cmplt, "%u" ); |
47 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_template_prepared, "%u" ); |
48 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_data_prepared, "%u" ); |
49 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_template_programmed, "%u" ); |
50 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_data_programmed, "%u" ); |
51 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_burst_programmed, "%u" ); |
52 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_starts, "%u" ); |
53 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_stop, "%u" ); |
54 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_templates, "%u" ); |
55 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_int_templates, "%u" ); |
56 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_fw_gen, "%u" ); |
57 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_data, "%u" ); |
58 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_null_frame, "%u" ); |
59 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch, "%u" ); |
60 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_retry_template, "%u" ); |
61 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_retry_data, "%u" ); |
62 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(tx, tx_retry_per_rate, |
63 | NUM_OF_RATES_INDEXES); |
64 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch_pending, "%u" ); |
65 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch_expiry, "%u" ); |
66 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_template, "%u" ); |
67 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_data, "%u" ); |
68 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_int_template, "%u" ); |
69 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_cfe1, "%u" ); |
70 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_cfe2, "%u" ); |
71 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_called, "%u" ); |
72 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_mpdu_alloc_failed, "%u" ); |
73 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_init_called, "%u" ); |
74 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_in_process_called, "%u" ); |
75 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_tkip_called, "%u" ); |
76 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_key_not_found, "%u" ); |
77 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_need_fragmentation, "%u" ); |
78 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_bad_mblk_num, "%u" ); |
79 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_failed, "%u" ); |
80 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_cache_hit, "%u" ); |
81 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_cache_miss, "%u" ); |
82 | |
83 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_beacon_early_term, "%u" ); |
84 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_out_of_mpdu_nodes, "%u" ); |
85 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_hdr_overflow, "%u" ); |
86 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_dropped_frame, "%u" ); |
87 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_done, "%u" ); |
88 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_defrag, "%u" ); |
89 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_defrag_end, "%u" ); |
90 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_cmplt, "%u" ); |
91 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_pre_complt, "%u" ); |
92 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_cmplt_task, "%u" ); |
93 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_phy_hdr, "%u" ); |
94 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_timeout, "%u" ); |
95 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_rts_timeout, "%u" ); |
96 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_timeout_wa, "%u" ); |
97 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_called, "%u" ); |
98 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_init_called, "%u" ); |
99 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_in_process_called, "%u" ); |
100 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_tkip_called, "%u" ); |
101 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_need_defrag, "%u" ); |
102 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_decrypt_failed, "%u" ); |
103 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, decrypt_key_not_found, "%u" ); |
104 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_need_decrypt, "%u" ); |
105 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_tkip_replays, "%u" ); |
106 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_xfr, "%u" ); |
107 | |
108 | WL18XX_DEBUGFS_FWSTATS_FILE(isr, irqs, "%u" ); |
109 | |
110 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, missing_bcns_cnt, "%u" ); |
111 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_bcns_cnt, "%u" ); |
112 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, connection_out_of_sync, "%u" ); |
113 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(pwr, cont_miss_bcns_spread, |
114 | PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD); |
115 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_bcns_cnt, "%u" ); |
116 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, sleep_time_count, "%u" ); |
117 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, sleep_time_avg, "%u" ); |
118 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, sleep_cycle_avg, "%u" ); |
119 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, sleep_percent, "%u" ); |
120 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, ap_sleep_active_conf, "%u" ); |
121 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, ap_sleep_user_conf, "%u" ); |
122 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, ap_sleep_counter, "%u" ); |
123 | |
124 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, beacon_filter, "%u" ); |
125 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, arp_filter, "%u" ); |
126 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, mc_filter, "%u" ); |
127 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, dup_filter, "%u" ); |
128 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, data_filter, "%u" ); |
129 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, ibss_filter, "%u" ); |
130 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, protection_filter, "%u" ); |
131 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, accum_arp_pend_requests, "%u" ); |
132 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, max_arp_queue_dep, "%u" ); |
133 | |
134 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(rx_rate, rx_frames_per_rates, 50); |
135 | |
136 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, tx_agg_rate, |
137 | AGGR_STATS_TX_AGG); |
138 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, tx_agg_len, |
139 | AGGR_STATS_TX_AGG); |
140 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, rx_size, |
141 | AGGR_STATS_RX_SIZE_LEN); |
142 | |
143 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, hs_tx_stat_fifo_int, "%u" ); |
144 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, enc_tx_stat_fifo_int, "%u" ); |
145 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, enc_rx_stat_fifo_int, "%u" ); |
146 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, rx_complete_stat_fifo_int, "%u" ); |
147 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, pre_proc_swi, "%u" ); |
148 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, post_proc_swi, "%u" ); |
149 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, sec_frag_swi, "%u" ); |
150 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, pre_to_defrag_swi, "%u" ); |
151 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, defrag_to_rx_xfer_swi, "%u" ); |
152 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_in, "%u" ); |
153 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_in_fifo_full, "%u" ); |
154 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_out, "%u" ); |
155 | |
156 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(pipeline, pipeline_fifo_full, |
157 | PIPE_STATS_HW_FIFO); |
158 | |
159 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(diversity, num_of_packets_per_ant, |
160 | DIVERSITY_STATS_NUM_OF_ANT); |
161 | WL18XX_DEBUGFS_FWSTATS_FILE(diversity, total_num_of_toggles, "%u" ); |
162 | |
163 | WL18XX_DEBUGFS_FWSTATS_FILE(thermal, irq_thr_low, "%u" ); |
164 | WL18XX_DEBUGFS_FWSTATS_FILE(thermal, irq_thr_high, "%u" ); |
165 | WL18XX_DEBUGFS_FWSTATS_FILE(thermal, tx_stop, "%u" ); |
166 | WL18XX_DEBUGFS_FWSTATS_FILE(thermal, tx_resume, "%u" ); |
167 | WL18XX_DEBUGFS_FWSTATS_FILE(thermal, false_irq, "%u" ); |
168 | WL18XX_DEBUGFS_FWSTATS_FILE(thermal, adc_source_unexpected, "%u" ); |
169 | |
170 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(calib, fail_count, |
171 | WL18XX_NUM_OF_CALIBRATIONS_ERRORS); |
172 | WL18XX_DEBUGFS_FWSTATS_FILE(calib, calib_count, "%u" ); |
173 | |
174 | WL18XX_DEBUGFS_FWSTATS_FILE(roaming, rssi_level, "%d" ); |
175 | |
176 | WL18XX_DEBUGFS_FWSTATS_FILE(dfs, num_of_radar_detections, "%d" ); |
177 | |
178 | static ssize_t conf_read(struct file *file, char __user *user_buf, |
179 | size_t count, loff_t *ppos) |
180 | { |
181 | struct wl1271 *wl = file->private_data; |
182 | struct wl18xx_priv *priv = wl->priv; |
183 | struct wlcore_conf_header ; |
184 | char *buf, *pos; |
185 | size_t len; |
186 | int ret; |
187 | |
188 | len = WL18XX_CONF_SIZE; |
189 | buf = kmalloc(size: len, GFP_KERNEL); |
190 | if (!buf) |
191 | return -ENOMEM; |
192 | |
193 | header.magic = cpu_to_le32(WL18XX_CONF_MAGIC); |
194 | header.version = cpu_to_le32(WL18XX_CONF_VERSION); |
195 | header.checksum = 0; |
196 | |
197 | mutex_lock(&wl->mutex); |
198 | |
199 | pos = buf; |
200 | memcpy(pos, &header, sizeof(header)); |
201 | pos += sizeof(header); |
202 | memcpy(pos, &wl->conf, sizeof(wl->conf)); |
203 | pos += sizeof(wl->conf); |
204 | memcpy(pos, &priv->conf, sizeof(priv->conf)); |
205 | |
206 | mutex_unlock(lock: &wl->mutex); |
207 | |
208 | ret = simple_read_from_buffer(to: user_buf, count, ppos, from: buf, available: len); |
209 | |
210 | kfree(objp: buf); |
211 | return ret; |
212 | } |
213 | |
214 | static const struct file_operations conf_ops = { |
215 | .read = conf_read, |
216 | .open = simple_open, |
217 | .llseek = default_llseek, |
218 | }; |
219 | |
220 | static ssize_t clear_fw_stats_write(struct file *file, |
221 | const char __user *user_buf, |
222 | size_t count, loff_t *ppos) |
223 | { |
224 | struct wl1271 *wl = file->private_data; |
225 | int ret; |
226 | |
227 | mutex_lock(&wl->mutex); |
228 | |
229 | if (unlikely(wl->state != WLCORE_STATE_ON)) |
230 | goto out; |
231 | |
232 | ret = wl18xx_acx_clear_statistics(wl); |
233 | if (ret < 0) { |
234 | count = ret; |
235 | goto out; |
236 | } |
237 | out: |
238 | mutex_unlock(lock: &wl->mutex); |
239 | return count; |
240 | } |
241 | |
242 | static const struct file_operations clear_fw_stats_ops = { |
243 | .write = clear_fw_stats_write, |
244 | .open = simple_open, |
245 | .llseek = default_llseek, |
246 | }; |
247 | |
248 | static ssize_t radar_detection_write(struct file *file, |
249 | const char __user *user_buf, |
250 | size_t count, loff_t *ppos) |
251 | { |
252 | struct wl1271 *wl = file->private_data; |
253 | int ret; |
254 | u8 channel; |
255 | |
256 | ret = kstrtou8_from_user(s: user_buf, count, base: 10, res: &channel); |
257 | if (ret < 0) { |
258 | wl1271_warning("illegal channel" ); |
259 | return -EINVAL; |
260 | } |
261 | |
262 | mutex_lock(&wl->mutex); |
263 | |
264 | if (unlikely(wl->state != WLCORE_STATE_ON)) |
265 | goto out; |
266 | |
267 | ret = pm_runtime_resume_and_get(dev: wl->dev); |
268 | if (ret < 0) |
269 | goto out; |
270 | |
271 | ret = wl18xx_cmd_radar_detection_debug(wl, channel); |
272 | if (ret < 0) |
273 | count = ret; |
274 | |
275 | pm_runtime_mark_last_busy(dev: wl->dev); |
276 | pm_runtime_put_autosuspend(dev: wl->dev); |
277 | out: |
278 | mutex_unlock(lock: &wl->mutex); |
279 | return count; |
280 | } |
281 | |
282 | static const struct file_operations radar_detection_ops = { |
283 | .write = radar_detection_write, |
284 | .open = simple_open, |
285 | .llseek = default_llseek, |
286 | }; |
287 | |
288 | static ssize_t dynamic_fw_traces_write(struct file *file, |
289 | const char __user *user_buf, |
290 | size_t count, loff_t *ppos) |
291 | { |
292 | struct wl1271 *wl = file->private_data; |
293 | unsigned long value; |
294 | int ret; |
295 | |
296 | ret = kstrtoul_from_user(s: user_buf, count, base: 0, res: &value); |
297 | if (ret < 0) |
298 | return ret; |
299 | |
300 | mutex_lock(&wl->mutex); |
301 | |
302 | wl->dynamic_fw_traces = value; |
303 | |
304 | if (unlikely(wl->state != WLCORE_STATE_ON)) |
305 | goto out; |
306 | |
307 | ret = pm_runtime_resume_and_get(dev: wl->dev); |
308 | if (ret < 0) |
309 | goto out; |
310 | |
311 | ret = wl18xx_acx_dynamic_fw_traces(wl); |
312 | if (ret < 0) |
313 | count = ret; |
314 | |
315 | pm_runtime_mark_last_busy(dev: wl->dev); |
316 | pm_runtime_put_autosuspend(dev: wl->dev); |
317 | out: |
318 | mutex_unlock(lock: &wl->mutex); |
319 | return count; |
320 | } |
321 | |
322 | static ssize_t dynamic_fw_traces_read(struct file *file, |
323 | char __user *userbuf, |
324 | size_t count, loff_t *ppos) |
325 | { |
326 | struct wl1271 *wl = file->private_data; |
327 | return wl1271_format_buffer(userbuf, count, ppos, |
328 | fmt: "%d\n" , wl->dynamic_fw_traces); |
329 | } |
330 | |
331 | static const struct file_operations dynamic_fw_traces_ops = { |
332 | .read = dynamic_fw_traces_read, |
333 | .write = dynamic_fw_traces_write, |
334 | .open = simple_open, |
335 | .llseek = default_llseek, |
336 | }; |
337 | |
338 | #ifdef CONFIG_CFG80211_CERTIFICATION_ONUS |
339 | static ssize_t radar_debug_mode_write(struct file *file, |
340 | const char __user *user_buf, |
341 | size_t count, loff_t *ppos) |
342 | { |
343 | struct wl1271 *wl = file->private_data; |
344 | struct wl12xx_vif *wlvif; |
345 | unsigned long value; |
346 | int ret; |
347 | |
348 | ret = kstrtoul_from_user(s: user_buf, count, base: 10, res: &value); |
349 | if (ret < 0) { |
350 | wl1271_warning("illegal radar_debug_mode value!" ); |
351 | return -EINVAL; |
352 | } |
353 | |
354 | /* valid values: 0/1 */ |
355 | if (!(value == 0 || value == 1)) { |
356 | wl1271_warning("value is not in valid!" ); |
357 | return -EINVAL; |
358 | } |
359 | |
360 | mutex_lock(&wl->mutex); |
361 | |
362 | wl->radar_debug_mode = value; |
363 | |
364 | if (unlikely(wl->state != WLCORE_STATE_ON)) |
365 | goto out; |
366 | |
367 | ret = pm_runtime_resume_and_get(dev: wl->dev); |
368 | if (ret < 0) |
369 | goto out; |
370 | |
371 | wl12xx_for_each_wlvif_ap(wl, wlvif) { |
372 | wlcore_cmd_generic_cfg(wl, wlvif, |
373 | feature: WLCORE_CFG_FEATURE_RADAR_DEBUG, |
374 | enable: wl->radar_debug_mode, value: 0); |
375 | } |
376 | |
377 | pm_runtime_mark_last_busy(dev: wl->dev); |
378 | pm_runtime_put_autosuspend(dev: wl->dev); |
379 | out: |
380 | mutex_unlock(lock: &wl->mutex); |
381 | return count; |
382 | } |
383 | |
384 | static ssize_t radar_debug_mode_read(struct file *file, |
385 | char __user *userbuf, |
386 | size_t count, loff_t *ppos) |
387 | { |
388 | struct wl1271 *wl = file->private_data; |
389 | |
390 | return wl1271_format_buffer(userbuf, count, ppos, |
391 | fmt: "%d\n" , wl->radar_debug_mode); |
392 | } |
393 | |
394 | static const struct file_operations radar_debug_mode_ops = { |
395 | .write = radar_debug_mode_write, |
396 | .read = radar_debug_mode_read, |
397 | .open = simple_open, |
398 | .llseek = default_llseek, |
399 | }; |
400 | #endif /* CFG80211_CERTIFICATION_ONUS */ |
401 | |
402 | int wl18xx_debugfs_add_files(struct wl1271 *wl, |
403 | struct dentry *rootdir) |
404 | { |
405 | struct dentry *stats, *moddir; |
406 | |
407 | moddir = debugfs_create_dir(KBUILD_MODNAME, parent: rootdir); |
408 | stats = debugfs_create_dir(name: "fw_stats" , parent: moddir); |
409 | |
410 | DEBUGFS_ADD(clear_fw_stats, stats); |
411 | |
412 | DEBUGFS_FWSTATS_ADD(error, error_frame_non_ctrl); |
413 | DEBUGFS_FWSTATS_ADD(error, error_frame_ctrl); |
414 | DEBUGFS_FWSTATS_ADD(error, error_frame_during_protection); |
415 | DEBUGFS_FWSTATS_ADD(error, null_frame_tx_start); |
416 | DEBUGFS_FWSTATS_ADD(error, null_frame_cts_start); |
417 | DEBUGFS_FWSTATS_ADD(error, bar_retry); |
418 | DEBUGFS_FWSTATS_ADD(error, num_frame_cts_nul_flid); |
419 | DEBUGFS_FWSTATS_ADD(error, tx_abort_failure); |
420 | DEBUGFS_FWSTATS_ADD(error, tx_resume_failure); |
421 | DEBUGFS_FWSTATS_ADD(error, rx_cmplt_db_overflow_cnt); |
422 | DEBUGFS_FWSTATS_ADD(error, elp_while_rx_exch); |
423 | DEBUGFS_FWSTATS_ADD(error, elp_while_tx_exch); |
424 | DEBUGFS_FWSTATS_ADD(error, elp_while_tx); |
425 | DEBUGFS_FWSTATS_ADD(error, elp_while_nvic_pending); |
426 | DEBUGFS_FWSTATS_ADD(error, rx_excessive_frame_len); |
427 | DEBUGFS_FWSTATS_ADD(error, burst_mismatch); |
428 | DEBUGFS_FWSTATS_ADD(error, tbc_exch_mismatch); |
429 | |
430 | DEBUGFS_FWSTATS_ADD(tx, tx_prepared_descs); |
431 | DEBUGFS_FWSTATS_ADD(tx, tx_cmplt); |
432 | DEBUGFS_FWSTATS_ADD(tx, tx_template_prepared); |
433 | DEBUGFS_FWSTATS_ADD(tx, tx_data_prepared); |
434 | DEBUGFS_FWSTATS_ADD(tx, tx_template_programmed); |
435 | DEBUGFS_FWSTATS_ADD(tx, tx_data_programmed); |
436 | DEBUGFS_FWSTATS_ADD(tx, tx_burst_programmed); |
437 | DEBUGFS_FWSTATS_ADD(tx, tx_starts); |
438 | DEBUGFS_FWSTATS_ADD(tx, tx_stop); |
439 | DEBUGFS_FWSTATS_ADD(tx, tx_start_templates); |
440 | DEBUGFS_FWSTATS_ADD(tx, tx_start_int_templates); |
441 | DEBUGFS_FWSTATS_ADD(tx, tx_start_fw_gen); |
442 | DEBUGFS_FWSTATS_ADD(tx, tx_start_data); |
443 | DEBUGFS_FWSTATS_ADD(tx, tx_start_null_frame); |
444 | DEBUGFS_FWSTATS_ADD(tx, tx_exch); |
445 | DEBUGFS_FWSTATS_ADD(tx, tx_retry_template); |
446 | DEBUGFS_FWSTATS_ADD(tx, tx_retry_data); |
447 | DEBUGFS_FWSTATS_ADD(tx, tx_retry_per_rate); |
448 | DEBUGFS_FWSTATS_ADD(tx, tx_exch_pending); |
449 | DEBUGFS_FWSTATS_ADD(tx, tx_exch_expiry); |
450 | DEBUGFS_FWSTATS_ADD(tx, tx_done_template); |
451 | DEBUGFS_FWSTATS_ADD(tx, tx_done_data); |
452 | DEBUGFS_FWSTATS_ADD(tx, tx_done_int_template); |
453 | DEBUGFS_FWSTATS_ADD(tx, tx_cfe1); |
454 | DEBUGFS_FWSTATS_ADD(tx, tx_cfe2); |
455 | DEBUGFS_FWSTATS_ADD(tx, frag_called); |
456 | DEBUGFS_FWSTATS_ADD(tx, frag_mpdu_alloc_failed); |
457 | DEBUGFS_FWSTATS_ADD(tx, frag_init_called); |
458 | DEBUGFS_FWSTATS_ADD(tx, frag_in_process_called); |
459 | DEBUGFS_FWSTATS_ADD(tx, frag_tkip_called); |
460 | DEBUGFS_FWSTATS_ADD(tx, frag_key_not_found); |
461 | DEBUGFS_FWSTATS_ADD(tx, frag_need_fragmentation); |
462 | DEBUGFS_FWSTATS_ADD(tx, frag_bad_mblk_num); |
463 | DEBUGFS_FWSTATS_ADD(tx, frag_failed); |
464 | DEBUGFS_FWSTATS_ADD(tx, frag_cache_hit); |
465 | DEBUGFS_FWSTATS_ADD(tx, frag_cache_miss); |
466 | |
467 | DEBUGFS_FWSTATS_ADD(rx, rx_beacon_early_term); |
468 | DEBUGFS_FWSTATS_ADD(rx, rx_out_of_mpdu_nodes); |
469 | DEBUGFS_FWSTATS_ADD(rx, rx_hdr_overflow); |
470 | DEBUGFS_FWSTATS_ADD(rx, rx_dropped_frame); |
471 | DEBUGFS_FWSTATS_ADD(rx, rx_done); |
472 | DEBUGFS_FWSTATS_ADD(rx, rx_defrag); |
473 | DEBUGFS_FWSTATS_ADD(rx, rx_defrag_end); |
474 | DEBUGFS_FWSTATS_ADD(rx, rx_cmplt); |
475 | DEBUGFS_FWSTATS_ADD(rx, rx_pre_complt); |
476 | DEBUGFS_FWSTATS_ADD(rx, rx_cmplt_task); |
477 | DEBUGFS_FWSTATS_ADD(rx, rx_phy_hdr); |
478 | DEBUGFS_FWSTATS_ADD(rx, rx_timeout); |
479 | DEBUGFS_FWSTATS_ADD(rx, rx_rts_timeout); |
480 | DEBUGFS_FWSTATS_ADD(rx, rx_timeout_wa); |
481 | DEBUGFS_FWSTATS_ADD(rx, defrag_called); |
482 | DEBUGFS_FWSTATS_ADD(rx, defrag_init_called); |
483 | DEBUGFS_FWSTATS_ADD(rx, defrag_in_process_called); |
484 | DEBUGFS_FWSTATS_ADD(rx, defrag_tkip_called); |
485 | DEBUGFS_FWSTATS_ADD(rx, defrag_need_defrag); |
486 | DEBUGFS_FWSTATS_ADD(rx, defrag_decrypt_failed); |
487 | DEBUGFS_FWSTATS_ADD(rx, decrypt_key_not_found); |
488 | DEBUGFS_FWSTATS_ADD(rx, defrag_need_decrypt); |
489 | DEBUGFS_FWSTATS_ADD(rx, rx_tkip_replays); |
490 | DEBUGFS_FWSTATS_ADD(rx, rx_xfr); |
491 | |
492 | DEBUGFS_FWSTATS_ADD(isr, irqs); |
493 | |
494 | DEBUGFS_FWSTATS_ADD(pwr, missing_bcns_cnt); |
495 | DEBUGFS_FWSTATS_ADD(pwr, rcvd_bcns_cnt); |
496 | DEBUGFS_FWSTATS_ADD(pwr, connection_out_of_sync); |
497 | DEBUGFS_FWSTATS_ADD(pwr, cont_miss_bcns_spread); |
498 | DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_bcns_cnt); |
499 | DEBUGFS_FWSTATS_ADD(pwr, sleep_time_count); |
500 | DEBUGFS_FWSTATS_ADD(pwr, sleep_time_avg); |
501 | DEBUGFS_FWSTATS_ADD(pwr, sleep_cycle_avg); |
502 | DEBUGFS_FWSTATS_ADD(pwr, sleep_percent); |
503 | DEBUGFS_FWSTATS_ADD(pwr, ap_sleep_active_conf); |
504 | DEBUGFS_FWSTATS_ADD(pwr, ap_sleep_user_conf); |
505 | DEBUGFS_FWSTATS_ADD(pwr, ap_sleep_counter); |
506 | |
507 | DEBUGFS_FWSTATS_ADD(rx_filter, beacon_filter); |
508 | DEBUGFS_FWSTATS_ADD(rx_filter, arp_filter); |
509 | DEBUGFS_FWSTATS_ADD(rx_filter, mc_filter); |
510 | DEBUGFS_FWSTATS_ADD(rx_filter, dup_filter); |
511 | DEBUGFS_FWSTATS_ADD(rx_filter, data_filter); |
512 | DEBUGFS_FWSTATS_ADD(rx_filter, ibss_filter); |
513 | DEBUGFS_FWSTATS_ADD(rx_filter, protection_filter); |
514 | DEBUGFS_FWSTATS_ADD(rx_filter, accum_arp_pend_requests); |
515 | DEBUGFS_FWSTATS_ADD(rx_filter, max_arp_queue_dep); |
516 | |
517 | DEBUGFS_FWSTATS_ADD(rx_rate, rx_frames_per_rates); |
518 | |
519 | DEBUGFS_FWSTATS_ADD(aggr_size, tx_agg_rate); |
520 | DEBUGFS_FWSTATS_ADD(aggr_size, tx_agg_len); |
521 | DEBUGFS_FWSTATS_ADD(aggr_size, rx_size); |
522 | |
523 | DEBUGFS_FWSTATS_ADD(pipeline, hs_tx_stat_fifo_int); |
524 | DEBUGFS_FWSTATS_ADD(pipeline, enc_tx_stat_fifo_int); |
525 | DEBUGFS_FWSTATS_ADD(pipeline, enc_rx_stat_fifo_int); |
526 | DEBUGFS_FWSTATS_ADD(pipeline, rx_complete_stat_fifo_int); |
527 | DEBUGFS_FWSTATS_ADD(pipeline, pre_proc_swi); |
528 | DEBUGFS_FWSTATS_ADD(pipeline, post_proc_swi); |
529 | DEBUGFS_FWSTATS_ADD(pipeline, sec_frag_swi); |
530 | DEBUGFS_FWSTATS_ADD(pipeline, pre_to_defrag_swi); |
531 | DEBUGFS_FWSTATS_ADD(pipeline, defrag_to_rx_xfer_swi); |
532 | DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_in); |
533 | DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_in_fifo_full); |
534 | DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_out); |
535 | DEBUGFS_FWSTATS_ADD(pipeline, pipeline_fifo_full); |
536 | |
537 | DEBUGFS_FWSTATS_ADD(diversity, num_of_packets_per_ant); |
538 | DEBUGFS_FWSTATS_ADD(diversity, total_num_of_toggles); |
539 | |
540 | DEBUGFS_FWSTATS_ADD(thermal, irq_thr_low); |
541 | DEBUGFS_FWSTATS_ADD(thermal, irq_thr_high); |
542 | DEBUGFS_FWSTATS_ADD(thermal, tx_stop); |
543 | DEBUGFS_FWSTATS_ADD(thermal, tx_resume); |
544 | DEBUGFS_FWSTATS_ADD(thermal, false_irq); |
545 | DEBUGFS_FWSTATS_ADD(thermal, adc_source_unexpected); |
546 | |
547 | DEBUGFS_FWSTATS_ADD(calib, fail_count); |
548 | |
549 | DEBUGFS_FWSTATS_ADD(calib, calib_count); |
550 | |
551 | DEBUGFS_FWSTATS_ADD(roaming, rssi_level); |
552 | |
553 | DEBUGFS_FWSTATS_ADD(dfs, num_of_radar_detections); |
554 | |
555 | DEBUGFS_ADD(conf, moddir); |
556 | DEBUGFS_ADD(radar_detection, moddir); |
557 | #ifdef CONFIG_CFG80211_CERTIFICATION_ONUS |
558 | DEBUGFS_ADD(radar_debug_mode, moddir); |
559 | #endif |
560 | DEBUGFS_ADD(dynamic_fw_traces, moddir); |
561 | |
562 | return 0; |
563 | } |
564 | |