[PATCH] acx: make firmware statistics parsing more intelligent

2006-02-03 Thread Andreas Mohr
Hi all,

this patch does:
- implement much more flexible firmware statistics parsing
  (for /proc/driver/acx_wlanX_diag)
  This has the nice effect that we now get output for both the older
  TNETW1100 USB and TNETW1450.
  Since firmware statistics information has non-stable layout depending on
  firmware version, please report if you suspect any parsing mismatch!
  This improved version now uses 2kB more driver space, unfortunately.
- use % 8 modulo instead of more complicated % 5 calculation
- use
if (++idx = count)
  idx = 0;
  instead of more bloaty
idx = (idx + 1) % count;
  We might want to add a kernel macro for this *very* common and
  performance-critical driver operation, say ring_advance_next or so,
  in order to have the most optimized version for each architecture;
  Or ($1 million question): Is there already such a beast somewhere!?
- tiny cleanup

Andreas Mohr

diff -urN acx-20060202/acx_func.h acx-20060202_stats/acx_func.h
--- acx-20060202/acx_func.h 2006-02-01 10:49:31.0 +0100
+++ acx-20060202_stats/acx_func.h   2006-02-05 06:21:35.0 +0100
@@ -257,7 +257,7 @@
 ** but may be run under lock
 **
 ** A small number of local helpers do not have acx_[eisl]_ prefix.
-** They are always close to caller and are to be revieved locally.
+** They are always close to caller and are to be reviewed locally.
 **
 ** Theory of operation:
 **
diff -urN acx-20060202/acx_struct.h acx-20060202_stats/acx_struct.h
--- acx-20060202/acx_struct.h   2006-02-01 10:49:38.0 +0100
+++ acx-20060202_stats/acx_struct.h 2006-02-03 23:21:35.0 +0100
@@ -582,21 +582,34 @@
 
 
 /*--- Firmware statistics 
*/
-typedef struct fw_stats {
-   u32 val0x0 ACX_PACKED;  /* hdr; */
+
+/* define a random 100 bytes more to catch firmware versions which
+ * provide a bigger struct */
+#define FW_STATS_FUTURE_EXTENSION  100
+
+typedef struct fw_stats_tx {
u32 tx_desc_of ACX_PACKED;
+} fw_stats_tx_t;
+
+typedef struct fw_stats_rx {
u32 rx_oom ACX_PACKED;
u32 rx_hdr_of ACX_PACKED;
-   u32 rx_hdr_use_next ACX_PACKED;
+   u32 rx_hw_stuck ACX_PACKED; /* old: u32 rx_hdr_use_next */
u32 rx_dropped_frame ACX_PACKED;
u32 rx_frame_ptr_err ACX_PACKED;
u32 rx_xfr_hint_trig ACX_PACKED;
+   u32 rx_aci_events ACX_PACKED; /* later versions only */
+   u32 rx_aci_resets ACX_PACKED; /* later versions only */
+} fw_stats_rx_t;
 
+typedef struct fw_stats_dma {
u32 rx_dma_req ACX_PACKED;
u32 rx_dma_err ACX_PACKED;
u32 tx_dma_req ACX_PACKED;
u32 tx_dma_err ACX_PACKED;
+} fw_stats_dma_t;
 
+typedef struct fw_stats_irq {
u32 cmd_cplt ACX_PACKED;
u32 fiq ACX_PACKED;
u32 rx_hdrs ACX_PACKED;
@@ -604,23 +617,78 @@
u32 rx_mem_of ACX_PACKED;
u32 rx_rdys ACX_PACKED;
u32 irqs ACX_PACKED;
-   u32 acx_trans_procs ACX_PACKED;
+   u32 tx_procs ACX_PACKED;
u32 decrypt_done ACX_PACKED;
u32 dma_0_done ACX_PACKED;
u32 dma_1_done ACX_PACKED;
u32 tx_exch_complet ACX_PACKED;
u32 commands ACX_PACKED;
-   u32 acx_rx_procs ACX_PACKED;
+   u32 rx_procs ACX_PACKED;
u32 hw_pm_mode_changes ACX_PACKED;
u32 host_acks ACX_PACKED;
u32 pci_pm ACX_PACKED;
u32 acm_wakeups ACX_PACKED;
+} fw_stats_irq_t;
 
+typedef struct fw_stats_wep {
u32 wep_key_count ACX_PACKED;
u32 wep_default_key_count ACX_PACKED;
u32 dot11_def_key_mib ACX_PACKED;
u32 wep_key_not_found ACX_PACKED;
u32 wep_decrypt_fail ACX_PACKED;
+   u32 wep_pkt_decrypt ACX_PACKED;
+   u32 wep_decrypt_irqs ACX_PACKED;
+} fw_stats_wep_t;
+
+typedef struct fw_stats_pwr {
+   u32 tx_start_ctr ACX_PACKED;
+   u32 no_ps_tx_too_short ACX_PACKED;
+   u32 rx_start_ctr ACX_PACKED;
+   u32 no_ps_rx_too_short ACX_PACKED;
+   u32 lppd_started ACX_PACKED;
+   u32 no_lppd_too_noisy ACX_PACKED;
+   u32 no_lppd_too_short ACX_PACKED;
+   u32 no_lppd_matching_frame ACX_PACKED;
+} fw_stats_pwr_t;
+
+typedef struct fw_stats_mic {
+   u32 mic_rx_pkts ACX_PACKED;
+   u32 mic_calc_fail ACX_PACKED;
+} fw_stats_mic_t;
+
+typedef struct fw_stats_aes {
+   u32 aes_enc_fail ACX_PACKED;
+   u32 aes_dec_fail ACX_PACKED;
+   u32 aes_enc_pkts ACX_PACKED;
+   u32 aes_dec_pkts ACX_PACKED;
+   u32 aes_enc_irq ACX_PACKED;
+   u32 aes_dec_irq ACX_PACKED;
+} fw_stats_aes_t;
+
+typedef struct fw_stats_event {
+   u32 heartbeat ACX_PACKED;
+   u32 calibration ACX_PACKED;
+   u32 rx_mismatch ACX_PACKED;
+   u32 rx_mem_empty ACX_PACKED;
+   u32 rx_pool ACX_PACKED;
+   u32 oom_late 

Re: [Acx100-devel] [PATCH] acx: make firmware statistics parsing more intelligent

2006-02-03 Thread Denis Vlasenko
On Friday 03 February 2006 12:58, Andreas Mohr wrote:
 -   adev-tx_head = (head + 1) % TX_CNT;
 +   /* slower: adev-tx_head = (head + 1) % TX_CNT; */
 +   adev-tx_head = head + 1;
 +   if (adev-tx_head = TX_CNT)
 +   adev-tx_head = 0;


struct a {
int tx_head;
};

#define TX_CNT 16

void f(struct a *adev, int head) {
adev-tx_head = (head + 1) % TX_CNT;
}

void g(struct a *adev, int head) {
adev-tx_head = head + 1;
if (adev-tx_head = TX_CNT)
adev-tx_head = 0;
}


gcc -Os -S t.c -fomit-frame-pointer -falign-functions=1 -falign-labels=1 
-falign-loops=1 -falign-jumps=1 -mtune=i386 -march=i386
produces:

f:
movl8(%esp), %eax
incl%eax
movl$16, %edx
movl%edx, %ecx
cltd
idivl   %ecx
movl4(%esp), %eax
movl%edx, (%eax)
ret
.size   f, .-f
.globl g
.type   g, @function
g:
movl4(%esp), %edx
movl8(%esp), %eax
incl%eax
movl%eax, (%edx)
cmpl$15, %eax
jle .L6
movl$0, (%edx)
.L6:
ret
.size   g, .-g
.ident  GCC: (GNU) 4.0.0

Well, gcc obviously failed to realize that % 16 ==  15.
I'll file a bug. Meanwhile, with  15 f() is better:

f:
movl8(%esp), %eax
incl%eax
andl$15, %eax
movl4(%esp), %edx
movl%eax, (%edx)
ret
.size   f, .-f
.globl g
.type   g, @function
g:
movl4(%esp), %edx
movl8(%esp), %eax
incl%eax
movl%eax, (%edx)
cmpl$15, %eax
jle .L6
movl$0, (%edx)
.L6:
ret
.size   g, .-g
.ident  GCC: (GNU) 4.0.0

--
vda
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Acx100-devel] [PATCH] acx: make firmware statistics parsing more intelligent

2006-02-03 Thread Denis Vlasenko
On Friday 03 February 2006 14:39, Denis Vlasenko wrote:
 Well, gcc obviously failed to realize that % 16 ==  15.
 I'll file a bug.

-ENOTABUG. It's incorrect for signed integers,
and gcc uses idiv insn instead.
--
vda
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Acx100-devel] [PATCH] acx: make firmware statistics parsing more intelligent

2006-02-03 Thread Andreas Mohr
Hi,

On Fri, Feb 03, 2006 at 03:28:29PM +0200, Denis Vlasenko wrote:
 On Friday 03 February 2006 14:39, Denis Vlasenko wrote:
  Well, gcc obviously failed to realize that % 16 ==  15.
  I'll file a bug.
 
 -ENOTABUG. It's incorrect for signed integers,
 and gcc uses idiv insn instead.

...which is one of the performance reasons why it may be a good idea
to use unsigned ints wherever signedness isn't required (unsigned int
is said to be faster sometimes, on many platforms).

Andreas Mohr
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html