diff options
author | Kolekar, Abhijeet <abhijeet.kolekar@intel.com> | 2008-12-18 21:37:37 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-01-29 15:59:19 -0500 |
commit | 0164b9b45dbee4a3c4c95f59f9dd538b1e9c2635 (patch) | |
tree | f7557888904652b8a54a85bbf626a285df9b2c88 /drivers/net/wireless/iwlwifi/iwl-3945.c | |
parent | 775a6e27bfca9d19f3ea6006a7e60a4a54aaf69c (diff) |
iwl3945: add load ucode op
The patch adds 3945 iwl_lib_ops->load_ucode to the driver.
Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index d5509d589382..1071dac99c53 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -2506,12 +2506,170 @@ void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv) | |||
2506 | cancel_delayed_work(&priv->thermal_periodic); | 2506 | cancel_delayed_work(&priv->thermal_periodic); |
2507 | } | 2507 | } |
2508 | 2508 | ||
2509 | /* check contents of special bootstrap uCode SRAM */ | ||
2510 | static int iwl3945_verify_bsm(struct iwl_priv *priv) | ||
2511 | { | ||
2512 | __le32 *image = priv->ucode_boot.v_addr; | ||
2513 | u32 len = priv->ucode_boot.len; | ||
2514 | u32 reg; | ||
2515 | u32 val; | ||
2516 | |||
2517 | IWL_DEBUG_INFO("Begin verify bsm\n"); | ||
2518 | |||
2519 | /* verify BSM SRAM contents */ | ||
2520 | val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); | ||
2521 | for (reg = BSM_SRAM_LOWER_BOUND; | ||
2522 | reg < BSM_SRAM_LOWER_BOUND + len; | ||
2523 | reg += sizeof(u32), image++) { | ||
2524 | val = iwl_read_prph(priv, reg); | ||
2525 | if (val != le32_to_cpu(*image)) { | ||
2526 | IWL_ERR(priv, "BSM uCode verification failed at " | ||
2527 | "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", | ||
2528 | BSM_SRAM_LOWER_BOUND, | ||
2529 | reg - BSM_SRAM_LOWER_BOUND, len, | ||
2530 | val, le32_to_cpu(*image)); | ||
2531 | return -EIO; | ||
2532 | } | ||
2533 | } | ||
2534 | |||
2535 | IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n"); | ||
2536 | |||
2537 | return 0; | ||
2538 | } | ||
2539 | |||
2540 | /** | ||
2541 | * iwl3945_load_bsm - Load bootstrap instructions | ||
2542 | * | ||
2543 | * BSM operation: | ||
2544 | * | ||
2545 | * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program | ||
2546 | * in special SRAM that does not power down during RFKILL. When powering back | ||
2547 | * up after power-saving sleeps (or during initial uCode load), the BSM loads | ||
2548 | * the bootstrap program into the on-board processor, and starts it. | ||
2549 | * | ||
2550 | * The bootstrap program loads (via DMA) instructions and data for a new | ||
2551 | * program from host DRAM locations indicated by the host driver in the | ||
2552 | * BSM_DRAM_* registers. Once the new program is loaded, it starts | ||
2553 | * automatically. | ||
2554 | * | ||
2555 | * When initializing the NIC, the host driver points the BSM to the | ||
2556 | * "initialize" uCode image. This uCode sets up some internal data, then | ||
2557 | * notifies host via "initialize alive" that it is complete. | ||
2558 | * | ||
2559 | * The host then replaces the BSM_DRAM_* pointer values to point to the | ||
2560 | * normal runtime uCode instructions and a backup uCode data cache buffer | ||
2561 | * (filled initially with starting data values for the on-board processor), | ||
2562 | * then triggers the "initialize" uCode to load and launch the runtime uCode, | ||
2563 | * which begins normal operation. | ||
2564 | * | ||
2565 | * When doing a power-save shutdown, runtime uCode saves data SRAM into | ||
2566 | * the backup data cache in DRAM before SRAM is powered down. | ||
2567 | * | ||
2568 | * When powering back up, the BSM loads the bootstrap program. This reloads | ||
2569 | * the runtime uCode instructions and the backup data cache into SRAM, | ||
2570 | * and re-launches the runtime uCode from where it left off. | ||
2571 | */ | ||
2572 | static int iwl3945_load_bsm(struct iwl_priv *priv) | ||
2573 | { | ||
2574 | __le32 *image = priv->ucode_boot.v_addr; | ||
2575 | u32 len = priv->ucode_boot.len; | ||
2576 | dma_addr_t pinst; | ||
2577 | dma_addr_t pdata; | ||
2578 | u32 inst_len; | ||
2579 | u32 data_len; | ||
2580 | int rc; | ||
2581 | int i; | ||
2582 | u32 done; | ||
2583 | u32 reg_offset; | ||
2584 | |||
2585 | IWL_DEBUG_INFO("Begin load bsm\n"); | ||
2586 | |||
2587 | /* make sure bootstrap program is no larger than BSM's SRAM size */ | ||
2588 | if (len > IWL39_MAX_BSM_SIZE) | ||
2589 | return -EINVAL; | ||
2590 | |||
2591 | /* Tell bootstrap uCode where to find the "Initialize" uCode | ||
2592 | * in host DRAM ... host DRAM physical address bits 31:0 for 3945. | ||
2593 | * NOTE: iwl3945_initialize_alive_start() will replace these values, | ||
2594 | * after the "initialize" uCode has run, to point to | ||
2595 | * runtime/protocol instructions and backup data cache. */ | ||
2596 | pinst = priv->ucode_init.p_addr; | ||
2597 | pdata = priv->ucode_init_data.p_addr; | ||
2598 | inst_len = priv->ucode_init.len; | ||
2599 | data_len = priv->ucode_init_data.len; | ||
2600 | |||
2601 | rc = iwl_grab_nic_access(priv); | ||
2602 | if (rc) | ||
2603 | return rc; | ||
2604 | |||
2605 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | ||
2606 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | ||
2607 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); | ||
2608 | iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); | ||
2609 | |||
2610 | /* Fill BSM memory with bootstrap instructions */ | ||
2611 | for (reg_offset = BSM_SRAM_LOWER_BOUND; | ||
2612 | reg_offset < BSM_SRAM_LOWER_BOUND + len; | ||
2613 | reg_offset += sizeof(u32), image++) | ||
2614 | _iwl_write_prph(priv, reg_offset, | ||
2615 | le32_to_cpu(*image)); | ||
2616 | |||
2617 | rc = iwl3945_verify_bsm(priv); | ||
2618 | if (rc) { | ||
2619 | iwl_release_nic_access(priv); | ||
2620 | return rc; | ||
2621 | } | ||
2622 | |||
2623 | /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ | ||
2624 | iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); | ||
2625 | iwl_write_prph(priv, BSM_WR_MEM_DST_REG, | ||
2626 | IWL39_RTC_INST_LOWER_BOUND); | ||
2627 | iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); | ||
2628 | |||
2629 | /* Load bootstrap code into instruction SRAM now, | ||
2630 | * to prepare to load "initialize" uCode */ | ||
2631 | iwl_write_prph(priv, BSM_WR_CTRL_REG, | ||
2632 | BSM_WR_CTRL_REG_BIT_START); | ||
2633 | |||
2634 | /* Wait for load of bootstrap uCode to finish */ | ||
2635 | for (i = 0; i < 100; i++) { | ||
2636 | done = iwl_read_prph(priv, BSM_WR_CTRL_REG); | ||
2637 | if (!(done & BSM_WR_CTRL_REG_BIT_START)) | ||
2638 | break; | ||
2639 | udelay(10); | ||
2640 | } | ||
2641 | if (i < 100) | ||
2642 | IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i); | ||
2643 | else { | ||
2644 | IWL_ERR(priv, "BSM write did not complete!\n"); | ||
2645 | return -EIO; | ||
2646 | } | ||
2647 | |||
2648 | /* Enable future boot loads whenever power management unit triggers it | ||
2649 | * (e.g. when powering back up after power-save shutdown) */ | ||
2650 | iwl_write_prph(priv, BSM_WR_CTRL_REG, | ||
2651 | BSM_WR_CTRL_REG_BIT_START_EN); | ||
2652 | |||
2653 | iwl_release_nic_access(priv); | ||
2654 | |||
2655 | return 0; | ||
2656 | } | ||
2657 | |||
2658 | static struct iwl_lib_ops iwl3945_lib = { | ||
2659 | .load_ucode = iwl3945_load_bsm, | ||
2660 | }; | ||
2661 | |||
2662 | static struct iwl_ops iwl3945_ops = { | ||
2663 | .lib = &iwl3945_lib, | ||
2664 | }; | ||
2665 | |||
2509 | static struct iwl_cfg iwl3945_bg_cfg = { | 2666 | static struct iwl_cfg iwl3945_bg_cfg = { |
2510 | .name = "3945BG", | 2667 | .name = "3945BG", |
2511 | .fw_name_pre = IWL3945_FW_PRE, | 2668 | .fw_name_pre = IWL3945_FW_PRE, |
2512 | .ucode_api_max = IWL3945_UCODE_API_MAX, | 2669 | .ucode_api_max = IWL3945_UCODE_API_MAX, |
2513 | .ucode_api_min = IWL3945_UCODE_API_MIN, | 2670 | .ucode_api_min = IWL3945_UCODE_API_MIN, |
2514 | .sku = IWL_SKU_G, | 2671 | .sku = IWL_SKU_G, |
2672 | .ops = &iwl3945_ops, | ||
2515 | .mod_params = &iwl3945_mod_params | 2673 | .mod_params = &iwl3945_mod_params |
2516 | }; | 2674 | }; |
2517 | 2675 | ||
@@ -2521,6 +2679,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { | |||
2521 | .ucode_api_max = IWL3945_UCODE_API_MAX, | 2679 | .ucode_api_max = IWL3945_UCODE_API_MAX, |
2522 | .ucode_api_min = IWL3945_UCODE_API_MIN, | 2680 | .ucode_api_min = IWL3945_UCODE_API_MIN, |
2523 | .sku = IWL_SKU_A|IWL_SKU_G, | 2681 | .sku = IWL_SKU_A|IWL_SKU_G, |
2682 | .ops = &iwl3945_ops, | ||
2524 | .mod_params = &iwl3945_mod_params | 2683 | .mod_params = &iwl3945_mod_params |
2525 | }; | 2684 | }; |
2526 | 2685 | ||