1 // SPDX-License-Identifier: GPL-2.0-only
2 /******************************************************************************
3  *
4  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
5  *
6  * Contact Information:
7  *  Intel Linux Wireless <ilw@linux.intel.com>
8  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
9  *****************************************************************************/
10 
11 #include "common.h"
12 #include "3945.h"
13 
14 static int
15 il3945_stats_flag(struct il_priv *il, char *buf, int bufsz)
16 {
17 	int p = 0;
18 
19 	p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
20 		       le32_to_cpu(il->_3945.stats.flag));
21 	if (le32_to_cpu(il->_3945.stats.flag) & UCODE_STATS_CLEAR_MSK)
22 		p += scnprintf(buf + p, bufsz - p,
23 			       "\tStatistics have been cleared\n");
24 	p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
25 		       (le32_to_cpu(il->_3945.stats.flag) &
26 			UCODE_STATS_FREQUENCY_MSK) ? "2.4 GHz" : "5.2 GHz");
27 	p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
28 		       (le32_to_cpu(il->_3945.stats.flag) &
29 			UCODE_STATS_NARROW_BAND_MSK) ? "enabled" : "disabled");
30 	return p;
31 }
32 
33 static ssize_t
34 il3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
35 			   size_t count, loff_t *ppos)
36 {
37 	struct il_priv *il = file->private_data;
38 	int pos = 0;
39 	char *buf;
40 	int bufsz =
41 	    sizeof(struct iwl39_stats_rx_phy) * 40 +
42 	    sizeof(struct iwl39_stats_rx_non_phy) * 40 + 400;
43 	ssize_t ret;
44 	struct iwl39_stats_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
45 	struct iwl39_stats_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
46 	struct iwl39_stats_rx_non_phy *general, *accum_general;
47 	struct iwl39_stats_rx_non_phy *delta_general, *max_general;
48 
49 	if (!il_is_alive(il))
50 		return -EAGAIN;
51 
52 	buf = kzalloc(bufsz, GFP_KERNEL);
53 	if (!buf) {
54 		IL_ERR("Can not allocate Buffer\n");
55 		return -ENOMEM;
56 	}
57 
58 	/*
59 	 * The statistic information display here is based on
60 	 * the last stats notification from uCode
61 	 * might not reflect the current uCode activity
62 	 */
63 	ofdm = &il->_3945.stats.rx.ofdm;
64 	cck = &il->_3945.stats.rx.cck;
65 	general = &il->_3945.stats.rx.general;
66 	accum_ofdm = &il->_3945.accum_stats.rx.ofdm;
67 	accum_cck = &il->_3945.accum_stats.rx.cck;
68 	accum_general = &il->_3945.accum_stats.rx.general;
69 	delta_ofdm = &il->_3945.delta_stats.rx.ofdm;
70 	delta_cck = &il->_3945.delta_stats.rx.cck;
71 	delta_general = &il->_3945.delta_stats.rx.general;
72 	max_ofdm = &il->_3945.max_delta.rx.ofdm;
73 	max_cck = &il->_3945.max_delta.rx.cck;
74 	max_general = &il->_3945.max_delta.rx.general;
75 
76 	pos += il3945_stats_flag(il, buf, bufsz);
77 	pos +=
78 	    scnprintf(buf + pos, bufsz - pos,
79 		      "%-32s     current"
80 		      "accumulative      delta         max\n",
81 		      "Statistics_Rx - OFDM:");
82 	pos +=
83 	    scnprintf(buf + pos, bufsz - pos,
84 		      "  %-30s %10u  %10u  %10u  %10u\n", "ina_cnt:",
85 		      le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt,
86 		      delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
87 	pos +=
88 	    scnprintf(buf + pos, bufsz - pos,
89 		      "  %-30s %10u  %10u  %10u  %10u\n", "fina_cnt:",
90 		      le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
91 		      delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
92 	pos +=
93 	    scnprintf(buf + pos, bufsz - pos,
94 		      "  %-30s %10u  %10u  %10u  %10u\n", "plcp_err:",
95 		      le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
96 		      delta_ofdm->plcp_err, max_ofdm->plcp_err);
97 	pos +=
98 	    scnprintf(buf + pos, bufsz - pos,
99 		      "  %-30s %10u  %10u  %10u  %10u\n", "crc32_err:",
100 		      le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
101 		      delta_ofdm->crc32_err, max_ofdm->crc32_err);
102 	pos +=
103 	    scnprintf(buf + pos, bufsz - pos,
104 		      "  %-30s %10u  %10u  %10u  %10u\n", "overrun_err:",
105 		      le32_to_cpu(ofdm->overrun_err), accum_ofdm->overrun_err,
106 		      delta_ofdm->overrun_err, max_ofdm->overrun_err);
107 	pos +=
108 	    scnprintf(buf + pos, bufsz - pos,
109 		      "  %-30s %10u  %10u  %10u  %10u\n", "early_overrun_err:",
110 		      le32_to_cpu(ofdm->early_overrun_err),
111 		      accum_ofdm->early_overrun_err,
112 		      delta_ofdm->early_overrun_err,
113 		      max_ofdm->early_overrun_err);
114 	pos +=
115 	    scnprintf(buf + pos, bufsz - pos,
116 		      "  %-30s %10u  %10u  %10u  %10u\n", "crc32_good:",
117 		      le32_to_cpu(ofdm->crc32_good), accum_ofdm->crc32_good,
118 		      delta_ofdm->crc32_good, max_ofdm->crc32_good);
119 	pos +=
120 	    scnprintf(buf + pos, bufsz - pos,
121 		      "  %-30s %10u  %10u  %10u  %10u\n", "false_alarm_cnt:",
122 		      le32_to_cpu(ofdm->false_alarm_cnt),
123 		      accum_ofdm->false_alarm_cnt, delta_ofdm->false_alarm_cnt,
124 		      max_ofdm->false_alarm_cnt);
125 	pos +=
126 	    scnprintf(buf + pos, bufsz - pos,
127 		      "  %-30s %10u  %10u  %10u  %10u\n", "fina_sync_err_cnt:",
128 		      le32_to_cpu(ofdm->fina_sync_err_cnt),
129 		      accum_ofdm->fina_sync_err_cnt,
130 		      delta_ofdm->fina_sync_err_cnt,
131 		      max_ofdm->fina_sync_err_cnt);
132 	pos +=
133 	    scnprintf(buf + pos, bufsz - pos,
134 		      "  %-30s %10u  %10u  %10u  %10u\n", "sfd_timeout:",
135 		      le32_to_cpu(ofdm->sfd_timeout), accum_ofdm->sfd_timeout,
136 		      delta_ofdm->sfd_timeout, max_ofdm->sfd_timeout);
137 	pos +=
138 	    scnprintf(buf + pos, bufsz - pos,
139 		      "  %-30s %10u  %10u  %10u  %10u\n", "fina_timeout:",
140 		      le32_to_cpu(ofdm->fina_timeout), accum_ofdm->fina_timeout,
141 		      delta_ofdm->fina_timeout, max_ofdm->fina_timeout);
142 	pos +=
143 	    scnprintf(buf + pos, bufsz - pos,
144 		      "  %-30s %10u  %10u  %10u  %10u\n", "unresponded_rts:",
145 		      le32_to_cpu(ofdm->unresponded_rts),
146 		      accum_ofdm->unresponded_rts, delta_ofdm->unresponded_rts,
147 		      max_ofdm->unresponded_rts);
148 	pos +=
149 	    scnprintf(buf + pos, bufsz - pos,
150 		      "  %-30s %10u  %10u  %10u  %10u\n",
151 		      "rxe_frame_lmt_ovrun:",
152 		      le32_to_cpu(ofdm->rxe_frame_limit_overrun),
153 		      accum_ofdm->rxe_frame_limit_overrun,
154 		      delta_ofdm->rxe_frame_limit_overrun,
155 		      max_ofdm->rxe_frame_limit_overrun);
156 	pos +=
157 	    scnprintf(buf + pos, bufsz - pos,
158 		      "  %-30s %10u  %10u  %10u  %10u\n", "sent_ack_cnt:",
159 		      le32_to_cpu(ofdm->sent_ack_cnt), accum_ofdm->sent_ack_cnt,
160 		      delta_ofdm->sent_ack_cnt, max_ofdm->sent_ack_cnt);
161 	pos +=
162 	    scnprintf(buf + pos, bufsz - pos,
163 		      "  %-30s %10u  %10u  %10u  %10u\n", "sent_cts_cnt:",
164 		      le32_to_cpu(ofdm->sent_cts_cnt), accum_ofdm->sent_cts_cnt,
165 		      delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt);
166 
167 	pos +=
168 	    scnprintf(buf + pos, bufsz - pos,
169 		      "%-32s     current"
170 		      "accumulative      delta         max\n",
171 		      "Statistics_Rx - CCK:");
172 	pos +=
173 	    scnprintf(buf + pos, bufsz - pos,
174 		      "  %-30s %10u  %10u  %10u  %10u\n", "ina_cnt:",
175 		      le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
176 		      delta_cck->ina_cnt, max_cck->ina_cnt);
177 	pos +=
178 	    scnprintf(buf + pos, bufsz - pos,
179 		      "  %-30s %10u  %10u  %10u  %10u\n", "fina_cnt:",
180 		      le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
181 		      delta_cck->fina_cnt, max_cck->fina_cnt);
182 	pos +=
183 	    scnprintf(buf + pos, bufsz - pos,
184 		      "  %-30s %10u  %10u  %10u  %10u\n", "plcp_err:",
185 		      le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
186 		      delta_cck->plcp_err, max_cck->plcp_err);
187 	pos +=
188 	    scnprintf(buf + pos, bufsz - pos,
189 		      "  %-30s %10u  %10u  %10u  %10u\n", "crc32_err:",
190 		      le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
191 		      delta_cck->crc32_err, max_cck->crc32_err);
192 	pos +=
193 	    scnprintf(buf + pos, bufsz - pos,
194 		      "  %-30s %10u  %10u  %10u  %10u\n", "overrun_err:",
195 		      le32_to_cpu(cck->overrun_err), accum_cck->overrun_err,
196 		      delta_cck->overrun_err, max_cck->overrun_err);
197 	pos +=
198 	    scnprintf(buf + pos, bufsz - pos,
199 		      "  %-30s %10u  %10u  %10u  %10u\n", "early_overrun_err:",
200 		      le32_to_cpu(cck->early_overrun_err),
201 		      accum_cck->early_overrun_err,
202 		      delta_cck->early_overrun_err, max_cck->early_overrun_err);
203 	pos +=
204 	    scnprintf(buf + pos, bufsz - pos,
205 		      "  %-30s %10u  %10u  %10u  %10u\n", "crc32_good:",
206 		      le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
207 		      delta_cck->crc32_good, max_cck->crc32_good);
208 	pos +=
209 	    scnprintf(buf + pos, bufsz - pos,
210 		      "  %-30s %10u  %10u  %10u  %10u\n", "false_alarm_cnt:",
211 		      le32_to_cpu(cck->false_alarm_cnt),
212 		      accum_cck->false_alarm_cnt, delta_cck->false_alarm_cnt,
213 		      max_cck->false_alarm_cnt);
214 	pos +=
215 	    scnprintf(buf + pos, bufsz - pos,
216 		      "  %-30s %10u  %10u  %10u  %10u\n", "fina_sync_err_cnt:",
217 		      le32_to_cpu(cck->fina_sync_err_cnt),
218 		      accum_cck->fina_sync_err_cnt,
219 		      delta_cck->fina_sync_err_cnt, max_cck->fina_sync_err_cnt);
220 	pos +=
221 	    scnprintf(buf + pos, bufsz - pos,
222 		      "  %-30s %10u  %10u  %10u  %10u\n", "sfd_timeout:",
223 		      le32_to_cpu(cck->sfd_timeout), accum_cck->sfd_timeout,
224 		      delta_cck->sfd_timeout, max_cck->sfd_timeout);
225 	pos +=
226 	    scnprintf(buf + pos, bufsz - pos,
227 		      "  %-30s %10u  %10u  %10u  %10u\n", "fina_timeout:",
228 		      le32_to_cpu(cck->fina_timeout), accum_cck->fina_timeout,
229 		      delta_cck->fina_timeout, max_cck->fina_timeout);
230 	pos +=
231 	    scnprintf(buf + pos, bufsz - pos,
232 		      "  %-30s %10u  %10u  %10u  %10u\n", "unresponded_rts:",
233 		      le32_to_cpu(cck->unresponded_rts),
234 		      accum_cck->unresponded_rts, delta_cck->unresponded_rts,
235 		      max_cck->unresponded_rts);
236 	pos +=
237 	    scnprintf(buf + pos, bufsz - pos,
238 		      "  %-30s %10u  %10u  %10u  %10u\n",
239 		      "rxe_frame_lmt_ovrun:",
240 		      le32_to_cpu(cck->rxe_frame_limit_overrun),
241 		      accum_cck->rxe_frame_limit_overrun,
242 		      delta_cck->rxe_frame_limit_overrun,
243 		      max_cck->rxe_frame_limit_overrun);
244 	pos +=
245 	    scnprintf(buf + pos, bufsz - pos,
246 		      "  %-30s %10u  %10u  %10u  %10u\n", "sent_ack_cnt:",
247 		      le32_to_cpu(cck->sent_ack_cnt), accum_cck->sent_ack_cnt,
248 		      delta_cck->sent_ack_cnt, max_cck->sent_ack_cnt);
249 	pos +=
250 	    scnprintf(buf + pos, bufsz - pos,
251 		      "  %-30s %10u  %10u  %10u  %10u\n", "sent_cts_cnt:",
252 		      le32_to_cpu(cck->sent_cts_cnt), accum_cck->sent_cts_cnt,
253 		      delta_cck->sent_cts_cnt, max_cck->sent_cts_cnt);
254 
255 	pos +=
256 	    scnprintf(buf + pos, bufsz - pos,
257 		      "%-32s     current"
258 		      "accumulative      delta         max\n",
259 		      "Statistics_Rx - GENERAL:");
260 	pos +=
261 	    scnprintf(buf + pos, bufsz - pos,
262 		      "  %-30s %10u  %10u  %10u  %10u\n", "bogus_cts:",
263 		      le32_to_cpu(general->bogus_cts), accum_general->bogus_cts,
264 		      delta_general->bogus_cts, max_general->bogus_cts);
265 	pos +=
266 	    scnprintf(buf + pos, bufsz - pos,
267 		      "  %-30s %10u  %10u  %10u  %10u\n", "bogus_ack:",
268 		      le32_to_cpu(general->bogus_ack), accum_general->bogus_ack,
269 		      delta_general->bogus_ack, max_general->bogus_ack);
270 	pos +=
271 	    scnprintf(buf + pos, bufsz - pos,
272 		      "  %-30s %10u  %10u  %10u  %10u\n", "non_bssid_frames:",
273 		      le32_to_cpu(general->non_bssid_frames),
274 		      accum_general->non_bssid_frames,
275 		      delta_general->non_bssid_frames,
276 		      max_general->non_bssid_frames);
277 	pos +=
278 	    scnprintf(buf + pos, bufsz - pos,
279 		      "  %-30s %10u  %10u  %10u  %10u\n", "filtered_frames:",
280 		      le32_to_cpu(general->filtered_frames),
281 		      accum_general->filtered_frames,
282 		      delta_general->filtered_frames,
283 		      max_general->filtered_frames);
284 	pos +=
285 	    scnprintf(buf + pos, bufsz - pos,
286 		      "  %-30s %10u  %10u  %10u  %10u\n",
287 		      "non_channel_beacons:",
288 		      le32_to_cpu(general->non_channel_beacons),
289 		      accum_general->non_channel_beacons,
290 		      delta_general->non_channel_beacons,
291 		      max_general->non_channel_beacons);
292 
293 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
294 	kfree(buf);
295 	return ret;
296 }
297 
298 static ssize_t
299 il3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
300 			   size_t count, loff_t *ppos)
301 {
302 	struct il_priv *il = file->private_data;
303 	int pos = 0;
304 	char *buf;
305 	int bufsz = (sizeof(struct iwl39_stats_tx) * 48) + 250;
306 	ssize_t ret;
307 	struct iwl39_stats_tx *tx, *accum_tx, *delta_tx, *max_tx;
308 
309 	if (!il_is_alive(il))
310 		return -EAGAIN;
311 
312 	buf = kzalloc(bufsz, GFP_KERNEL);
313 	if (!buf) {
314 		IL_ERR("Can not allocate Buffer\n");
315 		return -ENOMEM;
316 	}
317 
318 	/*
319 	 * The statistic information display here is based on
320 	 * the last stats notification from uCode
321 	 * might not reflect the current uCode activity
322 	 */
323 	tx = &il->_3945.stats.tx;
324 	accum_tx = &il->_3945.accum_stats.tx;
325 	delta_tx = &il->_3945.delta_stats.tx;
326 	max_tx = &il->_3945.max_delta.tx;
327 	pos += il3945_stats_flag(il, buf, bufsz);
328 	pos +=
329 	    scnprintf(buf + pos, bufsz - pos,
330 		      "%-32s     current"
331 		      "accumulative      delta         max\n",
332 		      "Statistics_Tx:");
333 	pos +=
334 	    scnprintf(buf + pos, bufsz - pos,
335 		      "  %-30s %10u  %10u  %10u  %10u\n", "preamble:",
336 		      le32_to_cpu(tx->preamble_cnt), accum_tx->preamble_cnt,
337 		      delta_tx->preamble_cnt, max_tx->preamble_cnt);
338 	pos +=
339 	    scnprintf(buf + pos, bufsz - pos,
340 		      "  %-30s %10u  %10u  %10u  %10u\n", "rx_detected_cnt:",
341 		      le32_to_cpu(tx->rx_detected_cnt),
342 		      accum_tx->rx_detected_cnt, delta_tx->rx_detected_cnt,
343 		      max_tx->rx_detected_cnt);
344 	pos +=
345 	    scnprintf(buf + pos, bufsz - pos,
346 		      "  %-30s %10u  %10u  %10u  %10u\n", "bt_prio_defer_cnt:",
347 		      le32_to_cpu(tx->bt_prio_defer_cnt),
348 		      accum_tx->bt_prio_defer_cnt, delta_tx->bt_prio_defer_cnt,
349 		      max_tx->bt_prio_defer_cnt);
350 	pos +=
351 	    scnprintf(buf + pos, bufsz - pos,
352 		      "  %-30s %10u  %10u  %10u  %10u\n", "bt_prio_kill_cnt:",
353 		      le32_to_cpu(tx->bt_prio_kill_cnt),
354 		      accum_tx->bt_prio_kill_cnt, delta_tx->bt_prio_kill_cnt,
355 		      max_tx->bt_prio_kill_cnt);
356 	pos +=
357 	    scnprintf(buf + pos, bufsz - pos,
358 		      "  %-30s %10u  %10u  %10u  %10u\n", "few_bytes_cnt:",
359 		      le32_to_cpu(tx->few_bytes_cnt), accum_tx->few_bytes_cnt,
360 		      delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
361 	pos +=
362 	    scnprintf(buf + pos, bufsz - pos,
363 		      "  %-30s %10u  %10u  %10u  %10u\n", "cts_timeout:",
364 		      le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
365 		      delta_tx->cts_timeout, max_tx->cts_timeout);
366 	pos +=
367 	    scnprintf(buf + pos, bufsz - pos,
368 		      "  %-30s %10u  %10u  %10u  %10u\n", "ack_timeout:",
369 		      le32_to_cpu(tx->ack_timeout), accum_tx->ack_timeout,
370 		      delta_tx->ack_timeout, max_tx->ack_timeout);
371 	pos +=
372 	    scnprintf(buf + pos, bufsz - pos,
373 		      "  %-30s %10u  %10u  %10u  %10u\n", "expected_ack_cnt:",
374 		      le32_to_cpu(tx->expected_ack_cnt),
375 		      accum_tx->expected_ack_cnt, delta_tx->expected_ack_cnt,
376 		      max_tx->expected_ack_cnt);
377 	pos +=
378 	    scnprintf(buf + pos, bufsz - pos,
379 		      "  %-30s %10u  %10u  %10u  %10u\n", "actual_ack_cnt:",
380 		      le32_to_cpu(tx->actual_ack_cnt), accum_tx->actual_ack_cnt,
381 		      delta_tx->actual_ack_cnt, max_tx->actual_ack_cnt);
382 
383 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
384 	kfree(buf);
385 	return ret;
386 }
387 
388 static ssize_t
389 il3945_ucode_general_stats_read(struct file *file, char __user *user_buf,
390 				size_t count, loff_t *ppos)
391 {
392 	struct il_priv *il = file->private_data;
393 	int pos = 0;
394 	char *buf;
395 	int bufsz = sizeof(struct iwl39_stats_general) * 10 + 300;
396 	ssize_t ret;
397 	struct iwl39_stats_general *general, *accum_general;
398 	struct iwl39_stats_general *delta_general, *max_general;
399 	struct stats_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
400 	struct iwl39_stats_div *div, *accum_div, *delta_div, *max_div;
401 
402 	if (!il_is_alive(il))
403 		return -EAGAIN;
404 
405 	buf = kzalloc(bufsz, GFP_KERNEL);
406 	if (!buf) {
407 		IL_ERR("Can not allocate Buffer\n");
408 		return -ENOMEM;
409 	}
410 
411 	/*
412 	 * The statistic information display here is based on
413 	 * the last stats notification from uCode
414 	 * might not reflect the current uCode activity
415 	 */
416 	general = &il->_3945.stats.general;
417 	dbg = &il->_3945.stats.general.dbg;
418 	div = &il->_3945.stats.general.div;
419 	accum_general = &il->_3945.accum_stats.general;
420 	delta_general = &il->_3945.delta_stats.general;
421 	max_general = &il->_3945.max_delta.general;
422 	accum_dbg = &il->_3945.accum_stats.general.dbg;
423 	delta_dbg = &il->_3945.delta_stats.general.dbg;
424 	max_dbg = &il->_3945.max_delta.general.dbg;
425 	accum_div = &il->_3945.accum_stats.general.div;
426 	delta_div = &il->_3945.delta_stats.general.div;
427 	max_div = &il->_3945.max_delta.general.div;
428 	pos += il3945_stats_flag(il, buf, bufsz);
429 	pos +=
430 	    scnprintf(buf + pos, bufsz - pos,
431 		      "%-32s     current"
432 		      "accumulative      delta         max\n",
433 		      "Statistics_General:");
434 	pos +=
435 	    scnprintf(buf + pos, bufsz - pos,
436 		      "  %-30s %10u  %10u  %10u  %10u\n", "burst_check:",
437 		      le32_to_cpu(dbg->burst_check), accum_dbg->burst_check,
438 		      delta_dbg->burst_check, max_dbg->burst_check);
439 	pos +=
440 	    scnprintf(buf + pos, bufsz - pos,
441 		      "  %-30s %10u  %10u  %10u  %10u\n", "burst_count:",
442 		      le32_to_cpu(dbg->burst_count), accum_dbg->burst_count,
443 		      delta_dbg->burst_count, max_dbg->burst_count);
444 	pos +=
445 	    scnprintf(buf + pos, bufsz - pos,
446 		      "  %-30s %10u  %10u  %10u  %10u\n", "sleep_time:",
447 		      le32_to_cpu(general->sleep_time),
448 		      accum_general->sleep_time, delta_general->sleep_time,
449 		      max_general->sleep_time);
450 	pos +=
451 	    scnprintf(buf + pos, bufsz - pos,
452 		      "  %-30s %10u  %10u  %10u  %10u\n", "slots_out:",
453 		      le32_to_cpu(general->slots_out), accum_general->slots_out,
454 		      delta_general->slots_out, max_general->slots_out);
455 	pos +=
456 	    scnprintf(buf + pos, bufsz - pos,
457 		      "  %-30s %10u  %10u  %10u  %10u\n", "slots_idle:",
458 		      le32_to_cpu(general->slots_idle),
459 		      accum_general->slots_idle, delta_general->slots_idle,
460 		      max_general->slots_idle);
461 	pos +=
462 	    scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
463 		      le32_to_cpu(general->ttl_timestamp));
464 	pos +=
465 	    scnprintf(buf + pos, bufsz - pos,
466 		      "  %-30s %10u  %10u  %10u  %10u\n", "tx_on_a:",
467 		      le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
468 		      delta_div->tx_on_a, max_div->tx_on_a);
469 	pos +=
470 	    scnprintf(buf + pos, bufsz - pos,
471 		      "  %-30s %10u  %10u  %10u  %10u\n", "tx_on_b:",
472 		      le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
473 		      delta_div->tx_on_b, max_div->tx_on_b);
474 	pos +=
475 	    scnprintf(buf + pos, bufsz - pos,
476 		      "  %-30s %10u  %10u  %10u  %10u\n", "exec_time:",
477 		      le32_to_cpu(div->exec_time), accum_div->exec_time,
478 		      delta_div->exec_time, max_div->exec_time);
479 	pos +=
480 	    scnprintf(buf + pos, bufsz - pos,
481 		      "  %-30s %10u  %10u  %10u  %10u\n", "probe_time:",
482 		      le32_to_cpu(div->probe_time), accum_div->probe_time,
483 		      delta_div->probe_time, max_div->probe_time);
484 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
485 	kfree(buf);
486 	return ret;
487 }
488 
489 const struct il_debugfs_ops il3945_debugfs_ops = {
490 	.rx_stats_read = il3945_ucode_rx_stats_read,
491 	.tx_stats_read = il3945_ucode_tx_stats_read,
492 	.general_stats_read = il3945_ucode_general_stats_read,
493 };
494