aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReinette Chatre <reinette.chatre@intel.com>2009-08-07 18:41:44 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:13:48 -0400
commitc03ea16285bf142172f9816b8a1f5c43bb4b4405 (patch)
tree7499ccfbcfee182cf387629ccd31c64123dd9214
parent5225935b53ce1eafb222c644230d03ad6011d357 (diff)
iwlwifi: revert uCode Alive notification with timeout
commit "iwlwifi: uCode Alive notification with timeout" introduced a more reliable mechanism for ucode loading. Unfortunately we hit a problem with it frequently enough to make a 4965 unusable. The problem can be seen in debug log below. What this code attempts is to set runtime ucode up to load, start a timer to wait for the alive response from runtime ucode, and if it times out it tries again. As can be seen below we receive the alive response and wake the waiting task _before_ the tasks starts waiting. The task thus times out as the alive response is not received while it is waiting for it and it restarts the device. This starts the cycle all over again. [29739.000819] ieee80211 phy0: U iwl_mac_start enter [29739.005751] ieee80211 phy0: U iwl_prepare_card_hw iwl_prepare_card_hw enter [29739.012798] ieee80211 phy0: U iwl_set_hw_ready hardware ready [29739.057200] ieee80211 phy0: U iwl4965_load_bsm Begin load bsm [29739.063366] ieee80211 phy0: U iwl4965_verify_bsm Begin verify bsm [29739.072485] ieee80211 phy0: U iwl4965_verify_bsm BSM bootstrap uCode image OK [29739.079671] ieee80211 phy0: U iwl4965_load_bsm BSM write complete, poll 0 iterations [29739.257019] ieee80211 phy0: I iwl_rx_reply_alive Alive ucode status 0x00000001 revision 0x1 0x9 [29739.260964] ieee80211 phy0: I iwl_rx_reply_alive Initialization Alive received. [29739.260964] ieee80211 phy0: U __iwl_up iwlagn is coming up [29739.278571] ieee80211 phy0: U iwl_mac_start Start UP work done. [29739.284509] ieee80211 phy0: U iwlcore_verify_inst_sparse ucode inst image size is 788 [29739.292432] ieee80211 phy0: U iwlcore_verify_inst_sparse ucode inst image size is 10312 [29739.302004] ieee80211 phy0: U iwl_verify_ucode Initialize uCode is good in inst SRAM [29739.309746] ieee80211 phy0: U iwl4965_hw_get_temperature Running temperature calibration [29739.317833] ieee80211 phy0: U iwl4965_hw_get_temperature Calib values R[1-3]: -36 13522 -13496 R4: -2726 [29739.327337] ieee80211 phy0: U iwl4965_hw_get_temperature Calibrated temperature: 310K, 37C [29739.335598] ieee80211 phy0: U iwl4965_init_alive_start Initialization Alive received. [29739.343477] ieee80211 phy0: U iwl4965_set_ucode_ptrs Runtime uCode pointers are set. [29739.351283] ieee80211 phy0: I iwl_rx_reply_alive Alive ucode status 0x00000001 revision 0x1 0x0 [29739.355210] ieee80211 phy0: I iwl_rx_reply_alive Runtime Alive received. [29739.366731] iwlagn 0000:03:00.0: Runtime uCode already alive? Waiting for alive anyway [29743.284110] iwlagn 0000:03:00.0: START_ALIVE timeout after 4000ms. [29743.290337] ieee80211 phy0: U iwl_mac_add_interface enter: type 2 [29744.364089] iwlagn 0000:03:00.0: Runtime timeout after 5000ms [29744.370882] ieee80211 phy0: U iwl_alive_start Runtime Alive received. [29744.377347] ieee80211 phy0: U iwlcore_verify_inst_sparse ucode inst image size is 788 [29744.385287] ieee80211 phy0: U iwlcore_verify_inst_sparse ucode inst image size is 10312 [29744.393397] ieee80211 phy0: U iwlcore_verify_inst_sparse ucode inst image size is 94720 [29744.415835] ieee80211 phy0: U iwl_verify_ucode Runtime uCode is good in inst SRAM Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c50
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h2
5 files changed, 10 insertions, 109 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index f02023eea41c..e427a8937ed8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -146,7 +146,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
146 146
147 IWL_DEBUG_INFO(priv, "Begin load bsm\n"); 147 IWL_DEBUG_INFO(priv, "Begin load bsm\n");
148 148
149 priv->ucode_type = UCODE_INIT; 149 priv->ucode_type = UCODE_RT;
150 150
151 /* make sure bootstrap program is no larger than BSM's SRAM size */ 151 /* make sure bootstrap program is no larger than BSM's SRAM size */
152 if (len > IWL49_MAX_BSM_SIZE) 152 if (len > IWL49_MAX_BSM_SIZE)
@@ -256,8 +256,6 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
256*/ 256*/
257static void iwl4965_init_alive_start(struct iwl_priv *priv) 257static void iwl4965_init_alive_start(struct iwl_priv *priv)
258{ 258{
259 int ret;
260
261 /* Check alive response for "valid" sign from uCode */ 259 /* Check alive response for "valid" sign from uCode */
262 if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { 260 if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
263 /* We had an error bringing up the hardware, so take it 261 /* We had an error bringing up the hardware, so take it
@@ -289,28 +287,6 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv)
289 IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n"); 287 IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n");
290 goto restart; 288 goto restart;
291 } 289 }
292 priv->ucode_type = UCODE_RT;
293 if (test_bit(STATUS_RT_UCODE_ALIVE, &priv->status)) {
294 IWL_WARN(priv, "Runtime uCode already alive? "
295 "Waiting for alive anyway\n");
296 clear_bit(STATUS_RT_UCODE_ALIVE, &priv->status);
297 }
298 ret = wait_event_interruptible_timeout(
299 priv->wait_command_queue,
300 test_bit(STATUS_RT_UCODE_ALIVE, &priv->status),
301 UCODE_ALIVE_TIMEOUT);
302 if (!ret) {
303 /* FIXME: if STATUS_RT_UCODE_ALIVE timeout
304 * go back to restart the download Init uCode again
305 * this might cause to trap in the restart loop
306 */
307 priv->ucode_type = UCODE_NONE;
308 if (!test_bit(STATUS_RT_UCODE_ALIVE, &priv->status)) {
309 IWL_ERR(priv, "Runtime timeout after %dms\n",
310 jiffies_to_msecs(UCODE_ALIVE_TIMEOUT));
311 goto restart;
312 }
313 }
314 return; 290 return;
315 291
316restart: 292restart:
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index c9a1aacb2437..319df4ab7f13 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -533,16 +533,12 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
533 533
534 if (palive->ver_subtype == INITIALIZE_SUBTYPE) { 534 if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
535 IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); 535 IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
536 set_bit(STATUS_INIT_UCODE_ALIVE, &priv->status);
537 wake_up_interruptible(&priv->wait_command_queue);
538 memcpy(&priv->card_alive_init, 536 memcpy(&priv->card_alive_init,
539 &pkt->u.alive_frame, 537 &pkt->u.alive_frame,
540 sizeof(struct iwl_init_alive_resp)); 538 sizeof(struct iwl_init_alive_resp));
541 pwork = &priv->init_alive_start; 539 pwork = &priv->init_alive_start;
542 } else { 540 } else {
543 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); 541 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
544 set_bit(STATUS_RT_UCODE_ALIVE, &priv->status);
545 wake_up_interruptible(&priv->wait_command_queue);
546 memcpy(&priv->card_alive, &pkt->u.alive_frame, 542 memcpy(&priv->card_alive, &pkt->u.alive_frame,
547 sizeof(struct iwl_alive_resp)); 543 sizeof(struct iwl_alive_resp));
548 pwork = &priv->alive_start; 544 pwork = &priv->alive_start;
@@ -1784,7 +1780,6 @@ static int __iwl_up(struct iwl_priv *priv)
1784{ 1780{
1785 int i; 1781 int i;
1786 int ret; 1782 int ret;
1787 unsigned long status;
1788 1783
1789 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { 1784 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
1790 IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); 1785 IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
@@ -1862,51 +1857,6 @@ static int __iwl_up(struct iwl_priv *priv)
1862 /* start card; "initialize" will load runtime ucode */ 1857 /* start card; "initialize" will load runtime ucode */
1863 iwl_nic_start(priv); 1858 iwl_nic_start(priv);
1864 1859
1865 /* Just finish download Init or Runtime uCode image to device
1866 * now we wait here for uCode send REPLY_ALIVE notification
1867 * to indicate uCode is ready.
1868 * 1) For Init uCode image, all iwlagn devices should wait here
1869 * on STATUS_INIT_UCODE_ALIVE status bit; if timeout before
1870 * receive the REPLY_ALIVE notification, go back and try to
1871 * download the Init uCode image again.
1872 * 2) For Runtime uCode image, all iwlagn devices except 4965
1873 * wait here on STATUS_RT_UCODE_ALIVE status bit; if
1874 * timeout before receive the REPLY_ALIVE notification, go back
1875 * and download the Runtime uCode image again.
1876 * 3) For 4965 Runtime uCode, it will not go through this path,
1877 * need to wait for STATUS_RT_UCODE_ALIVE status bit in
1878 * iwl4965_init_alive_start() function; if timeout, need to
1879 * restart and download Init uCode image.
1880 */
1881 if (priv->ucode_type == UCODE_INIT)
1882 status = STATUS_INIT_UCODE_ALIVE;
1883 else
1884 status = STATUS_RT_UCODE_ALIVE;
1885 if (test_bit(status, &priv->status)) {
1886 IWL_WARN(priv,
1887 "%s uCode already alive? "
1888 "Waiting for alive anyway\n",
1889 (status == STATUS_INIT_UCODE_ALIVE)
1890 ? "INIT" : "Runtime");
1891 clear_bit(status, &priv->status);
1892 }
1893 ret = wait_event_interruptible_timeout(
1894 priv->wait_command_queue,
1895 test_bit(status, &priv->status),
1896 UCODE_ALIVE_TIMEOUT);
1897 if (!ret) {
1898 if (!test_bit(status, &priv->status)) {
1899 priv->ucode_type =
1900 (status == STATUS_INIT_UCODE_ALIVE)
1901 ? UCODE_NONE : UCODE_INIT;
1902 IWL_ERR(priv,
1903 "%s timeout after %dms\n",
1904 (status == STATUS_INIT_UCODE_ALIVE)
1905 ? "INIT" : "Runtime",
1906 jiffies_to_msecs(UCODE_ALIVE_TIMEOUT));
1907 continue;
1908 }
1909 }
1910 IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n"); 1860 IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
1911 1861
1912 return 0; 1862 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 202bc3985a46..79170a9037a1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1343,17 +1343,10 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
1343 u32 desc, time, count, base, data1; 1343 u32 desc, time, count, base, data1;
1344 u32 blink1, blink2, ilink1, ilink2; 1344 u32 blink1, blink2, ilink1, ilink2;
1345 1345
1346 switch (priv->ucode_type) { 1346 if (priv->ucode_type == UCODE_INIT)
1347 case UCODE_RT:
1348 base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
1349 break;
1350 case UCODE_INIT:
1351 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); 1347 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
1352 break; 1348 else
1353 default: 1349 base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
1354 IWL_ERR(priv, "uCode image not available\n");
1355 return;
1356 }
1357 1350
1358 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { 1351 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
1359 IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base); 1352 IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
@@ -1405,17 +1398,10 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1405 1398
1406 if (num_events == 0) 1399 if (num_events == 0)
1407 return; 1400 return;
1408 switch (priv->ucode_type) { 1401 if (priv->ucode_type == UCODE_INIT)
1409 case UCODE_RT:
1410 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1411 break;
1412 case UCODE_INIT:
1413 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 1402 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
1414 break; 1403 else
1415 default: 1404 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1416 IWL_ERR(priv, "uCode image not available\n");
1417 return;
1418 }
1419 1405
1420 if (mode == 0) 1406 if (mode == 0)
1421 event_size = 2 * sizeof(u32); 1407 event_size = 2 * sizeof(u32);
@@ -1452,17 +1438,10 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
1452 u32 next_entry; /* index of next entry to be written by uCode */ 1438 u32 next_entry; /* index of next entry to be written by uCode */
1453 u32 size; /* # entries that we'll print */ 1439 u32 size; /* # entries that we'll print */
1454 1440
1455 switch (priv->ucode_type) { 1441 if (priv->ucode_type == UCODE_INIT)
1456 case UCODE_RT:
1457 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1458 break;
1459 case UCODE_INIT:
1460 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 1442 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
1461 break; 1443 else
1462 default: 1444 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1463 IWL_ERR(priv, "uCode image not available\n");
1464 return;
1465 }
1466 1445
1467 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { 1446 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
1468 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); 1447 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index fc096b929ee3..ea8748dd675d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -547,8 +547,6 @@ void iwlcore_free_geos(struct iwl_priv *priv);
547#define STATUS_POWER_PMI 16 547#define STATUS_POWER_PMI 16
548#define STATUS_FW_ERROR 17 548#define STATUS_FW_ERROR 17
549#define STATUS_MODE_PENDING 18 549#define STATUS_MODE_PENDING 18
550#define STATUS_INIT_UCODE_ALIVE 19
551#define STATUS_RT_UCODE_ALIVE 20
552 550
553 551
554static inline int iwl_is_ready(struct iwl_priv *priv) 552static inline int iwl_is_ready(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index dcf9d5763237..61f952330a89 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -823,8 +823,6 @@ struct iwl_calib_result {
823 size_t buf_len; 823 size_t buf_len;
824}; 824};
825 825
826#define UCODE_ALIVE_TIMEOUT (5 * HZ)
827
828enum ucode_type { 826enum ucode_type {
829 UCODE_NONE = 0, 827 UCODE_NONE = 0,
830 UCODE_INIT, 828 UCODE_INIT,