aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h90
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h10
4 files changed, 91 insertions, 54 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index cdeb09eee739..f8559cc974f8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1878,6 +1878,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1878 u32 desc, time, count, base, data1; 1878 u32 desc, time, count, base, data1;
1879 u32 blink1, blink2, ilink1, ilink2; 1879 u32 blink1, blink2, ilink1, ilink2;
1880 u32 pc, hcmd; 1880 u32 pc, hcmd;
1881 struct iwl_error_event_table table;
1881 1882
1882 base = priv->device_pointers.error_event_table; 1883 base = priv->device_pointers.error_event_table;
1883 if (priv->ucode_type == UCODE_INIT) { 1884 if (priv->ucode_type == UCODE_INIT) {
@@ -1895,7 +1896,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1895 return; 1896 return;
1896 } 1897 }
1897 1898
1898 count = iwl_read_targ_mem(priv, base); 1899 iwl_read_targ_mem_words(priv, base, &table, sizeof(table));
1900
1901 count = table.valid;
1899 1902
1900 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { 1903 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
1901 IWL_ERR(priv, "Start IWL Error Log Dump:\n"); 1904 IWL_ERR(priv, "Start IWL Error Log Dump:\n");
@@ -1903,18 +1906,18 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1903 priv->status, count); 1906 priv->status, count);
1904 } 1907 }
1905 1908
1906 desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32)); 1909 desc = table.error_id;
1907 priv->isr_stats.err_code = desc; 1910 priv->isr_stats.err_code = desc;
1908 pc = iwl_read_targ_mem(priv, base + 2 * sizeof(u32)); 1911 pc = table.pc;
1909 blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32)); 1912 blink1 = table.blink1;
1910 blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32)); 1913 blink2 = table.blink2;
1911 ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32)); 1914 ilink1 = table.ilink1;
1912 ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32)); 1915 ilink2 = table.ilink2;
1913 data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32)); 1916 data1 = table.data1;
1914 data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32)); 1917 data2 = table.data2;
1915 line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32)); 1918 line = table.line;
1916 time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32)); 1919 time = table.tsf_low;
1917 hcmd = iwl_read_targ_mem(priv, base + 22 * sizeof(u32)); 1920 hcmd = table.hcmd;
1918 1921
1919 trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line, 1922 trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line,
1920 blink1, blink2, ilink1, ilink2); 1923 blink1, blink2, ilink1, ilink2);
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 0edba8a6419b..7aea7b34f36c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -422,49 +422,61 @@ struct iwl_tx_ant_config_cmd {
422 * 422 *
423 * 2) error_event_table_ptr indicates base of the error log. This contains 423 * 2) error_event_table_ptr indicates base of the error log. This contains
424 * information about any uCode error that occurs. For agn, the format 424 * information about any uCode error that occurs. For agn, the format
425 * of the error log is: 425 * of the error log is defined by struct iwl_error_event_table.
426 *
427 * __le32 valid; (nonzero) valid, (0) log is empty
428 * __le32 error_id; type of error
429 * __le32 pc; program counter
430 * __le32 blink1; branch link
431 * __le32 blink2; branch link
432 * __le32 ilink1; interrupt link
433 * __le32 ilink2; interrupt link
434 * __le32 data1; error-specific data
435 * __le32 data2; error-specific data
436 * __le32 line; source code line of error
437 * __le32 bcon_time; beacon timer
438 * __le32 tsf_low; network timestamp function timer
439 * __le32 tsf_hi; network timestamp function timer
440 * __le32 gp1; GP1 timer register
441 * __le32 gp2; GP2 timer register
442 * __le32 gp3; GP3 timer register
443 * __le32 ucode_ver; uCode version
444 * __le32 hw_ver; HW Silicon version
445 * __le32 brd_ver; HW board version
446 * __le32 log_pc; log program counter
447 * __le32 frame_ptr; frame pointer
448 * __le32 stack_ptr; stack pointer
449 * __le32 hcmd; last host command
450 * __le32 isr0; isr status register LMPM_NIC_ISR0: rxtx_flag
451 * __le32 isr1; isr status register LMPM_NIC_ISR1: host_flag
452 * __le32 isr2; isr status register LMPM_NIC_ISR2: enc_flag
453 * __le32 isr3; isr status register LMPM_NIC_ISR3: time_flag
454 * __le32 isr4; isr status register LMPM_NIC_ISR4: wico interrupt
455 * __le32 isr_pref; isr status register LMPM_NIC_PREF_STAT
456 * __le32 wait_event; wait event() caller address
457 * __le32 l2p_control; L2pControlField
458 * __le32 l2p_duration; L2pDurationField
459 * __le32 l2p_mhvalid; L2pMhValidBits
460 * __le32 l2p_addr_match; L2pAddrMatchStat
461 * __le32 lmpm_pmg_sel; indicate which clocks are turned on (LMPM_PMG_SEL)
462 * __le32 u_timestamp; indicate when the date and time of the compilation
463 * __le32 reserved;
464 * 426 *
465 * The Linux driver can print both logs to the system log when a uCode error 427 * The Linux driver can print both logs to the system log when a uCode error
466 * occurs. 428 * occurs.
467 */ 429 */
430
431/*
432 * Note: This structure is read from the device with IO accesses,
433 * and the reading already does the endian conversion. As it is
434 * read with u32-sized accesses, any members with a different size
435 * need to be ordered correctly though!
436 */
437struct iwl_error_event_table {
438 u32 valid; /* (nonzero) valid, (0) log is empty */
439 u32 error_id; /* type of error */
440 u32 pc; /* program counter */
441 u32 blink1; /* branch link */
442 u32 blink2; /* branch link */
443 u32 ilink1; /* interrupt link */
444 u32 ilink2; /* interrupt link */
445 u32 data1; /* error-specific data */
446 u32 data2; /* error-specific data */
447 u32 line; /* source code line of error */
448 u32 bcon_time; /* beacon timer */
449 u32 tsf_low; /* network timestamp function timer */
450 u32 tsf_hi; /* network timestamp function timer */
451 u32 gp1; /* GP1 timer register */
452 u32 gp2; /* GP2 timer register */
453 u32 gp3; /* GP3 timer register */
454 u32 ucode_ver; /* uCode version */
455 u32 hw_ver; /* HW Silicon version */
456 u32 brd_ver; /* HW board version */
457 u32 log_pc; /* log program counter */
458 u32 frame_ptr; /* frame pointer */
459 u32 stack_ptr; /* stack pointer */
460 u32 hcmd; /* last host command header */
461#if 0
462 /* no need to read the remainder, we don't use the values */
463 u32 isr0; /* isr status register LMPM_NIC_ISR0: rxtx_flag */
464 u32 isr1; /* isr status register LMPM_NIC_ISR1: host_flag */
465 u32 isr2; /* isr status register LMPM_NIC_ISR2: enc_flag */
466 u32 isr3; /* isr status register LMPM_NIC_ISR3: time_flag */
467 u32 isr4; /* isr status register LMPM_NIC_ISR4: wico interrupt */
468 u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
469 u32 wait_event; /* wait event() caller address */
470 u32 l2p_control; /* L2pControlField */
471 u32 l2p_duration; /* L2pDurationField */
472 u32 l2p_mhvalid; /* L2pMhValidBits */
473 u32 l2p_addr_match; /* L2pAddrMatchStat */
474 u32 lmpm_pmg_sel; /* indicate which clocks are turned on (LMPM_PMG_SEL) */
475 u32 u_timestamp; /* indicate when the date and time of the compilation */
476 u32 flow_handler; /* FH read/write pointers, RX credit */
477#endif
478} __packed;
479
468struct iwl_alive_resp { 480struct iwl_alive_resp {
469 u8 ucode_minor; 481 u8 ucode_minor;
470 u8 ucode_major; 482 u8 ucode_major;
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index 51337416e4ca..993b3df1b72b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -242,20 +242,32 @@ void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
242 spin_unlock_irqrestore(&priv->reg_lock, flags); 242 spin_unlock_irqrestore(&priv->reg_lock, flags);
243} 243}
244 244
245u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr) 245void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr,
246 void *buf, int words)
246{ 247{
247 unsigned long flags; 248 unsigned long flags;
248 u32 value; 249 int offs;
250 u32 *vals = buf;
249 251
250 spin_lock_irqsave(&priv->reg_lock, flags); 252 spin_lock_irqsave(&priv->reg_lock, flags);
251 iwl_grab_nic_access(priv); 253 iwl_grab_nic_access(priv);
252 254
253 iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr); 255 iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr);
254 rmb(); 256 rmb();
255 value = iwl_read32(priv, HBUS_TARG_MEM_RDAT); 257
258 for (offs = 0; offs < words; offs++)
259 vals[offs] = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
256 260
257 iwl_release_nic_access(priv); 261 iwl_release_nic_access(priv);
258 spin_unlock_irqrestore(&priv->reg_lock, flags); 262 spin_unlock_irqrestore(&priv->reg_lock, flags);
263}
264
265u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
266{
267 u32 value;
268
269 _iwl_read_targ_mem_words(priv, addr, &value, 1);
270
259 return value; 271 return value;
260} 272}
261 273
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index ab632baf49d5..262e0262496d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -76,6 +76,16 @@ void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
76 u32 bits, u32 mask); 76 u32 bits, u32 mask);
77void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask); 77void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask);
78 78
79void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr,
80 void *buf, int words);
81
82#define iwl_read_targ_mem_words(priv, addr, buf, bufsize) \
83 do { \
84 BUILD_BUG_ON((bufsize) % sizeof(u32)); \
85 _iwl_read_targ_mem_words(priv, addr, buf, \
86 (bufsize) / sizeof(u32));\
87 } while (0)
88
79u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr); 89u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr);
80void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val); 90void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val);
81#endif 91#endif