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.000000000 +0100
+++ acx-20060202_stats/acx_func.h 2006-02-05 06:21:35.000000000 +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.000000000 +0100
+++ acx-20060202_stats/acx_struct.h 2006-02-03 23:21:35.000000000 +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 ACX_PACKED;
+ u32 phy_tx_err ACX_PACKED;
+ u32 tx_stuck ACX_PACKED;
+} fw_stats_event_t;
+
+/* mainly for size calculation only */
+typedef struct fw_stats {
+ u16 type;
+ u16 len;
+ fw_stats_tx_t tx;
+ fw_stats_rx_t rx;
+ fw_stats_dma_t dma;
+ fw_stats_irq_t irq;
+ fw_stats_wep_t wep;
+ fw_stats_pwr_t pwr;
+ fw_stats_mic_t mic;
+ fw_stats_aes_t aes;
+ fw_stats_event_t evt;
} fw_stats_t;
/* Firmware version struct */
diff -urN acx-20060202/common.c acx-20060202_stats/common.c
--- acx-20060202/common.c 2006-02-01 10:49:37.000000000 +0100
+++ acx-20060202_stats/common.c 2006-02-05 06:23:21.000000000 +0100
@@ -851,7 +851,7 @@
ACX1xx_IE_RXCONFIG_LEN,
0,
0,
- ACX1xx_IE_FIRMWARE_STATISTICS_LEN,
+ sizeof(fw_stats_t)-4+FW_STATS_FUTURE_EXTENSION,
0,
ACX1xx_IE_FEATURE_CONFIG_LEN,
ACX111_IE_KEY_CHOOSE_LEN,
@@ -928,7 +928,7 @@
ACX1xx_IE_RXCONFIG_LEN,
0,
0,
- ACX1xx_IE_FIRMWARE_STATISTICS_LEN,
+ sizeof(fw_stats_t)-4+FW_STATS_FUTURE_EXTENSION,
0,
ACX1xx_IE_FEATURE_CONFIG_LEN,
ACX111_IE_KEY_CHOOSE_LEN,
@@ -1148,20 +1148,27 @@
acx_s_proc_diag_output(char *buf, acx_device_t *adev)
{
char *p = buf;
- fw_stats_t *fw_stats;
unsigned long flags;
+ unsigned int len = 0, partlen;
+ u32 temp1, temp2;
+ u8 *st, *st_end;
+#ifdef __BIG_ENDIAN
+ u8 *st2;
+#endif
+ fw_stats_t *fw_stats;
+ char *part_str = NULL;
+ fw_stats_tx_t *tx = NULL;
+ fw_stats_rx_t *rx = NULL;
+ fw_stats_dma_t *dma = NULL;
+ fw_stats_irq_t *irq = NULL;
+ fw_stats_wep_t *wep = NULL;
+ fw_stats_pwr_t *pwr = NULL;
+ fw_stats_mic_t *mic = NULL;
+ fw_stats_aes_t *aes = NULL;
+ fw_stats_event_t *evt = NULL;
FN_ENTER;
- /* TODO: may replace kmalloc/memset with kzalloc once
- * Linux 2.6.14 is widespread */
- fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
- if (!fw_stats) {
- FN_EXIT1(0);
- return 0;
- }
- memset(fw_stats, 0, sizeof(*fw_stats));
-
acx_lock(adev, flags);
if (IS_PCI(adev))
@@ -1205,63 +1212,322 @@
acx_unlock(adev, flags);
- if (OK != acx_s_interrogate(adev, fw_stats,
ACX1xx_IE_FIRMWARE_STATISTICS))
- p += sprintf(p,
- "\n"
- "** Firmware **\n"
- "QUERY FAILED!!\n");
- else {
- p += sprintf(p,
- "\n"
- "** Firmware **\n"
- "version \"%s\"\n"
- "tx_desc_overfl %u, rx_OutOfMem %u, rx_hdr_overfl %u,
rx_hdr_use_next %u\n"
- "rx_dropped_frame %u, rx_frame_ptr_err %u,
rx_xfr_hint_trig %u, rx_dma_req %u\n"
- "rx_dma_err %u, tx_dma_req %u, tx_dma_err %u, cmd_cplt
%u, fiq %u\n"
- "rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u,
irqs %u\n"
- "acx_trans_procs %u, decrypt_done %u, dma_0_done %u,
dma_1_done %u\n",
- adev->firmware_version,
- le32_to_cpu(fw_stats->tx_desc_of),
- le32_to_cpu(fw_stats->rx_oom),
- le32_to_cpu(fw_stats->rx_hdr_of),
- le32_to_cpu(fw_stats->rx_hdr_use_next),
- le32_to_cpu(fw_stats->rx_dropped_frame),
- le32_to_cpu(fw_stats->rx_frame_ptr_err),
- le32_to_cpu(fw_stats->rx_xfr_hint_trig),
- le32_to_cpu(fw_stats->rx_dma_req),
- le32_to_cpu(fw_stats->rx_dma_err),
- le32_to_cpu(fw_stats->tx_dma_req),
- le32_to_cpu(fw_stats->tx_dma_err),
- le32_to_cpu(fw_stats->cmd_cplt),
- le32_to_cpu(fw_stats->fiq),
- le32_to_cpu(fw_stats->rx_hdrs),
- le32_to_cpu(fw_stats->rx_cmplt),
- le32_to_cpu(fw_stats->rx_mem_of),
- le32_to_cpu(fw_stats->rx_rdys),
- le32_to_cpu(fw_stats->irqs),
- le32_to_cpu(fw_stats->acx_trans_procs),
- le32_to_cpu(fw_stats->decrypt_done),
- le32_to_cpu(fw_stats->dma_0_done),
- le32_to_cpu(fw_stats->dma_1_done));
+ p += sprintf(p,
+ "\n"
+ "** Firmware **\n"
+ "NOTE: version dependent statistics layout, "
+ "please report if you suspect wrong parsing!\n"
+ "\n"
+ "version \"%s\"\n", adev->firmware_version);
+
+ /* TODO: may replace kmalloc/memset with kzalloc once
+ * Linux 2.6.14 is widespread */
+ fw_stats = kmalloc(sizeof(*fw_stats)+FW_STATS_FUTURE_EXTENSION,
GFP_KERNEL);
+ if (!fw_stats) {
+ FN_EXIT1(0);
+ return 0;
+ }
+ memset(fw_stats, 0, sizeof(*fw_stats)+FW_STATS_FUTURE_EXTENSION);
+
+ st = (u8 *)fw_stats;
+
+ part_str = "statistics query command";
+
+ if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS))
+ goto fw_stats_end;
+
+ st += sizeof(u16);
+ len = *(u16 *)st;
+
+ if (len > sizeof(*fw_stats)) {
p += sprintf(p,
- "tx_exch_complet %u, commands %u, acx_rx_procs %u\n"
- "hw_pm_mode_changes %u, host_acks %u, pci_pm %u,
acm_wakeups %u\n"
- "wep_key_count %u, wep_default_key_count %u,
dot11_def_key_mib %u\n"
- "wep_key_not_found %u, wep_decrypt_fail %u\n",
- le32_to_cpu(fw_stats->tx_exch_complet),
- le32_to_cpu(fw_stats->commands),
- le32_to_cpu(fw_stats->acx_rx_procs),
- le32_to_cpu(fw_stats->hw_pm_mode_changes),
- le32_to_cpu(fw_stats->host_acks),
- le32_to_cpu(fw_stats->pci_pm),
- le32_to_cpu(fw_stats->acm_wakeups),
- le32_to_cpu(fw_stats->wep_key_count),
- le32_to_cpu(fw_stats->wep_default_key_count),
- le32_to_cpu(fw_stats->dot11_def_key_mib),
- le32_to_cpu(fw_stats->wep_key_not_found),
- le32_to_cpu(fw_stats->wep_decrypt_fail));
+ "firmware version with bigger fw_stats struct
detected\n"
+ "(%u vs. %u), PLEASE REPORT!!\n", len,
sizeof(fw_stats_t));
+ if (len > sizeof(*fw_stats)+FW_STATS_FUTURE_EXTENSION) {
+ p += sprintf(p, "struct size exceeded allocation!\n");
+ len = sizeof(*fw_stats)+FW_STATS_FUTURE_EXTENSION;
+ }
+ }
+ st += sizeof(u16);
+ st_end = st - 2*sizeof(u16) + len;
+
+#ifdef __BIG_ENDIAN
+ /* let's make one bold assumption here:
+ * (hopefully!) *all* statistics fields are u32 only,
+ * thus if we need to make endianness corrections
+ * we can simply do them in one go, in advance */
+ st2 = (u8 *)fw_stats;
+ for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
+ *(u32 *)st2 = le32_to_cpu(*(u32 *)st2);
+#endif
+
+ part_str = "Rx/Tx";
+
+ /* directly at end of a struct part? --> no error! */
+ if (st == st_end)
+ goto fw_stats_end;
+
+ tx = (fw_stats_tx_t *)st;
+ st += sizeof(fw_stats_tx_t);
+ rx = (fw_stats_rx_t *)st;
+ st += sizeof(fw_stats_rx_t);
+ partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
+
+ if (
+ (IS_PCI(adev) && IS_ACX100(adev))
+ || (IS_USB(adev) && IS_ACX100(adev))
+ ) {
+ /* at least ACX100 PCI F/W 1.9.8.b
+ * and ACX100 USB F/W 1.0.7-USB
+ * don't have those two fields... */
+ st -= 2*sizeof(u32);
+
+ /* our parsing doesn't quite match this firmware yet,
+ * log failure */
+ if (st > st_end)
+ goto fw_stats_fail;
+ temp1 = temp2 = 999999999;
+ } else {
+ if (st > st_end)
+ goto fw_stats_fail;
+ temp1 = rx->rx_aci_events;
+ temp2 = rx->rx_aci_resets;
}
+ p += sprintf(p,
+ "%s:\n"
+ " tx_desc_overfl %u\n"
+ " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
+ " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig
%u\n"
+ " rx_aci_events %u, rx_aci_resets %u\n",
+ part_str,
+ tx->tx_desc_of,
+ rx->rx_oom,
+ rx->rx_hdr_of,
+ rx->rx_hw_stuck,
+ rx->rx_dropped_frame,
+ rx->rx_frame_ptr_err,
+ rx->rx_xfr_hint_trig,
+ temp1,
+ temp2);
+
+ part_str = "DMA";
+
+ if (st == st_end)
+ goto fw_stats_end;
+
+ dma = (fw_stats_dma_t *)st;
+ partlen = sizeof(fw_stats_dma_t);
+ st += partlen;
+
+ if (st > st_end)
+ goto fw_stats_fail;
+
+ p += sprintf(p,
+ "%s:\n"
+ " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err
%u\n",
+ part_str,
+ dma->rx_dma_req,
+ dma->rx_dma_err,
+ dma->tx_dma_req,
+ dma->tx_dma_err);
+
+ part_str = "IRQ";
+
+ if (st == st_end)
+ goto fw_stats_end;
+
+ irq = (fw_stats_irq_t *)st;
+ partlen = sizeof(fw_stats_irq_t);
+ st += partlen;
+
+ if (st > st_end)
+ goto fw_stats_fail;
+
+ p += sprintf(p,
+ "%s:\n"
+ " cmd_cplt %u, fiq %u\n"
+ " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
+ " irqs %u, tx_procs %u, decrypt_done %u\n"
+ " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
+ " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
+ " host_acks %u, pci_pm %u, acm_wakeups %u\n",
+ part_str,
+ irq->cmd_cplt,
+ irq->fiq,
+ irq->rx_hdrs,
+ irq->rx_cmplt,
+ irq->rx_mem_of,
+ irq->rx_rdys,
+ irq->irqs,
+ irq->tx_procs,
+ irq->decrypt_done,
+ irq->dma_0_done,
+ irq->dma_1_done,
+ irq->tx_exch_complet,
+ irq->commands,
+ irq->rx_procs,
+ irq->hw_pm_mode_changes,
+ irq->host_acks,
+ irq->pci_pm,
+ irq->acm_wakeups);
+
+ part_str = "WEP";
+
+ if (st == st_end)
+ goto fw_stats_end;
+
+ wep = (fw_stats_wep_t *)st;
+ partlen = sizeof(fw_stats_wep_t);
+ st += partlen;
+
+ if (
+ (IS_PCI(adev) && IS_ACX100(adev))
+ || (IS_USB(adev) && IS_ACX100(adev))
+ ) {
+ /* at least ACX100 PCI F/W 1.9.8.b
+ * and ACX100 USB F/W 1.0.7-USB
+ * don't have those two fields... */
+ st -= 2*sizeof(u32);
+ if (st > st_end)
+ goto fw_stats_fail;
+ temp1 = temp2 = 999999999;
+ } else {
+ if (st > st_end)
+ goto fw_stats_fail;
+ temp1 = wep->wep_pkt_decrypt;
+ temp2 = wep->wep_decrypt_irqs;
+ }
+
+ p += sprintf(p,
+ "%s:\n"
+ " wep_key_count %u, wep_default_key_count %u,
dot11_def_key_mib %u\n"
+ " wep_key_not_found %u, wep_decrypt_fail %u\n"
+ " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
+ part_str,
+ wep->wep_key_count,
+ wep->wep_default_key_count,
+ wep->dot11_def_key_mib,
+ wep->wep_key_not_found,
+ wep->wep_decrypt_fail,
+ temp1,
+ temp2);
+
+ part_str = "power";
+
+ if (st == st_end)
+ goto fw_stats_end;
+
+ pwr = (fw_stats_pwr_t *)st;
+ partlen = sizeof(fw_stats_pwr_t);
+ st += partlen;
+
+ if (st > st_end)
+ goto fw_stats_fail;
+
+ p += sprintf(p,
+ "%s:\n"
+ " tx_start_ctr %u, no_ps_tx_too_short %u\n"
+ " rx_start_ctr %u, no_ps_rx_too_short %u\n"
+ " lppd_started %u\n"
+ " no_lppd_too_noisy %u, no_lppd_too_short %u,
no_lppd_matching_frame %u\n",
+ part_str,
+ pwr->tx_start_ctr,
+ pwr->no_ps_tx_too_short,
+ pwr->rx_start_ctr,
+ pwr->no_ps_rx_too_short,
+ pwr->lppd_started,
+ pwr->no_lppd_too_noisy,
+ pwr->no_lppd_too_short,
+ pwr->no_lppd_matching_frame);
+
+ part_str = "MIC";
+
+ if (st == st_end)
+ goto fw_stats_end;
+
+ mic = (fw_stats_mic_t *)st;
+ partlen = sizeof(fw_stats_mic_t);
+ st += partlen;
+
+ if (st > st_end)
+ goto fw_stats_fail;
+
+ p += sprintf(p,
+ "%s:\n"
+ " mic_rx_pkts %u, mic_calc_fail %u\n",
+ part_str,
+ mic->mic_rx_pkts,
+ mic->mic_calc_fail);
+
+ part_str = "AES";
+
+ if (st == st_end)
+ goto fw_stats_end;
+
+ aes = (fw_stats_aes_t *)st;
+ partlen = sizeof(fw_stats_aes_t);
+ st += partlen;
+
+ if (st > st_end)
+ goto fw_stats_fail;
+
+ p += sprintf(p,
+ "%s:\n"
+ " aes_enc_fail %u, aes_dec_fail %u\n"
+ " aes_enc_pkts %u, aes_dec_pkts %u\n"
+ " aes_enc_irq %u, aes_dec_irq %u\n",
+ part_str,
+ aes->aes_enc_fail,
+ aes->aes_dec_fail,
+ aes->aes_enc_pkts,
+ aes->aes_dec_pkts,
+ aes->aes_enc_irq,
+ aes->aes_dec_irq);
+
+ part_str = "event";
+
+ if (st == st_end)
+ goto fw_stats_end;
+
+ evt = (fw_stats_event_t *)st;
+ partlen = sizeof(fw_stats_event_t);
+ st += partlen;
+
+ if (st > st_end)
+ goto fw_stats_fail;
+
+ p += sprintf(p,
+ "%s:\n"
+ " heartbeat %u, calibration %u\n"
+ " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
+ " oom_late %u\n"
+ " phy_tx_err %u, tx_stuck %u\n",
+ part_str,
+ evt->heartbeat,
+ evt->calibration,
+ evt->rx_mismatch,
+ evt->rx_mem_empty,
+ evt->rx_pool,
+ evt->oom_late,
+ evt->phy_tx_err,
+ evt->tx_stuck);
+
+ if (st < st_end)
+ goto fw_stats_bigger;
+
+ goto fw_stats_end;
+
+fw_stats_fail:
+ st -= partlen;
+ p += sprintf(p,
+ "failed at %s part (size %u), offset %u (struct size %u),
PLEASE REPORT!\n", part_str, partlen, (int)st - (int)fw_stats, len);
+fw_stats_bigger:
+ for (; st < st_end; st += 4)
+ p += sprintf(p,
+ "UNKN%3d: %u\n", (int)st - (int)fw_stats, *(u32 *)st);
+
+fw_stats_end:
kfree(fw_stats);
FN_EXIT1(p - buf);
diff -urN acx-20060202/pci.c acx-20060202_stats/pci.c
--- acx-20060202/pci.c 2006-02-01 10:49:33.000000000 +0100
+++ acx-20060202_stats/pci.c 2006-02-04 19:30:29.000000000 +0100
@@ -1058,13 +1058,13 @@
/* Test for IDLE state */
if (!cmd_status)
break;
- if (counter % 5 == 0) {
+ if (counter % 8 == 0) {
if (time_after(jiffies, timeout)) {
counter = 0;
break;
}
- /* we waited 5 iterations, no luck. Sleep 5 ms */
- acx_s_msleep(5);
+ /* we waited 8 iterations, no luck. Sleep 8 ms */
+ acx_s_msleep(8);
}
} while (likely(--counter));
@@ -1124,13 +1124,13 @@
break;
}
- if (counter % 5 == 0) {
+ if (counter % 8 == 0) {
if (time_after(jiffies, timeout)) {
counter = 0;
break;
}
- /* we waited 5 iterations, no luck. Sleep 5 ms */
- acx_s_msleep(5);
+ /* we waited 8 iterations, no luck. Sleep 8 ms */
+ acx_s_msleep(8);
}
} while (likely(--counter));
@@ -2307,7 +2307,9 @@
while (1) {
hostdesc = &adev->rxhostdesc_start[tail];
/* advance tail regardless of outcome of the below test */
- tail = (tail + 1) % RX_CNT;
+ /* smaller/less writes than: tail = (tail + 1) % RX_CNT; */
+ if (++tail >= RX_CNT)
+ tail = 0;
if ((hostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN))
&& (hostdesc->Status & cpu_to_le32(DESC_STATUS_FULL)))
@@ -2338,7 +2340,9 @@
|| !(hostdesc->Status & cpu_to_le32(DESC_STATUS_FULL)))
break;
- tail = (tail + 1) % RX_CNT;
+ /* slower: tail = (tail + 1) % RX_CNT; */
+ if (++tail >= RX_CNT)
+ tail = 0;
}
end:
adev->rx_tail = tail;
@@ -3065,7 +3069,10 @@
}
/* returning current descriptor, so advance to next free one */
- 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;
end:
FN_EXIT0;
@@ -3497,7 +3504,9 @@
finger, ack_failures, rts_failures, rts_ok,
r100);
/* update pointer for descr to be cleaned next */
- finger = (finger + 1) % TX_CNT;
+ /* slower: finger = (finger + 1) % TX_CNT; */
+ if (++finger >= TX_CNT)
+ finger = 0;
}
/* remember last position */
diff -urN acx-20060202/usb.c acx-20060202_stats/usb.c
--- acx-20060202/usb.c 2006-02-01 10:49:34.000000000 +0100
+++ acx-20060202_stats/usb.c 2006-02-03 10:24:07.000000000 +0100
@@ -1576,7 +1576,10 @@
head = adev->tx_head;
do {
- head = (head + 1) % ACX_TX_URB_CNT;
+ /* slower: head = (head + 1) % ACX_TX_URB_CNT; */
+ if (++head >= ACX_TX_URB_CNT)
+ head = 0;
+
if (!adev->usb_tx[head].busy) {
log(L_USBRXTX, "allocated tx %d\n", head);
tx = &adev->usb_tx[head];
-
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