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 | |
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>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 159 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 152 |
2 files changed, 160 insertions, 151 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 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 52c03cf29089..6669ab0d3f52 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -4924,156 +4924,6 @@ static int iwl3945_verify_ucode(struct iwl_priv *priv) | |||
4924 | return rc; | 4924 | return rc; |
4925 | } | 4925 | } |
4926 | 4926 | ||
4927 | |||
4928 | /* check contents of special bootstrap uCode SRAM */ | ||
4929 | static int iwl3945_verify_bsm(struct iwl_priv *priv) | ||
4930 | { | ||
4931 | __le32 *image = priv->ucode_boot.v_addr; | ||
4932 | u32 len = priv->ucode_boot.len; | ||
4933 | u32 reg; | ||
4934 | u32 val; | ||
4935 | |||
4936 | IWL_DEBUG_INFO("Begin verify bsm\n"); | ||
4937 | |||
4938 | /* verify BSM SRAM contents */ | ||
4939 | val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); | ||
4940 | for (reg = BSM_SRAM_LOWER_BOUND; | ||
4941 | reg < BSM_SRAM_LOWER_BOUND + len; | ||
4942 | reg += sizeof(u32), image++) { | ||
4943 | val = iwl_read_prph(priv, reg); | ||
4944 | if (val != le32_to_cpu(*image)) { | ||
4945 | IWL_ERR(priv, "BSM uCode verification failed at " | ||
4946 | "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", | ||
4947 | BSM_SRAM_LOWER_BOUND, | ||
4948 | reg - BSM_SRAM_LOWER_BOUND, len, | ||
4949 | val, le32_to_cpu(*image)); | ||
4950 | return -EIO; | ||
4951 | } | ||
4952 | } | ||
4953 | |||
4954 | IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n"); | ||
4955 | |||
4956 | return 0; | ||
4957 | } | ||
4958 | |||
4959 | /** | ||
4960 | * iwl3945_load_bsm - Load bootstrap instructions | ||
4961 | * | ||
4962 | * BSM operation: | ||
4963 | * | ||
4964 | * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program | ||
4965 | * in special SRAM that does not power down during RFKILL. When powering back | ||
4966 | * up after power-saving sleeps (or during initial uCode load), the BSM loads | ||
4967 | * the bootstrap program into the on-board processor, and starts it. | ||
4968 | * | ||
4969 | * The bootstrap program loads (via DMA) instructions and data for a new | ||
4970 | * program from host DRAM locations indicated by the host driver in the | ||
4971 | * BSM_DRAM_* registers. Once the new program is loaded, it starts | ||
4972 | * automatically. | ||
4973 | * | ||
4974 | * When initializing the NIC, the host driver points the BSM to the | ||
4975 | * "initialize" uCode image. This uCode sets up some internal data, then | ||
4976 | * notifies host via "initialize alive" that it is complete. | ||
4977 | * | ||
4978 | * The host then replaces the BSM_DRAM_* pointer values to point to the | ||
4979 | * normal runtime uCode instructions and a backup uCode data cache buffer | ||
4980 | * (filled initially with starting data values for the on-board processor), | ||
4981 | * then triggers the "initialize" uCode to load and launch the runtime uCode, | ||
4982 | * which begins normal operation. | ||
4983 | * | ||
4984 | * When doing a power-save shutdown, runtime uCode saves data SRAM into | ||
4985 | * the backup data cache in DRAM before SRAM is powered down. | ||
4986 | * | ||
4987 | * When powering back up, the BSM loads the bootstrap program. This reloads | ||
4988 | * the runtime uCode instructions and the backup data cache into SRAM, | ||
4989 | * and re-launches the runtime uCode from where it left off. | ||
4990 | */ | ||
4991 | static int iwl3945_load_bsm(struct iwl_priv *priv) | ||
4992 | { | ||
4993 | __le32 *image = priv->ucode_boot.v_addr; | ||
4994 | u32 len = priv->ucode_boot.len; | ||
4995 | dma_addr_t pinst; | ||
4996 | dma_addr_t pdata; | ||
4997 | u32 inst_len; | ||
4998 | u32 data_len; | ||
4999 | int rc; | ||
5000 | int i; | ||
5001 | u32 done; | ||
5002 | u32 reg_offset; | ||
5003 | |||
5004 | IWL_DEBUG_INFO("Begin load bsm\n"); | ||
5005 | |||
5006 | /* make sure bootstrap program is no larger than BSM's SRAM size */ | ||
5007 | if (len > IWL39_MAX_BSM_SIZE) | ||
5008 | return -EINVAL; | ||
5009 | |||
5010 | /* Tell bootstrap uCode where to find the "Initialize" uCode | ||
5011 | * in host DRAM ... host DRAM physical address bits 31:0 for 3945. | ||
5012 | * NOTE: iwl3945_initialize_alive_start() will replace these values, | ||
5013 | * after the "initialize" uCode has run, to point to | ||
5014 | * runtime/protocol instructions and backup data cache. */ | ||
5015 | pinst = priv->ucode_init.p_addr; | ||
5016 | pdata = priv->ucode_init_data.p_addr; | ||
5017 | inst_len = priv->ucode_init.len; | ||
5018 | data_len = priv->ucode_init_data.len; | ||
5019 | |||
5020 | rc = iwl_grab_nic_access(priv); | ||
5021 | if (rc) | ||
5022 | return rc; | ||
5023 | |||
5024 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | ||
5025 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | ||
5026 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); | ||
5027 | iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); | ||
5028 | |||
5029 | /* Fill BSM memory with bootstrap instructions */ | ||
5030 | for (reg_offset = BSM_SRAM_LOWER_BOUND; | ||
5031 | reg_offset < BSM_SRAM_LOWER_BOUND + len; | ||
5032 | reg_offset += sizeof(u32), image++) | ||
5033 | _iwl_write_prph(priv, reg_offset, | ||
5034 | le32_to_cpu(*image)); | ||
5035 | |||
5036 | rc = iwl3945_verify_bsm(priv); | ||
5037 | if (rc) { | ||
5038 | iwl_release_nic_access(priv); | ||
5039 | return rc; | ||
5040 | } | ||
5041 | |||
5042 | /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ | ||
5043 | iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); | ||
5044 | iwl_write_prph(priv, BSM_WR_MEM_DST_REG, | ||
5045 | IWL39_RTC_INST_LOWER_BOUND); | ||
5046 | iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); | ||
5047 | |||
5048 | /* Load bootstrap code into instruction SRAM now, | ||
5049 | * to prepare to load "initialize" uCode */ | ||
5050 | iwl_write_prph(priv, BSM_WR_CTRL_REG, | ||
5051 | BSM_WR_CTRL_REG_BIT_START); | ||
5052 | |||
5053 | /* Wait for load of bootstrap uCode to finish */ | ||
5054 | for (i = 0; i < 100; i++) { | ||
5055 | done = iwl_read_prph(priv, BSM_WR_CTRL_REG); | ||
5056 | if (!(done & BSM_WR_CTRL_REG_BIT_START)) | ||
5057 | break; | ||
5058 | udelay(10); | ||
5059 | } | ||
5060 | if (i < 100) | ||
5061 | IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i); | ||
5062 | else { | ||
5063 | IWL_ERR(priv, "BSM write did not complete!\n"); | ||
5064 | return -EIO; | ||
5065 | } | ||
5066 | |||
5067 | /* Enable future boot loads whenever power management unit triggers it | ||
5068 | * (e.g. when powering back up after power-save shutdown) */ | ||
5069 | iwl_write_prph(priv, BSM_WR_CTRL_REG, | ||
5070 | BSM_WR_CTRL_REG_BIT_START_EN); | ||
5071 | |||
5072 | iwl_release_nic_access(priv); | ||
5073 | |||
5074 | return 0; | ||
5075 | } | ||
5076 | |||
5077 | static void iwl3945_nic_start(struct iwl_priv *priv) | 4927 | static void iwl3945_nic_start(struct iwl_priv *priv) |
5078 | { | 4928 | { |
5079 | /* Remove all resets to allow NIC to operate */ | 4929 | /* Remove all resets to allow NIC to operate */ |
@@ -5714,7 +5564,7 @@ static int __iwl3945_up(struct iwl_priv *priv) | |||
5714 | /* load bootstrap state machine, | 5564 | /* load bootstrap state machine, |
5715 | * load bootstrap program into processor's memory, | 5565 | * load bootstrap program into processor's memory, |
5716 | * prepare to load the "initialize" uCode */ | 5566 | * prepare to load the "initialize" uCode */ |
5717 | rc = iwl3945_load_bsm(priv); | 5567 | priv->cfg->ops->lib->load_ucode(priv); |
5718 | 5568 | ||
5719 | if (rc) { | 5569 | if (rc) { |
5720 | IWL_ERR(priv, | 5570 | IWL_ERR(priv, |