aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-05-06 02:24:54 -0400
committerReinette Chatre <reinette.chatre@intel.com>2010-05-13 13:44:28 -0400
commitb2e640d4851abfe6b03fc91597d0b8378c629907 (patch)
tree8b61a49d6d9332f3a6ea35fd02eb691231e7d06c /drivers
parent9c5ac091b269912cd30fade987f4bc615ef3be90 (diff)
iwlagn: use firmware event/error log information
In order to debug problems before the ALIVE notification is received, new firmware files contain the event/error log information in the file. Use that information. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c102
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h9
2 files changed, 99 insertions, 12 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index f62a345d71dc..845d0eeb0c86 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1543,6 +1543,9 @@ struct iwlagn_firmware_pieces {
1543 size_t inst_size, data_size, init_size, init_data_size, boot_size; 1543 size_t inst_size, data_size, init_size, init_data_size, boot_size;
1544 1544
1545 u32 build; 1545 u32 build;
1546
1547 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
1548 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
1546}; 1549};
1547 1550
1548static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, 1551static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
@@ -1720,6 +1723,42 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1720 capa->max_probe_length = 1723 capa->max_probe_length =
1721 le32_to_cpup((__le32 *)tlv_data); 1724 le32_to_cpup((__le32 *)tlv_data);
1722 break; 1725 break;
1726 case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
1727 if (tlv_len != 4)
1728 return -EINVAL;
1729 pieces->init_evtlog_ptr =
1730 le32_to_cpup((__le32 *)tlv_data);
1731 break;
1732 case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
1733 if (tlv_len != 4)
1734 return -EINVAL;
1735 pieces->init_evtlog_size =
1736 le32_to_cpup((__le32 *)tlv_data);
1737 break;
1738 case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
1739 if (tlv_len != 4)
1740 return -EINVAL;
1741 pieces->init_errlog_ptr =
1742 le32_to_cpup((__le32 *)tlv_data);
1743 break;
1744 case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
1745 if (tlv_len != 4)
1746 return -EINVAL;
1747 pieces->inst_evtlog_ptr =
1748 le32_to_cpup((__le32 *)tlv_data);
1749 break;
1750 case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
1751 if (tlv_len != 4)
1752 return -EINVAL;
1753 pieces->inst_evtlog_size =
1754 le32_to_cpup((__le32 *)tlv_data);
1755 break;
1756 case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
1757 if (tlv_len != 4)
1758 return -EINVAL;
1759 pieces->inst_errlog_ptr =
1760 le32_to_cpup((__le32 *)tlv_data);
1761 break;
1723 default: 1762 default:
1724 break; 1763 break;
1725 } 1764 }
@@ -1912,6 +1951,26 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1912 goto err_pci_alloc; 1951 goto err_pci_alloc;
1913 } 1952 }
1914 1953
1954 /* Now that we can no longer fail, copy information */
1955
1956 /*
1957 * The (size - 16) / 12 formula is based on the information recorded
1958 * for each event, which is of mode 1 (including timestamp) for all
1959 * new microcodes that include this information.
1960 */
1961 priv->_agn.init_evtlog_ptr = pieces.init_evtlog_ptr;
1962 if (pieces.init_evtlog_size)
1963 priv->_agn.init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
1964 else
1965 priv->_agn.init_evtlog_size = priv->cfg->max_event_log_size;
1966 priv->_agn.init_errlog_ptr = pieces.init_errlog_ptr;
1967 priv->_agn.inst_evtlog_ptr = pieces.inst_evtlog_ptr;
1968 if (pieces.inst_evtlog_size)
1969 priv->_agn.inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
1970 else
1971 priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size;
1972 priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
1973
1915 /* Copy images into buffers for card's bus-master reads ... */ 1974 /* Copy images into buffers for card's bus-master reads ... */
1916 1975
1917 /* Runtime instructions (first block of data in file) */ 1976 /* Runtime instructions (first block of data in file) */
@@ -2037,10 +2096,15 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
2037 u32 blink1, blink2, ilink1, ilink2; 2096 u32 blink1, blink2, ilink1, ilink2;
2038 u32 pc, hcmd; 2097 u32 pc, hcmd;
2039 2098
2040 if (priv->ucode_type == UCODE_INIT) 2099 if (priv->ucode_type == UCODE_INIT) {
2041 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); 2100 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
2042 else 2101 if (!base)
2102 base = priv->_agn.init_errlog_ptr;
2103 } else {
2043 base = le32_to_cpu(priv->card_alive.error_event_table_ptr); 2104 base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
2105 if (!base)
2106 base = priv->_agn.inst_errlog_ptr;
2107 }
2044 2108
2045 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { 2109 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
2046 IWL_ERR(priv, 2110 IWL_ERR(priv,
@@ -2100,10 +2164,16 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
2100 2164
2101 if (num_events == 0) 2165 if (num_events == 0)
2102 return pos; 2166 return pos;
2103 if (priv->ucode_type == UCODE_INIT) 2167
2168 if (priv->ucode_type == UCODE_INIT) {
2104 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 2169 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
2105 else 2170 if (!base)
2171 base = priv->_agn.init_evtlog_ptr;
2172 } else {
2106 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 2173 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
2174 if (!base)
2175 base = priv->_agn.inst_evtlog_ptr;
2176 }
2107 2177
2108 if (mode == 0) 2178 if (mode == 0)
2109 event_size = 2 * sizeof(u32); 2179 event_size = 2 * sizeof(u32);
@@ -2205,13 +2275,21 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
2205 u32 num_wraps; /* # times uCode wrapped to top of log */ 2275 u32 num_wraps; /* # times uCode wrapped to top of log */
2206 u32 next_entry; /* index of next entry to be written by uCode */ 2276 u32 next_entry; /* index of next entry to be written by uCode */
2207 u32 size; /* # entries that we'll print */ 2277 u32 size; /* # entries that we'll print */
2278 u32 logsize;
2208 int pos = 0; 2279 int pos = 0;
2209 size_t bufsz = 0; 2280 size_t bufsz = 0;
2210 2281
2211 if (priv->ucode_type == UCODE_INIT) 2282 if (priv->ucode_type == UCODE_INIT) {
2212 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 2283 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
2213 else 2284 logsize = priv->_agn.init_evtlog_size;
2285 if (!base)
2286 base = priv->_agn.init_evtlog_ptr;
2287 } else {
2214 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 2288 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
2289 logsize = priv->_agn.inst_evtlog_size;
2290 if (!base)
2291 base = priv->_agn.inst_evtlog_ptr;
2292 }
2215 2293
2216 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { 2294 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
2217 IWL_ERR(priv, 2295 IWL_ERR(priv,
@@ -2226,16 +2304,16 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
2226 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); 2304 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
2227 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); 2305 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
2228 2306
2229 if (capacity > priv->cfg->max_event_log_size) { 2307 if (capacity > logsize) {
2230 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", 2308 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
2231 capacity, priv->cfg->max_event_log_size); 2309 capacity, logsize);
2232 capacity = priv->cfg->max_event_log_size; 2310 capacity = logsize;
2233 } 2311 }
2234 2312
2235 if (next_entry > priv->cfg->max_event_log_size) { 2313 if (next_entry > logsize) {
2236 IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", 2314 IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
2237 next_entry, priv->cfg->max_event_log_size); 2315 next_entry, logsize);
2238 next_entry = priv->cfg->max_event_log_size; 2316 next_entry = logsize;
2239 } 2317 }
2240 2318
2241 size = num_wraps ? capacity : next_entry; 2319 size = num_wraps ? capacity : next_entry;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 5ac03f5a4713..fdd043014ec2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -583,6 +583,12 @@ enum iwl_ucode_tlv_type {
583 IWL_UCODE_TLV_INIT_DATA = 4, 583 IWL_UCODE_TLV_INIT_DATA = 4,
584 IWL_UCODE_TLV_BOOT = 5, 584 IWL_UCODE_TLV_BOOT = 5,
585 IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ 585 IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */
586 IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8,
587 IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9,
588 IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10,
589 IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11,
590 IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12,
591 IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13,
586}; 592};
587 593
588struct iwl_ucode_tlv { 594struct iwl_ucode_tlv {
@@ -1317,6 +1323,9 @@ struct iwl_priv {
1317 struct iwl_notif_statistics delta_statistics; 1323 struct iwl_notif_statistics delta_statistics;
1318 struct iwl_notif_statistics max_delta; 1324 struct iwl_notif_statistics max_delta;
1319#endif 1325#endif
1326
1327 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
1328 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
1320 } _agn; 1329 } _agn;
1321#endif 1330#endif
1322 }; 1331 };