1*ad306d68SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
27ac9a364SKalle Valo /******************************************************************************
37ac9a364SKalle Valo  *
47ac9a364SKalle Valo  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
57ac9a364SKalle Valo  *
67ac9a364SKalle Valo  * Contact Information:
77ac9a364SKalle Valo  *  Intel Linux Wireless <ilw@linux.intel.com>
87ac9a364SKalle Valo  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
97ac9a364SKalle Valo  *****************************************************************************/
107ac9a364SKalle Valo 
117ac9a364SKalle Valo #include "common.h"
127ac9a364SKalle Valo #include "3945.h"
137ac9a364SKalle Valo 
147ac9a364SKalle Valo static int
il3945_stats_flag(struct il_priv * il,char * buf,int bufsz)157ac9a364SKalle Valo il3945_stats_flag(struct il_priv *il, char *buf, int bufsz)
167ac9a364SKalle Valo {
177ac9a364SKalle Valo 	int p = 0;
187ac9a364SKalle Valo 
197ac9a364SKalle Valo 	p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
207ac9a364SKalle Valo 		       le32_to_cpu(il->_3945.stats.flag));
217ac9a364SKalle Valo 	if (le32_to_cpu(il->_3945.stats.flag) & UCODE_STATS_CLEAR_MSK)
227ac9a364SKalle Valo 		p += scnprintf(buf + p, bufsz - p,
237ac9a364SKalle Valo 			       "\tStatistics have been cleared\n");
247ac9a364SKalle Valo 	p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
257ac9a364SKalle Valo 		       (le32_to_cpu(il->_3945.stats.flag) &
267ac9a364SKalle Valo 			UCODE_STATS_FREQUENCY_MSK) ? "2.4 GHz" : "5.2 GHz");
277ac9a364SKalle Valo 	p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
287ac9a364SKalle Valo 		       (le32_to_cpu(il->_3945.stats.flag) &
297ac9a364SKalle Valo 			UCODE_STATS_NARROW_BAND_MSK) ? "enabled" : "disabled");
307ac9a364SKalle Valo 	return p;
317ac9a364SKalle Valo }
327ac9a364SKalle Valo 
337ac9a364SKalle Valo static ssize_t
il3945_ucode_rx_stats_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)347ac9a364SKalle Valo il3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
357ac9a364SKalle Valo 			   size_t count, loff_t *ppos)
367ac9a364SKalle Valo {
377ac9a364SKalle Valo 	struct il_priv *il = file->private_data;
387ac9a364SKalle Valo 	int pos = 0;
397ac9a364SKalle Valo 	char *buf;
407ac9a364SKalle Valo 	int bufsz =
417ac9a364SKalle Valo 	    sizeof(struct iwl39_stats_rx_phy) * 40 +
427ac9a364SKalle Valo 	    sizeof(struct iwl39_stats_rx_non_phy) * 40 + 400;
437ac9a364SKalle Valo 	ssize_t ret;
447ac9a364SKalle Valo 	struct iwl39_stats_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
457ac9a364SKalle Valo 	struct iwl39_stats_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
467ac9a364SKalle Valo 	struct iwl39_stats_rx_non_phy *general, *accum_general;
477ac9a364SKalle Valo 	struct iwl39_stats_rx_non_phy *delta_general, *max_general;
487ac9a364SKalle Valo 
497ac9a364SKalle Valo 	if (!il_is_alive(il))
507ac9a364SKalle Valo 		return -EAGAIN;
517ac9a364SKalle Valo 
527ac9a364SKalle Valo 	buf = kzalloc(bufsz, GFP_KERNEL);
537ac9a364SKalle Valo 	if (!buf) {
547ac9a364SKalle Valo 		IL_ERR("Can not allocate Buffer\n");
557ac9a364SKalle Valo 		return -ENOMEM;
567ac9a364SKalle Valo 	}
577ac9a364SKalle Valo 
587ac9a364SKalle Valo 	/*
597ac9a364SKalle Valo 	 * The statistic information display here is based on
607ac9a364SKalle Valo 	 * the last stats notification from uCode
617ac9a364SKalle Valo 	 * might not reflect the current uCode activity
627ac9a364SKalle Valo 	 */
637ac9a364SKalle Valo 	ofdm = &il->_3945.stats.rx.ofdm;
647ac9a364SKalle Valo 	cck = &il->_3945.stats.rx.cck;
657ac9a364SKalle Valo 	general = &il->_3945.stats.rx.general;
667ac9a364SKalle Valo 	accum_ofdm = &il->_3945.accum_stats.rx.ofdm;
677ac9a364SKalle Valo 	accum_cck = &il->_3945.accum_stats.rx.cck;
687ac9a364SKalle Valo 	accum_general = &il->_3945.accum_stats.rx.general;
697ac9a364SKalle Valo 	delta_ofdm = &il->_3945.delta_stats.rx.ofdm;
707ac9a364SKalle Valo 	delta_cck = &il->_3945.delta_stats.rx.cck;
717ac9a364SKalle Valo 	delta_general = &il->_3945.delta_stats.rx.general;
727ac9a364SKalle Valo 	max_ofdm = &il->_3945.max_delta.rx.ofdm;
737ac9a364SKalle Valo 	max_cck = &il->_3945.max_delta.rx.cck;
747ac9a364SKalle Valo 	max_general = &il->_3945.max_delta.rx.general;
757ac9a364SKalle Valo 
767ac9a364SKalle Valo 	pos += il3945_stats_flag(il, buf, bufsz);
777ac9a364SKalle Valo 	pos +=
787ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
797ac9a364SKalle Valo 		      "%-32s     current"
8026b701adSColin Ian King 		      "accumulative      delta         max\n",
817ac9a364SKalle Valo 		      "Statistics_Rx - OFDM:");
827ac9a364SKalle Valo 	pos +=
837ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
847ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "ina_cnt:",
857ac9a364SKalle Valo 		      le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt,
867ac9a364SKalle Valo 		      delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
877ac9a364SKalle Valo 	pos +=
887ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
897ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "fina_cnt:",
907ac9a364SKalle Valo 		      le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
917ac9a364SKalle Valo 		      delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
927ac9a364SKalle Valo 	pos +=
937ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
947ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "plcp_err:",
957ac9a364SKalle Valo 		      le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
967ac9a364SKalle Valo 		      delta_ofdm->plcp_err, max_ofdm->plcp_err);
977ac9a364SKalle Valo 	pos +=
987ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
997ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "crc32_err:",
1007ac9a364SKalle Valo 		      le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
1017ac9a364SKalle Valo 		      delta_ofdm->crc32_err, max_ofdm->crc32_err);
1027ac9a364SKalle Valo 	pos +=
1037ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1047ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "overrun_err:",
1057ac9a364SKalle Valo 		      le32_to_cpu(ofdm->overrun_err), accum_ofdm->overrun_err,
1067ac9a364SKalle Valo 		      delta_ofdm->overrun_err, max_ofdm->overrun_err);
1077ac9a364SKalle Valo 	pos +=
1087ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1097ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "early_overrun_err:",
1107ac9a364SKalle Valo 		      le32_to_cpu(ofdm->early_overrun_err),
1117ac9a364SKalle Valo 		      accum_ofdm->early_overrun_err,
1127ac9a364SKalle Valo 		      delta_ofdm->early_overrun_err,
1137ac9a364SKalle Valo 		      max_ofdm->early_overrun_err);
1147ac9a364SKalle Valo 	pos +=
1157ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1167ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "crc32_good:",
1177ac9a364SKalle Valo 		      le32_to_cpu(ofdm->crc32_good), accum_ofdm->crc32_good,
1187ac9a364SKalle Valo 		      delta_ofdm->crc32_good, max_ofdm->crc32_good);
1197ac9a364SKalle Valo 	pos +=
1207ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1217ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "false_alarm_cnt:",
1227ac9a364SKalle Valo 		      le32_to_cpu(ofdm->false_alarm_cnt),
1237ac9a364SKalle Valo 		      accum_ofdm->false_alarm_cnt, delta_ofdm->false_alarm_cnt,
1247ac9a364SKalle Valo 		      max_ofdm->false_alarm_cnt);
1257ac9a364SKalle Valo 	pos +=
1267ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1277ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "fina_sync_err_cnt:",
1287ac9a364SKalle Valo 		      le32_to_cpu(ofdm->fina_sync_err_cnt),
1297ac9a364SKalle Valo 		      accum_ofdm->fina_sync_err_cnt,
1307ac9a364SKalle Valo 		      delta_ofdm->fina_sync_err_cnt,
1317ac9a364SKalle Valo 		      max_ofdm->fina_sync_err_cnt);
1327ac9a364SKalle Valo 	pos +=
1337ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1347ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "sfd_timeout:",
1357ac9a364SKalle Valo 		      le32_to_cpu(ofdm->sfd_timeout), accum_ofdm->sfd_timeout,
1367ac9a364SKalle Valo 		      delta_ofdm->sfd_timeout, max_ofdm->sfd_timeout);
1377ac9a364SKalle Valo 	pos +=
1387ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1397ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "fina_timeout:",
1407ac9a364SKalle Valo 		      le32_to_cpu(ofdm->fina_timeout), accum_ofdm->fina_timeout,
1417ac9a364SKalle Valo 		      delta_ofdm->fina_timeout, max_ofdm->fina_timeout);
1427ac9a364SKalle Valo 	pos +=
1437ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1447ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "unresponded_rts:",
1457ac9a364SKalle Valo 		      le32_to_cpu(ofdm->unresponded_rts),
1467ac9a364SKalle Valo 		      accum_ofdm->unresponded_rts, delta_ofdm->unresponded_rts,
1477ac9a364SKalle Valo 		      max_ofdm->unresponded_rts);
1487ac9a364SKalle Valo 	pos +=
1497ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1507ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n",
1517ac9a364SKalle Valo 		      "rxe_frame_lmt_ovrun:",
1527ac9a364SKalle Valo 		      le32_to_cpu(ofdm->rxe_frame_limit_overrun),
1537ac9a364SKalle Valo 		      accum_ofdm->rxe_frame_limit_overrun,
1547ac9a364SKalle Valo 		      delta_ofdm->rxe_frame_limit_overrun,
1557ac9a364SKalle Valo 		      max_ofdm->rxe_frame_limit_overrun);
1567ac9a364SKalle Valo 	pos +=
1577ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1587ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "sent_ack_cnt:",
1597ac9a364SKalle Valo 		      le32_to_cpu(ofdm->sent_ack_cnt), accum_ofdm->sent_ack_cnt,
1607ac9a364SKalle Valo 		      delta_ofdm->sent_ack_cnt, max_ofdm->sent_ack_cnt);
1617ac9a364SKalle Valo 	pos +=
1627ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1637ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "sent_cts_cnt:",
1647ac9a364SKalle Valo 		      le32_to_cpu(ofdm->sent_cts_cnt), accum_ofdm->sent_cts_cnt,
1657ac9a364SKalle Valo 		      delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt);
1667ac9a364SKalle Valo 
1677ac9a364SKalle Valo 	pos +=
1687ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1697ac9a364SKalle Valo 		      "%-32s     current"
170b9574ce1SColin Ian King 		      "accumulative      delta         max\n",
1717ac9a364SKalle Valo 		      "Statistics_Rx - CCK:");
1727ac9a364SKalle Valo 	pos +=
1737ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1747ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "ina_cnt:",
1757ac9a364SKalle Valo 		      le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
1767ac9a364SKalle Valo 		      delta_cck->ina_cnt, max_cck->ina_cnt);
1777ac9a364SKalle Valo 	pos +=
1787ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1797ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "fina_cnt:",
1807ac9a364SKalle Valo 		      le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
1817ac9a364SKalle Valo 		      delta_cck->fina_cnt, max_cck->fina_cnt);
1827ac9a364SKalle Valo 	pos +=
1837ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1847ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "plcp_err:",
1857ac9a364SKalle Valo 		      le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
1867ac9a364SKalle Valo 		      delta_cck->plcp_err, max_cck->plcp_err);
1877ac9a364SKalle Valo 	pos +=
1887ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1897ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "crc32_err:",
1907ac9a364SKalle Valo 		      le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
1917ac9a364SKalle Valo 		      delta_cck->crc32_err, max_cck->crc32_err);
1927ac9a364SKalle Valo 	pos +=
1937ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1947ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "overrun_err:",
1957ac9a364SKalle Valo 		      le32_to_cpu(cck->overrun_err), accum_cck->overrun_err,
1967ac9a364SKalle Valo 		      delta_cck->overrun_err, max_cck->overrun_err);
1977ac9a364SKalle Valo 	pos +=
1987ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
1997ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "early_overrun_err:",
2007ac9a364SKalle Valo 		      le32_to_cpu(cck->early_overrun_err),
2017ac9a364SKalle Valo 		      accum_cck->early_overrun_err,
2027ac9a364SKalle Valo 		      delta_cck->early_overrun_err, max_cck->early_overrun_err);
2037ac9a364SKalle Valo 	pos +=
2047ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2057ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "crc32_good:",
2067ac9a364SKalle Valo 		      le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
2077ac9a364SKalle Valo 		      delta_cck->crc32_good, max_cck->crc32_good);
2087ac9a364SKalle Valo 	pos +=
2097ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2107ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "false_alarm_cnt:",
2117ac9a364SKalle Valo 		      le32_to_cpu(cck->false_alarm_cnt),
2127ac9a364SKalle Valo 		      accum_cck->false_alarm_cnt, delta_cck->false_alarm_cnt,
2137ac9a364SKalle Valo 		      max_cck->false_alarm_cnt);
2147ac9a364SKalle Valo 	pos +=
2157ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2167ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "fina_sync_err_cnt:",
2177ac9a364SKalle Valo 		      le32_to_cpu(cck->fina_sync_err_cnt),
2187ac9a364SKalle Valo 		      accum_cck->fina_sync_err_cnt,
2197ac9a364SKalle Valo 		      delta_cck->fina_sync_err_cnt, max_cck->fina_sync_err_cnt);
2207ac9a364SKalle Valo 	pos +=
2217ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2227ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "sfd_timeout:",
2237ac9a364SKalle Valo 		      le32_to_cpu(cck->sfd_timeout), accum_cck->sfd_timeout,
2247ac9a364SKalle Valo 		      delta_cck->sfd_timeout, max_cck->sfd_timeout);
2257ac9a364SKalle Valo 	pos +=
2267ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2277ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "fina_timeout:",
2287ac9a364SKalle Valo 		      le32_to_cpu(cck->fina_timeout), accum_cck->fina_timeout,
2297ac9a364SKalle Valo 		      delta_cck->fina_timeout, max_cck->fina_timeout);
2307ac9a364SKalle Valo 	pos +=
2317ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2327ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "unresponded_rts:",
2337ac9a364SKalle Valo 		      le32_to_cpu(cck->unresponded_rts),
2347ac9a364SKalle Valo 		      accum_cck->unresponded_rts, delta_cck->unresponded_rts,
2357ac9a364SKalle Valo 		      max_cck->unresponded_rts);
2367ac9a364SKalle Valo 	pos +=
2377ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2387ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n",
2397ac9a364SKalle Valo 		      "rxe_frame_lmt_ovrun:",
2407ac9a364SKalle Valo 		      le32_to_cpu(cck->rxe_frame_limit_overrun),
2417ac9a364SKalle Valo 		      accum_cck->rxe_frame_limit_overrun,
2427ac9a364SKalle Valo 		      delta_cck->rxe_frame_limit_overrun,
2437ac9a364SKalle Valo 		      max_cck->rxe_frame_limit_overrun);
2447ac9a364SKalle Valo 	pos +=
2457ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2467ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "sent_ack_cnt:",
2477ac9a364SKalle Valo 		      le32_to_cpu(cck->sent_ack_cnt), accum_cck->sent_ack_cnt,
2487ac9a364SKalle Valo 		      delta_cck->sent_ack_cnt, max_cck->sent_ack_cnt);
2497ac9a364SKalle Valo 	pos +=
2507ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2517ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "sent_cts_cnt:",
2527ac9a364SKalle Valo 		      le32_to_cpu(cck->sent_cts_cnt), accum_cck->sent_cts_cnt,
2537ac9a364SKalle Valo 		      delta_cck->sent_cts_cnt, max_cck->sent_cts_cnt);
2547ac9a364SKalle Valo 
2557ac9a364SKalle Valo 	pos +=
2567ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2577ac9a364SKalle Valo 		      "%-32s     current"
258b9574ce1SColin Ian King 		      "accumulative      delta         max\n",
2597ac9a364SKalle Valo 		      "Statistics_Rx - GENERAL:");
2607ac9a364SKalle Valo 	pos +=
2617ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2627ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "bogus_cts:",
2637ac9a364SKalle Valo 		      le32_to_cpu(general->bogus_cts), accum_general->bogus_cts,
2647ac9a364SKalle Valo 		      delta_general->bogus_cts, max_general->bogus_cts);
2657ac9a364SKalle Valo 	pos +=
2667ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2677ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "bogus_ack:",
2687ac9a364SKalle Valo 		      le32_to_cpu(general->bogus_ack), accum_general->bogus_ack,
2697ac9a364SKalle Valo 		      delta_general->bogus_ack, max_general->bogus_ack);
2707ac9a364SKalle Valo 	pos +=
2717ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2727ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "non_bssid_frames:",
2737ac9a364SKalle Valo 		      le32_to_cpu(general->non_bssid_frames),
2747ac9a364SKalle Valo 		      accum_general->non_bssid_frames,
2757ac9a364SKalle Valo 		      delta_general->non_bssid_frames,
2767ac9a364SKalle Valo 		      max_general->non_bssid_frames);
2777ac9a364SKalle Valo 	pos +=
2787ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2797ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "filtered_frames:",
2807ac9a364SKalle Valo 		      le32_to_cpu(general->filtered_frames),
2817ac9a364SKalle Valo 		      accum_general->filtered_frames,
2827ac9a364SKalle Valo 		      delta_general->filtered_frames,
2837ac9a364SKalle Valo 		      max_general->filtered_frames);
2847ac9a364SKalle Valo 	pos +=
2857ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
2867ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n",
2877ac9a364SKalle Valo 		      "non_channel_beacons:",
2887ac9a364SKalle Valo 		      le32_to_cpu(general->non_channel_beacons),
2897ac9a364SKalle Valo 		      accum_general->non_channel_beacons,
2907ac9a364SKalle Valo 		      delta_general->non_channel_beacons,
2917ac9a364SKalle Valo 		      max_general->non_channel_beacons);
2927ac9a364SKalle Valo 
2937ac9a364SKalle Valo 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2947ac9a364SKalle Valo 	kfree(buf);
2957ac9a364SKalle Valo 	return ret;
2967ac9a364SKalle Valo }
2977ac9a364SKalle Valo 
2987ac9a364SKalle Valo static ssize_t
il3945_ucode_tx_stats_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)2997ac9a364SKalle Valo il3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
3007ac9a364SKalle Valo 			   size_t count, loff_t *ppos)
3017ac9a364SKalle Valo {
3027ac9a364SKalle Valo 	struct il_priv *il = file->private_data;
3037ac9a364SKalle Valo 	int pos = 0;
3047ac9a364SKalle Valo 	char *buf;
3057ac9a364SKalle Valo 	int bufsz = (sizeof(struct iwl39_stats_tx) * 48) + 250;
3067ac9a364SKalle Valo 	ssize_t ret;
3077ac9a364SKalle Valo 	struct iwl39_stats_tx *tx, *accum_tx, *delta_tx, *max_tx;
3087ac9a364SKalle Valo 
3097ac9a364SKalle Valo 	if (!il_is_alive(il))
3107ac9a364SKalle Valo 		return -EAGAIN;
3117ac9a364SKalle Valo 
3127ac9a364SKalle Valo 	buf = kzalloc(bufsz, GFP_KERNEL);
3137ac9a364SKalle Valo 	if (!buf) {
3147ac9a364SKalle Valo 		IL_ERR("Can not allocate Buffer\n");
3157ac9a364SKalle Valo 		return -ENOMEM;
3167ac9a364SKalle Valo 	}
3177ac9a364SKalle Valo 
3187ac9a364SKalle Valo 	/*
3197ac9a364SKalle Valo 	 * The statistic information display here is based on
3207ac9a364SKalle Valo 	 * the last stats notification from uCode
3217ac9a364SKalle Valo 	 * might not reflect the current uCode activity
3227ac9a364SKalle Valo 	 */
3237ac9a364SKalle Valo 	tx = &il->_3945.stats.tx;
3247ac9a364SKalle Valo 	accum_tx = &il->_3945.accum_stats.tx;
3257ac9a364SKalle Valo 	delta_tx = &il->_3945.delta_stats.tx;
3267ac9a364SKalle Valo 	max_tx = &il->_3945.max_delta.tx;
3277ac9a364SKalle Valo 	pos += il3945_stats_flag(il, buf, bufsz);
3287ac9a364SKalle Valo 	pos +=
3297ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
3307ac9a364SKalle Valo 		      "%-32s     current"
331b9574ce1SColin Ian King 		      "accumulative      delta         max\n",
3327ac9a364SKalle Valo 		      "Statistics_Tx:");
3337ac9a364SKalle Valo 	pos +=
3347ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
3357ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "preamble:",
3367ac9a364SKalle Valo 		      le32_to_cpu(tx->preamble_cnt), accum_tx->preamble_cnt,
3377ac9a364SKalle Valo 		      delta_tx->preamble_cnt, max_tx->preamble_cnt);
3387ac9a364SKalle Valo 	pos +=
3397ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
3407ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "rx_detected_cnt:",
3417ac9a364SKalle Valo 		      le32_to_cpu(tx->rx_detected_cnt),
3427ac9a364SKalle Valo 		      accum_tx->rx_detected_cnt, delta_tx->rx_detected_cnt,
3437ac9a364SKalle Valo 		      max_tx->rx_detected_cnt);
3447ac9a364SKalle Valo 	pos +=
3457ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
3467ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "bt_prio_defer_cnt:",
3477ac9a364SKalle Valo 		      le32_to_cpu(tx->bt_prio_defer_cnt),
3487ac9a364SKalle Valo 		      accum_tx->bt_prio_defer_cnt, delta_tx->bt_prio_defer_cnt,
3497ac9a364SKalle Valo 		      max_tx->bt_prio_defer_cnt);
3507ac9a364SKalle Valo 	pos +=
3517ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
3527ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "bt_prio_kill_cnt:",
3537ac9a364SKalle Valo 		      le32_to_cpu(tx->bt_prio_kill_cnt),
3547ac9a364SKalle Valo 		      accum_tx->bt_prio_kill_cnt, delta_tx->bt_prio_kill_cnt,
3557ac9a364SKalle Valo 		      max_tx->bt_prio_kill_cnt);
3567ac9a364SKalle Valo 	pos +=
3577ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
3587ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "few_bytes_cnt:",
3597ac9a364SKalle Valo 		      le32_to_cpu(tx->few_bytes_cnt), accum_tx->few_bytes_cnt,
3607ac9a364SKalle Valo 		      delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
3617ac9a364SKalle Valo 	pos +=
3627ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
3637ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "cts_timeout:",
3647ac9a364SKalle Valo 		      le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
3657ac9a364SKalle Valo 		      delta_tx->cts_timeout, max_tx->cts_timeout);
3667ac9a364SKalle Valo 	pos +=
3677ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
3687ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "ack_timeout:",
3697ac9a364SKalle Valo 		      le32_to_cpu(tx->ack_timeout), accum_tx->ack_timeout,
3707ac9a364SKalle Valo 		      delta_tx->ack_timeout, max_tx->ack_timeout);
3717ac9a364SKalle Valo 	pos +=
3727ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
3737ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "expected_ack_cnt:",
3747ac9a364SKalle Valo 		      le32_to_cpu(tx->expected_ack_cnt),
3757ac9a364SKalle Valo 		      accum_tx->expected_ack_cnt, delta_tx->expected_ack_cnt,
3767ac9a364SKalle Valo 		      max_tx->expected_ack_cnt);
3777ac9a364SKalle Valo 	pos +=
3787ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
3797ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "actual_ack_cnt:",
3807ac9a364SKalle Valo 		      le32_to_cpu(tx->actual_ack_cnt), accum_tx->actual_ack_cnt,
3817ac9a364SKalle Valo 		      delta_tx->actual_ack_cnt, max_tx->actual_ack_cnt);
3827ac9a364SKalle Valo 
3837ac9a364SKalle Valo 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
3847ac9a364SKalle Valo 	kfree(buf);
3857ac9a364SKalle Valo 	return ret;
3867ac9a364SKalle Valo }
3877ac9a364SKalle Valo 
3887ac9a364SKalle Valo static ssize_t
il3945_ucode_general_stats_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)3897ac9a364SKalle Valo il3945_ucode_general_stats_read(struct file *file, char __user *user_buf,
3907ac9a364SKalle Valo 				size_t count, loff_t *ppos)
3917ac9a364SKalle Valo {
3927ac9a364SKalle Valo 	struct il_priv *il = file->private_data;
3937ac9a364SKalle Valo 	int pos = 0;
3947ac9a364SKalle Valo 	char *buf;
3957ac9a364SKalle Valo 	int bufsz = sizeof(struct iwl39_stats_general) * 10 + 300;
3967ac9a364SKalle Valo 	ssize_t ret;
3977ac9a364SKalle Valo 	struct iwl39_stats_general *general, *accum_general;
3987ac9a364SKalle Valo 	struct iwl39_stats_general *delta_general, *max_general;
3997ac9a364SKalle Valo 	struct stats_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
4007ac9a364SKalle Valo 	struct iwl39_stats_div *div, *accum_div, *delta_div, *max_div;
4017ac9a364SKalle Valo 
4027ac9a364SKalle Valo 	if (!il_is_alive(il))
4037ac9a364SKalle Valo 		return -EAGAIN;
4047ac9a364SKalle Valo 
4057ac9a364SKalle Valo 	buf = kzalloc(bufsz, GFP_KERNEL);
4067ac9a364SKalle Valo 	if (!buf) {
4077ac9a364SKalle Valo 		IL_ERR("Can not allocate Buffer\n");
4087ac9a364SKalle Valo 		return -ENOMEM;
4097ac9a364SKalle Valo 	}
4107ac9a364SKalle Valo 
4117ac9a364SKalle Valo 	/*
4127ac9a364SKalle Valo 	 * The statistic information display here is based on
4137ac9a364SKalle Valo 	 * the last stats notification from uCode
4147ac9a364SKalle Valo 	 * might not reflect the current uCode activity
4157ac9a364SKalle Valo 	 */
4167ac9a364SKalle Valo 	general = &il->_3945.stats.general;
4177ac9a364SKalle Valo 	dbg = &il->_3945.stats.general.dbg;
4187ac9a364SKalle Valo 	div = &il->_3945.stats.general.div;
4197ac9a364SKalle Valo 	accum_general = &il->_3945.accum_stats.general;
4207ac9a364SKalle Valo 	delta_general = &il->_3945.delta_stats.general;
4217ac9a364SKalle Valo 	max_general = &il->_3945.max_delta.general;
4227ac9a364SKalle Valo 	accum_dbg = &il->_3945.accum_stats.general.dbg;
4237ac9a364SKalle Valo 	delta_dbg = &il->_3945.delta_stats.general.dbg;
4247ac9a364SKalle Valo 	max_dbg = &il->_3945.max_delta.general.dbg;
4257ac9a364SKalle Valo 	accum_div = &il->_3945.accum_stats.general.div;
4267ac9a364SKalle Valo 	delta_div = &il->_3945.delta_stats.general.div;
4277ac9a364SKalle Valo 	max_div = &il->_3945.max_delta.general.div;
4287ac9a364SKalle Valo 	pos += il3945_stats_flag(il, buf, bufsz);
4297ac9a364SKalle Valo 	pos +=
4307ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
4317ac9a364SKalle Valo 		      "%-32s     current"
432b9574ce1SColin Ian King 		      "accumulative      delta         max\n",
4337ac9a364SKalle Valo 		      "Statistics_General:");
4347ac9a364SKalle Valo 	pos +=
4357ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
4367ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "burst_check:",
4377ac9a364SKalle Valo 		      le32_to_cpu(dbg->burst_check), accum_dbg->burst_check,
4387ac9a364SKalle Valo 		      delta_dbg->burst_check, max_dbg->burst_check);
4397ac9a364SKalle Valo 	pos +=
4407ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
4417ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "burst_count:",
4427ac9a364SKalle Valo 		      le32_to_cpu(dbg->burst_count), accum_dbg->burst_count,
4437ac9a364SKalle Valo 		      delta_dbg->burst_count, max_dbg->burst_count);
4447ac9a364SKalle Valo 	pos +=
4457ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
4467ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "sleep_time:",
4477ac9a364SKalle Valo 		      le32_to_cpu(general->sleep_time),
4487ac9a364SKalle Valo 		      accum_general->sleep_time, delta_general->sleep_time,
4497ac9a364SKalle Valo 		      max_general->sleep_time);
4507ac9a364SKalle Valo 	pos +=
4517ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
4527ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "slots_out:",
4537ac9a364SKalle Valo 		      le32_to_cpu(general->slots_out), accum_general->slots_out,
4547ac9a364SKalle Valo 		      delta_general->slots_out, max_general->slots_out);
4557ac9a364SKalle Valo 	pos +=
4567ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
4577ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "slots_idle:",
4587ac9a364SKalle Valo 		      le32_to_cpu(general->slots_idle),
4597ac9a364SKalle Valo 		      accum_general->slots_idle, delta_general->slots_idle,
4607ac9a364SKalle Valo 		      max_general->slots_idle);
4617ac9a364SKalle Valo 	pos +=
4627ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
4637ac9a364SKalle Valo 		      le32_to_cpu(general->ttl_timestamp));
4647ac9a364SKalle Valo 	pos +=
4657ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
4667ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "tx_on_a:",
4677ac9a364SKalle Valo 		      le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
4687ac9a364SKalle Valo 		      delta_div->tx_on_a, max_div->tx_on_a);
4697ac9a364SKalle Valo 	pos +=
4707ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
4717ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "tx_on_b:",
4727ac9a364SKalle Valo 		      le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
4737ac9a364SKalle Valo 		      delta_div->tx_on_b, max_div->tx_on_b);
4747ac9a364SKalle Valo 	pos +=
4757ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
4767ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "exec_time:",
4777ac9a364SKalle Valo 		      le32_to_cpu(div->exec_time), accum_div->exec_time,
4787ac9a364SKalle Valo 		      delta_div->exec_time, max_div->exec_time);
4797ac9a364SKalle Valo 	pos +=
4807ac9a364SKalle Valo 	    scnprintf(buf + pos, bufsz - pos,
4817ac9a364SKalle Valo 		      "  %-30s %10u  %10u  %10u  %10u\n", "probe_time:",
4827ac9a364SKalle Valo 		      le32_to_cpu(div->probe_time), accum_div->probe_time,
4837ac9a364SKalle Valo 		      delta_div->probe_time, max_div->probe_time);
4847ac9a364SKalle Valo 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
4857ac9a364SKalle Valo 	kfree(buf);
4867ac9a364SKalle Valo 	return ret;
4877ac9a364SKalle Valo }
4887ac9a364SKalle Valo 
4897ac9a364SKalle Valo const struct il_debugfs_ops il3945_debugfs_ops = {
4907ac9a364SKalle Valo 	.rx_stats_read = il3945_ucode_rx_stats_read,
4917ac9a364SKalle Valo 	.tx_stats_read = il3945_ucode_tx_stats_read,
4927ac9a364SKalle Valo 	.general_stats_read = il3945_ucode_general_stats_read,
4937ac9a364SKalle Valo };
494