iwlwifi: speed up event log dumps
authorBen Cahill <ben.m.cahill@intel.com>
Fri, 6 Nov 2009 22:52:58 +0000 (14:52 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 11 Nov 2009 20:23:46 +0000 (15:23 -0500)
Take advantage of device's auto-increment for SRAM reads to eliminate extra
write address accesses.

Grab/release NIC access before/after entire read sequence, rather than for
each read individually.

After a quick check of dmesg logs, this seems to double Event Log dump speed,
reducing from about 20 milliseconds to about 10 milliseconds for 512 entries
using 3945.

Signed-off-by: Ben Cahill <ben.m.cahill@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl3945-base.c

index 9c40742727a2066b3c3a5f309b93b9c324230bc1..2abd1f5b5eea00a32e3be78d21d567b6302b5813 100644 (file)
@@ -1666,6 +1666,7 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
        u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
        u32 ptr;        /* SRAM byte address of log data */
        u32 ev, time, data; /* event log data */
+       unsigned long reg_flags;
 
        if (num_events == 0)
                return;
@@ -1681,25 +1682,34 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
 
        ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
 
+       /* Make sure device is powered up for SRAM reads */
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       iwl_grab_nic_access(priv);
+
+       /* Set starting address; reads will auto-increment */
+       _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+       rmb();
+
        /* "time" is actually "data" for mode 0 (no timestamp).
        * place event id # at far right for easier visual parsing. */
        for (i = 0; i < num_events; i++) {
-               ev = iwl_read_targ_mem(priv, ptr);
-               ptr += sizeof(u32);
-               time = iwl_read_targ_mem(priv, ptr);
-               ptr += sizeof(u32);
+               ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+               time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                if (mode == 0) {
                        /* data, ev */
                        trace_iwlwifi_dev_ucode_event(priv, 0, time, ev);
                        IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
                } else {
-                       data = iwl_read_targ_mem(priv, ptr);
-                       ptr += sizeof(u32);
+                       data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                        IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
                                        time, data, ev);
                        trace_iwlwifi_dev_ucode_event(priv, time, data, ev);
                }
        }
+
+       /* Allow device to power down */
+       iwl_release_nic_access(priv);
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 }
 
 /* For sanity check only.  Actual size is determined by uCode, typ. 512 */
index a17afe01c0c056c1a9c99fe5fadee597eeb74de0..92ecdd9abd9ffed14cd41c6950b2f314f591024a 100644 (file)
@@ -1570,6 +1570,7 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
        u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
        u32 ptr;        /* SRAM byte address of log data */
        u32 ev, time, data; /* event log data */
+       unsigned long reg_flags;
 
        if (num_events == 0)
                return;
@@ -1583,24 +1584,33 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
 
        ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
 
+       /* Make sure device is powered up for SRAM reads */
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       iwl_grab_nic_access(priv);
+
+       /* Set starting address; reads will auto-increment */
+       _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+       rmb();
+
        /* "time" is actually "data" for mode 0 (no timestamp).
         * place event id # at far right for easier visual parsing. */
        for (i = 0; i < num_events; i++) {
-               ev = iwl_read_targ_mem(priv, ptr);
-               ptr += sizeof(u32);
-               time = iwl_read_targ_mem(priv, ptr);
-               ptr += sizeof(u32);
+               ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+               time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                if (mode == 0) {
                        /* data, ev */
                        IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
                        trace_iwlwifi_dev_ucode_event(priv, 0, time, ev);
                } else {
-                       data = iwl_read_targ_mem(priv, ptr);
-                       ptr += sizeof(u32);
+                       data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                        IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev);
                        trace_iwlwifi_dev_ucode_event(priv, time, data, ev);
                }
        }
+
+       /* Allow device to power down */
+       iwl_release_nic_access(priv);
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 }
 
 /* For sanity check only.  Actual size is determined by uCode, typ. 512 */