aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-3945.c
diff options
context:
space:
mode:
authorKolekar, Abhijeet <abhijeet.kolekar@intel.com>2008-12-18 21:37:37 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-29 15:59:19 -0500
commit0164b9b45dbee4a3c4c95f59f9dd538b1e9c2635 (patch)
treef7557888904652b8a54a85bbf626a285df9b2c88 /drivers/net/wireless/iwlwifi/iwl-3945.c
parent775a6e27bfca9d19f3ea6006a7e60a4a54aaf69c (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.c159
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 */
2510static 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 */
2572static 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
2658static struct iwl_lib_ops iwl3945_lib = {
2659 .load_ucode = iwl3945_load_bsm,
2660};
2661
2662static struct iwl_ops iwl3945_ops = {
2663 .lib = &iwl3945_lib,
2664};
2665
2509static struct iwl_cfg iwl3945_bg_cfg = { 2666static 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