diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-04-22 13:15:23 -0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-04-22 13:18:48 -0400 |
commit | ca7966c88e44233fac113579071a6f55e00ef5ac (patch) | |
tree | c80674f6237d48ea56b677bc6b409c54afeb9f08 /drivers/net/wireless/iwlwifi/iwl-agn.c | |
parent | e74fe2330a5a721610b2b69652d2ec2ebbd302e0 (diff) |
iwlagn: implement synchronous firmware load
The current firmware loading mechanism in
iwlwifi is very hard to follow, and thus
hard to maintain. To make it easier, make
the firmware loading synchronous.
For now, as a side effect, this removes a
number of retry possibilities we had. It
isn't typical for this to fail, but if it
does happen we restart from scratch which
this also makes easier to do should it be
necessary.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 190 |
1 files changed, 54 insertions, 136 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index a9204db377a8..12cd5e0352bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1181,12 +1181,6 @@ static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) | |||
1181 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); | 1181 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); |
1182 | } | 1182 | } |
1183 | 1183 | ||
1184 | static void iwl_nic_start(struct iwl_priv *priv) | ||
1185 | { | ||
1186 | /* Remove all resets to allow NIC to operate */ | ||
1187 | iwl_write32(priv, CSR_RESET, 0); | ||
1188 | } | ||
1189 | |||
1190 | struct iwlagn_ucode_capabilities { | 1184 | struct iwlagn_ucode_capabilities { |
1191 | u32 max_probe_length; | 1185 | u32 max_probe_length; |
1192 | u32 standard_phy_calibration_size; | 1186 | u32 standard_phy_calibration_size; |
@@ -1873,7 +1867,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1873 | struct iwl_error_event_table table; | 1867 | struct iwl_error_event_table table; |
1874 | 1868 | ||
1875 | base = priv->device_pointers.error_event_table; | 1869 | base = priv->device_pointers.error_event_table; |
1876 | if (priv->ucode_type == UCODE_INIT) { | 1870 | if (priv->ucode_type == UCODE_SUBTYPE_INIT) { |
1877 | if (!base) | 1871 | if (!base) |
1878 | base = priv->_agn.init_errlog_ptr; | 1872 | base = priv->_agn.init_errlog_ptr; |
1879 | } else { | 1873 | } else { |
@@ -1884,7 +1878,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1884 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | 1878 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { |
1885 | IWL_ERR(priv, | 1879 | IWL_ERR(priv, |
1886 | "Not valid error log pointer 0x%08X for %s uCode\n", | 1880 | "Not valid error log pointer 0x%08X for %s uCode\n", |
1887 | base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); | 1881 | base, |
1882 | (priv->ucode_type == UCODE_SUBTYPE_INIT) | ||
1883 | ? "Init" : "RT"); | ||
1888 | return; | 1884 | return; |
1889 | } | 1885 | } |
1890 | 1886 | ||
@@ -1944,7 +1940,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1944 | return pos; | 1940 | return pos; |
1945 | 1941 | ||
1946 | base = priv->device_pointers.log_event_table; | 1942 | base = priv->device_pointers.log_event_table; |
1947 | if (priv->ucode_type == UCODE_INIT) { | 1943 | if (priv->ucode_type == UCODE_SUBTYPE_INIT) { |
1948 | if (!base) | 1944 | if (!base) |
1949 | base = priv->_agn.init_evtlog_ptr; | 1945 | base = priv->_agn.init_evtlog_ptr; |
1950 | } else { | 1946 | } else { |
@@ -2057,7 +2053,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | |||
2057 | size_t bufsz = 0; | 2053 | size_t bufsz = 0; |
2058 | 2054 | ||
2059 | base = priv->device_pointers.log_event_table; | 2055 | base = priv->device_pointers.log_event_table; |
2060 | if (priv->ucode_type == UCODE_INIT) { | 2056 | if (priv->ucode_type == UCODE_SUBTYPE_INIT) { |
2061 | logsize = priv->_agn.init_evtlog_size; | 2057 | logsize = priv->_agn.init_evtlog_size; |
2062 | if (!base) | 2058 | if (!base) |
2063 | base = priv->_agn.init_evtlog_ptr; | 2059 | base = priv->_agn.init_evtlog_ptr; |
@@ -2070,7 +2066,9 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | |||
2070 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | 2066 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { |
2071 | IWL_ERR(priv, | 2067 | IWL_ERR(priv, |
2072 | "Invalid event log pointer 0x%08X for %s uCode\n", | 2068 | "Invalid event log pointer 0x%08X for %s uCode\n", |
2073 | base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); | 2069 | base, |
2070 | (priv->ucode_type == UCODE_SUBTYPE_INIT) | ||
2071 | ? "Init" : "RT"); | ||
2074 | return -EINVAL; | 2072 | return -EINVAL; |
2075 | } | 2073 | } |
2076 | 2074 | ||
@@ -2217,30 +2215,14 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) | |||
2217 | * from protocol/runtime uCode (initialization uCode's | 2215 | * from protocol/runtime uCode (initialization uCode's |
2218 | * Alive gets handled by iwl_init_alive_start()). | 2216 | * Alive gets handled by iwl_init_alive_start()). |
2219 | */ | 2217 | */ |
2220 | static void iwl_alive_start(struct iwl_priv *priv) | 2218 | static int iwl_alive_start(struct iwl_priv *priv) |
2221 | { | 2219 | { |
2222 | int ret = 0; | 2220 | int ret = 0; |
2223 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 2221 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
2224 | 2222 | ||
2225 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | 2223 | iwl_reset_ict(priv); |
2226 | |||
2227 | /* Initialize uCode has loaded Runtime uCode ... verify inst image. | ||
2228 | * This is a paranoid check, because we would not have gotten the | ||
2229 | * "runtime" alive if code weren't properly loaded. */ | ||
2230 | if (iwl_verify_ucode(priv, &priv->ucode_code)) { | ||
2231 | /* Runtime instruction load was bad; | ||
2232 | * take it all the way back down so we can try again */ | ||
2233 | IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n"); | ||
2234 | goto restart; | ||
2235 | } | ||
2236 | |||
2237 | ret = iwlagn_alive_notify(priv); | ||
2238 | if (ret) { | ||
2239 | IWL_WARN(priv, | ||
2240 | "Could not complete ALIVE transition [ntf]: %d\n", ret); | ||
2241 | goto restart; | ||
2242 | } | ||
2243 | 2224 | ||
2225 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | ||
2244 | 2226 | ||
2245 | /* After the ALIVE response, we can send host commands to the uCode */ | 2227 | /* After the ALIVE response, we can send host commands to the uCode */ |
2246 | set_bit(STATUS_ALIVE, &priv->status); | 2228 | set_bit(STATUS_ALIVE, &priv->status); |
@@ -2249,7 +2231,7 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2249 | iwl_setup_watchdog(priv); | 2231 | iwl_setup_watchdog(priv); |
2250 | 2232 | ||
2251 | if (iwl_is_rfkill(priv)) | 2233 | if (iwl_is_rfkill(priv)) |
2252 | return; | 2234 | return -ERFKILL; |
2253 | 2235 | ||
2254 | /* download priority table before any calibration request */ | 2236 | /* download priority table before any calibration request */ |
2255 | if (priv->cfg->bt_params && | 2237 | if (priv->cfg->bt_params && |
@@ -2263,10 +2245,14 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2263 | iwlagn_send_prio_tbl(priv); | 2245 | iwlagn_send_prio_tbl(priv); |
2264 | 2246 | ||
2265 | /* FIXME: w/a to force change uCode BT state machine */ | 2247 | /* FIXME: w/a to force change uCode BT state machine */ |
2266 | iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, | 2248 | ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, |
2267 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 2249 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
2268 | iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, | 2250 | if (ret) |
2269 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 2251 | return ret; |
2252 | ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, | ||
2253 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | ||
2254 | if (ret) | ||
2255 | return ret; | ||
2270 | } | 2256 | } |
2271 | if (priv->hw_params.calib_rt_cfg) | 2257 | if (priv->hw_params.calib_rt_cfg) |
2272 | iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg); | 2258 | iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg); |
@@ -2308,22 +2294,16 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2308 | set_bit(STATUS_READY, &priv->status); | 2294 | set_bit(STATUS_READY, &priv->status); |
2309 | 2295 | ||
2310 | /* Configure the adapter for unassociated operation */ | 2296 | /* Configure the adapter for unassociated operation */ |
2311 | iwlcore_commit_rxon(priv, ctx); | 2297 | ret = iwlcore_commit_rxon(priv, ctx); |
2298 | if (ret) | ||
2299 | return ret; | ||
2312 | 2300 | ||
2313 | /* At this point, the NIC is initialized and operational */ | 2301 | /* At this point, the NIC is initialized and operational */ |
2314 | iwl_rf_kill_ct_config(priv); | 2302 | iwl_rf_kill_ct_config(priv); |
2315 | 2303 | ||
2316 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); | 2304 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); |
2317 | wake_up_interruptible(&priv->wait_command_queue); | ||
2318 | |||
2319 | iwl_power_update_mode(priv, true); | ||
2320 | IWL_DEBUG_INFO(priv, "Updated power mode\n"); | ||
2321 | |||
2322 | 2305 | ||
2323 | return; | 2306 | return iwl_power_update_mode(priv, true); |
2324 | |||
2325 | restart: | ||
2326 | queue_work(priv->workqueue, &priv->restart); | ||
2327 | } | 2307 | } |
2328 | 2308 | ||
2329 | static void iwl_cancel_deferred_work(struct iwl_priv *priv); | 2309 | static void iwl_cancel_deferred_work(struct iwl_priv *priv); |
@@ -2446,9 +2426,10 @@ int iwl_prepare_card_hw(struct iwl_priv *priv) | |||
2446 | static int __iwl_up(struct iwl_priv *priv) | 2426 | static int __iwl_up(struct iwl_priv *priv) |
2447 | { | 2427 | { |
2448 | struct iwl_rxon_context *ctx; | 2428 | struct iwl_rxon_context *ctx; |
2449 | int i; | ||
2450 | int ret; | 2429 | int ret; |
2451 | 2430 | ||
2431 | lockdep_assert_held(&priv->mutex); | ||
2432 | |||
2452 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 2433 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
2453 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); | 2434 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); |
2454 | return -EIO; | 2435 | return -EIO; |
@@ -2462,39 +2443,34 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2462 | } | 2443 | } |
2463 | } | 2444 | } |
2464 | 2445 | ||
2465 | ret = iwlagn_start_device(priv); | 2446 | ret = iwlagn_run_init_ucode(priv); |
2466 | if (ret) | 2447 | if (ret) { |
2467 | return ret; | 2448 | IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); |
2468 | 2449 | goto error; | |
2469 | for (i = 0; i < MAX_HW_RESTARTS; i++) { | 2450 | } |
2470 | |||
2471 | /* load bootstrap state machine, | ||
2472 | * load bootstrap program into processor's memory, | ||
2473 | * prepare to load the "initialize" uCode */ | ||
2474 | ret = iwlagn_load_ucode(priv); | ||
2475 | |||
2476 | if (ret) { | ||
2477 | IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n", | ||
2478 | ret); | ||
2479 | continue; | ||
2480 | } | ||
2481 | |||
2482 | /* start card; "initialize" will load runtime ucode */ | ||
2483 | iwl_nic_start(priv); | ||
2484 | |||
2485 | IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n"); | ||
2486 | 2451 | ||
2487 | return 0; | 2452 | ret = iwlagn_load_ucode_wait_alive(priv, |
2453 | &priv->ucode_code, | ||
2454 | &priv->ucode_data, | ||
2455 | UCODE_SUBTYPE_REGULAR, | ||
2456 | UCODE_SUBTYPE_REGULAR_NEW); | ||
2457 | if (ret) { | ||
2458 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); | ||
2459 | goto error; | ||
2488 | } | 2460 | } |
2489 | 2461 | ||
2462 | ret = iwl_alive_start(priv); | ||
2463 | if (ret) | ||
2464 | goto error; | ||
2465 | return 0; | ||
2466 | |||
2467 | error: | ||
2490 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 2468 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
2491 | __iwl_down(priv); | 2469 | __iwl_down(priv); |
2492 | clear_bit(STATUS_EXIT_PENDING, &priv->status); | 2470 | clear_bit(STATUS_EXIT_PENDING, &priv->status); |
2493 | 2471 | ||
2494 | /* tried to restart and config the device for as long as our | 2472 | IWL_ERR(priv, "Unable to initialize device.\n"); |
2495 | * patience could withstand */ | 2473 | return ret; |
2496 | IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i); | ||
2497 | return -EIO; | ||
2498 | } | 2474 | } |
2499 | 2475 | ||
2500 | 2476 | ||
@@ -2504,39 +2480,6 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2504 | * | 2480 | * |
2505 | *****************************************************************************/ | 2481 | *****************************************************************************/ |
2506 | 2482 | ||
2507 | static void iwl_bg_init_alive_start(struct work_struct *data) | ||
2508 | { | ||
2509 | struct iwl_priv *priv = | ||
2510 | container_of(data, struct iwl_priv, init_alive_start.work); | ||
2511 | |||
2512 | mutex_lock(&priv->mutex); | ||
2513 | |||
2514 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
2515 | mutex_unlock(&priv->mutex); | ||
2516 | return; | ||
2517 | } | ||
2518 | |||
2519 | iwlagn_init_alive_start(priv); | ||
2520 | mutex_unlock(&priv->mutex); | ||
2521 | } | ||
2522 | |||
2523 | static void iwl_bg_alive_start(struct work_struct *data) | ||
2524 | { | ||
2525 | struct iwl_priv *priv = | ||
2526 | container_of(data, struct iwl_priv, alive_start.work); | ||
2527 | |||
2528 | mutex_lock(&priv->mutex); | ||
2529 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2530 | goto unlock; | ||
2531 | |||
2532 | /* enable dram interrupt */ | ||
2533 | iwl_reset_ict(priv); | ||
2534 | |||
2535 | iwl_alive_start(priv); | ||
2536 | unlock: | ||
2537 | mutex_unlock(&priv->mutex); | ||
2538 | } | ||
2539 | |||
2540 | static void iwl_bg_run_time_calib_work(struct work_struct *work) | 2483 | static void iwl_bg_run_time_calib_work(struct work_struct *work) |
2541 | { | 2484 | { |
2542 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 2485 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
@@ -2602,14 +2545,7 @@ static void iwl_bg_restart(struct work_struct *data) | |||
2602 | iwl_cancel_deferred_work(priv); | 2545 | iwl_cancel_deferred_work(priv); |
2603 | ieee80211_restart_hw(priv->hw); | 2546 | ieee80211_restart_hw(priv->hw); |
2604 | } else { | 2547 | } else { |
2605 | iwl_down(priv); | 2548 | WARN_ON(1); |
2606 | |||
2607 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2608 | return; | ||
2609 | |||
2610 | mutex_lock(&priv->mutex); | ||
2611 | __iwl_up(priv); | ||
2612 | mutex_unlock(&priv->mutex); | ||
2613 | } | 2549 | } |
2614 | } | 2550 | } |
2615 | 2551 | ||
@@ -2720,8 +2656,6 @@ unlock: | |||
2720 | * | 2656 | * |
2721 | *****************************************************************************/ | 2657 | *****************************************************************************/ |
2722 | 2658 | ||
2723 | #define UCODE_READY_TIMEOUT (4 * HZ) | ||
2724 | |||
2725 | /* | 2659 | /* |
2726 | * Not a mac80211 entry point function, but it fits in with all the | 2660 | * Not a mac80211 entry point function, but it fits in with all the |
2727 | * other mac80211 functions grouped here. | 2661 | * other mac80211 functions grouped here. |
@@ -2814,31 +2748,17 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw) | |||
2814 | mutex_lock(&priv->mutex); | 2748 | mutex_lock(&priv->mutex); |
2815 | ret = __iwl_up(priv); | 2749 | ret = __iwl_up(priv); |
2816 | mutex_unlock(&priv->mutex); | 2750 | mutex_unlock(&priv->mutex); |
2817 | |||
2818 | if (ret) | 2751 | if (ret) |
2819 | return ret; | 2752 | return ret; |
2820 | 2753 | ||
2821 | if (iwl_is_rfkill(priv)) | ||
2822 | goto out; | ||
2823 | |||
2824 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); | 2754 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); |
2825 | 2755 | ||
2826 | /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from | 2756 | /* Now we should be done, and the READY bit should be set. */ |
2827 | * mac80211 will not be run successfully. */ | 2757 | if (WARN_ON(!test_bit(STATUS_READY, &priv->status))) |
2828 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | 2758 | ret = -EIO; |
2829 | test_bit(STATUS_READY, &priv->status), | ||
2830 | UCODE_READY_TIMEOUT); | ||
2831 | if (!ret) { | ||
2832 | if (!test_bit(STATUS_READY, &priv->status)) { | ||
2833 | IWL_ERR(priv, "START_ALIVE timeout after %dms.\n", | ||
2834 | jiffies_to_msecs(UCODE_READY_TIMEOUT)); | ||
2835 | return -ETIMEDOUT; | ||
2836 | } | ||
2837 | } | ||
2838 | 2759 | ||
2839 | iwlagn_led_enable(priv); | 2760 | iwlagn_led_enable(priv); |
2840 | 2761 | ||
2841 | out: | ||
2842 | priv->is_open = 1; | 2762 | priv->is_open = 1; |
2843 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2763 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
2844 | return 0; | 2764 | return 0; |
@@ -3425,8 +3345,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
3425 | INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); | 3345 | INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); |
3426 | INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency); | 3346 | INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency); |
3427 | INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); | 3347 | INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); |
3428 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); | ||
3429 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); | ||
3430 | INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done); | 3348 | INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done); |
3431 | 3349 | ||
3432 | iwl_setup_scan_deferred_work(priv); | 3350 | iwl_setup_scan_deferred_work(priv); |
@@ -3455,8 +3373,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
3455 | if (priv->cfg->ops->lib->cancel_deferred_work) | 3373 | if (priv->cfg->ops->lib->cancel_deferred_work) |
3456 | priv->cfg->ops->lib->cancel_deferred_work(priv); | 3374 | priv->cfg->ops->lib->cancel_deferred_work(priv); |
3457 | 3375 | ||
3458 | cancel_delayed_work_sync(&priv->init_alive_start); | ||
3459 | cancel_delayed_work(&priv->alive_start); | ||
3460 | cancel_work_sync(&priv->run_time_calib_work); | 3376 | cancel_work_sync(&priv->run_time_calib_work); |
3461 | cancel_work_sync(&priv->beacon_update); | 3377 | cancel_work_sync(&priv->beacon_update); |
3462 | 3378 | ||
@@ -3691,6 +3607,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3691 | priv = hw->priv; | 3607 | priv = hw->priv; |
3692 | /* At this point both hw and priv are allocated. */ | 3608 | /* At this point both hw and priv are allocated. */ |
3693 | 3609 | ||
3610 | priv->ucode_type = UCODE_SUBTYPE_NONE_LOADED; | ||
3611 | |||
3694 | /* | 3612 | /* |
3695 | * The default context is always valid, | 3613 | * The default context is always valid, |
3696 | * more may be discovered when firmware | 3614 | * more may be discovered when firmware |