diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2008-04-15 00:16:03 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-04-16 15:59:57 -0400 |
commit | 57aab75a39089744aba4bd126df2de526481b128 (patch) | |
tree | 34c7a4a3a29aea852e7886e68fc8778390f809e7 /drivers/net/wireless/iwlwifi/iwl4965-base.c | |
parent | b454048cb933eb69dd9d46c16bf01e9df997fa3d (diff) |
iwlwifi: generalize iwlwifi init flow
This patch creates handlers to support
iwlwifi init flow for multiple HWs
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 179 |
1 files changed, 15 insertions, 164 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 06e44dad5f02..ecc9cba62bf9 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -4305,7 +4305,7 @@ static void iwl4965_dump_nic_error_log(struct iwl_priv *priv) | |||
4305 | 4305 | ||
4306 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); | 4306 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); |
4307 | 4307 | ||
4308 | if (!iwl4965_hw_valid_rtc_data_addr(base)) { | 4308 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { |
4309 | IWL_ERROR("Not valid error log pointer 0x%08X\n", base); | 4309 | IWL_ERROR("Not valid error log pointer 0x%08X\n", base); |
4310 | return; | 4310 | return; |
4311 | } | 4311 | } |
@@ -4400,7 +4400,7 @@ static void iwl4965_dump_nic_event_log(struct iwl_priv *priv) | |||
4400 | u32 size; /* # entries that we'll print */ | 4400 | u32 size; /* # entries that we'll print */ |
4401 | 4401 | ||
4402 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | 4402 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); |
4403 | if (!iwl4965_hw_valid_rtc_data_addr(base)) { | 4403 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { |
4404 | IWL_ERROR("Invalid event log pointer 0x%08X\n", base); | 4404 | IWL_ERROR("Invalid event log pointer 0x%08X\n", base); |
4405 | return; | 4405 | return; |
4406 | } | 4406 | } |
@@ -5175,156 +5175,6 @@ static int iwl4965_verify_ucode(struct iwl_priv *priv) | |||
5175 | return rc; | 5175 | return rc; |
5176 | } | 5176 | } |
5177 | 5177 | ||
5178 | |||
5179 | /* check contents of special bootstrap uCode SRAM */ | ||
5180 | static int iwl4965_verify_bsm(struct iwl_priv *priv) | ||
5181 | { | ||
5182 | __le32 *image = priv->ucode_boot.v_addr; | ||
5183 | u32 len = priv->ucode_boot.len; | ||
5184 | u32 reg; | ||
5185 | u32 val; | ||
5186 | |||
5187 | IWL_DEBUG_INFO("Begin verify bsm\n"); | ||
5188 | |||
5189 | /* verify BSM SRAM contents */ | ||
5190 | val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); | ||
5191 | for (reg = BSM_SRAM_LOWER_BOUND; | ||
5192 | reg < BSM_SRAM_LOWER_BOUND + len; | ||
5193 | reg += sizeof(u32), image ++) { | ||
5194 | val = iwl_read_prph(priv, reg); | ||
5195 | if (val != le32_to_cpu(*image)) { | ||
5196 | IWL_ERROR("BSM uCode verification failed at " | ||
5197 | "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", | ||
5198 | BSM_SRAM_LOWER_BOUND, | ||
5199 | reg - BSM_SRAM_LOWER_BOUND, len, | ||
5200 | val, le32_to_cpu(*image)); | ||
5201 | return -EIO; | ||
5202 | } | ||
5203 | } | ||
5204 | |||
5205 | IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n"); | ||
5206 | |||
5207 | return 0; | ||
5208 | } | ||
5209 | |||
5210 | /** | ||
5211 | * iwl4965_load_bsm - Load bootstrap instructions | ||
5212 | * | ||
5213 | * BSM operation: | ||
5214 | * | ||
5215 | * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program | ||
5216 | * in special SRAM that does not power down during RFKILL. When powering back | ||
5217 | * up after power-saving sleeps (or during initial uCode load), the BSM loads | ||
5218 | * the bootstrap program into the on-board processor, and starts it. | ||
5219 | * | ||
5220 | * The bootstrap program loads (via DMA) instructions and data for a new | ||
5221 | * program from host DRAM locations indicated by the host driver in the | ||
5222 | * BSM_DRAM_* registers. Once the new program is loaded, it starts | ||
5223 | * automatically. | ||
5224 | * | ||
5225 | * When initializing the NIC, the host driver points the BSM to the | ||
5226 | * "initialize" uCode image. This uCode sets up some internal data, then | ||
5227 | * notifies host via "initialize alive" that it is complete. | ||
5228 | * | ||
5229 | * The host then replaces the BSM_DRAM_* pointer values to point to the | ||
5230 | * normal runtime uCode instructions and a backup uCode data cache buffer | ||
5231 | * (filled initially with starting data values for the on-board processor), | ||
5232 | * then triggers the "initialize" uCode to load and launch the runtime uCode, | ||
5233 | * which begins normal operation. | ||
5234 | * | ||
5235 | * When doing a power-save shutdown, runtime uCode saves data SRAM into | ||
5236 | * the backup data cache in DRAM before SRAM is powered down. | ||
5237 | * | ||
5238 | * When powering back up, the BSM loads the bootstrap program. This reloads | ||
5239 | * the runtime uCode instructions and the backup data cache into SRAM, | ||
5240 | * and re-launches the runtime uCode from where it left off. | ||
5241 | */ | ||
5242 | static int iwl4965_load_bsm(struct iwl_priv *priv) | ||
5243 | { | ||
5244 | __le32 *image = priv->ucode_boot.v_addr; | ||
5245 | u32 len = priv->ucode_boot.len; | ||
5246 | dma_addr_t pinst; | ||
5247 | dma_addr_t pdata; | ||
5248 | u32 inst_len; | ||
5249 | u32 data_len; | ||
5250 | int rc; | ||
5251 | int i; | ||
5252 | u32 done; | ||
5253 | u32 reg_offset; | ||
5254 | |||
5255 | IWL_DEBUG_INFO("Begin load bsm\n"); | ||
5256 | |||
5257 | /* make sure bootstrap program is no larger than BSM's SRAM size */ | ||
5258 | if (len > IWL_MAX_BSM_SIZE) | ||
5259 | return -EINVAL; | ||
5260 | |||
5261 | /* Tell bootstrap uCode where to find the "Initialize" uCode | ||
5262 | * in host DRAM ... host DRAM physical address bits 35:4 for 4965. | ||
5263 | * NOTE: iwl4965_initialize_alive_start() will replace these values, | ||
5264 | * after the "initialize" uCode has run, to point to | ||
5265 | * runtime/protocol instructions and backup data cache. */ | ||
5266 | pinst = priv->ucode_init.p_addr >> 4; | ||
5267 | pdata = priv->ucode_init_data.p_addr >> 4; | ||
5268 | inst_len = priv->ucode_init.len; | ||
5269 | data_len = priv->ucode_init_data.len; | ||
5270 | |||
5271 | rc = iwl_grab_nic_access(priv); | ||
5272 | if (rc) | ||
5273 | return rc; | ||
5274 | |||
5275 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | ||
5276 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | ||
5277 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); | ||
5278 | iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); | ||
5279 | |||
5280 | /* Fill BSM memory with bootstrap instructions */ | ||
5281 | for (reg_offset = BSM_SRAM_LOWER_BOUND; | ||
5282 | reg_offset < BSM_SRAM_LOWER_BOUND + len; | ||
5283 | reg_offset += sizeof(u32), image++) | ||
5284 | _iwl_write_prph(priv, reg_offset, | ||
5285 | le32_to_cpu(*image)); | ||
5286 | |||
5287 | rc = iwl4965_verify_bsm(priv); | ||
5288 | if (rc) { | ||
5289 | iwl_release_nic_access(priv); | ||
5290 | return rc; | ||
5291 | } | ||
5292 | |||
5293 | /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ | ||
5294 | iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); | ||
5295 | iwl_write_prph(priv, BSM_WR_MEM_DST_REG, | ||
5296 | RTC_INST_LOWER_BOUND); | ||
5297 | iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); | ||
5298 | |||
5299 | /* Load bootstrap code into instruction SRAM now, | ||
5300 | * to prepare to load "initialize" uCode */ | ||
5301 | iwl_write_prph(priv, BSM_WR_CTRL_REG, | ||
5302 | BSM_WR_CTRL_REG_BIT_START); | ||
5303 | |||
5304 | /* Wait for load of bootstrap uCode to finish */ | ||
5305 | for (i = 0; i < 100; i++) { | ||
5306 | done = iwl_read_prph(priv, BSM_WR_CTRL_REG); | ||
5307 | if (!(done & BSM_WR_CTRL_REG_BIT_START)) | ||
5308 | break; | ||
5309 | udelay(10); | ||
5310 | } | ||
5311 | if (i < 100) | ||
5312 | IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i); | ||
5313 | else { | ||
5314 | IWL_ERROR("BSM write did not complete!\n"); | ||
5315 | return -EIO; | ||
5316 | } | ||
5317 | |||
5318 | /* Enable future boot loads whenever power management unit triggers it | ||
5319 | * (e.g. when powering back up after power-save shutdown) */ | ||
5320 | iwl_write_prph(priv, BSM_WR_CTRL_REG, | ||
5321 | BSM_WR_CTRL_REG_BIT_START_EN); | ||
5322 | |||
5323 | iwl_release_nic_access(priv); | ||
5324 | |||
5325 | return 0; | ||
5326 | } | ||
5327 | |||
5328 | static void iwl4965_nic_start(struct iwl_priv *priv) | 5178 | static void iwl4965_nic_start(struct iwl_priv *priv) |
5329 | { | 5179 | { |
5330 | /* Remove all resets to allow NIC to operate */ | 5180 | /* Remove all resets to allow NIC to operate */ |
@@ -5634,7 +5484,7 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv) | |||
5634 | */ | 5484 | */ |
5635 | static void iwl4965_alive_start(struct iwl_priv *priv) | 5485 | static void iwl4965_alive_start(struct iwl_priv *priv) |
5636 | { | 5486 | { |
5637 | int rc = 0; | 5487 | int ret = 0; |
5638 | 5488 | ||
5639 | IWL_DEBUG_INFO("Runtime Alive received.\n"); | 5489 | IWL_DEBUG_INFO("Runtime Alive received.\n"); |
5640 | 5490 | ||
@@ -5657,10 +5507,10 @@ static void iwl4965_alive_start(struct iwl_priv *priv) | |||
5657 | 5507 | ||
5658 | iwlcore_clear_stations_table(priv); | 5508 | iwlcore_clear_stations_table(priv); |
5659 | 5509 | ||
5660 | rc = iwl4965_alive_notify(priv); | 5510 | ret = priv->cfg->ops->lib->alive_notify(priv); |
5661 | if (rc) { | 5511 | if (ret) { |
5662 | IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n", | 5512 | IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n", |
5663 | rc); | 5513 | ret); |
5664 | goto restart; | 5514 | goto restart; |
5665 | } | 5515 | } |
5666 | 5516 | ||
@@ -5835,7 +5685,8 @@ static void iwl4965_down(struct iwl_priv *priv) | |||
5835 | 5685 | ||
5836 | static int __iwl4965_up(struct iwl_priv *priv) | 5686 | static int __iwl4965_up(struct iwl_priv *priv) |
5837 | { | 5687 | { |
5838 | int rc, i; | 5688 | int i; |
5689 | int ret; | ||
5839 | 5690 | ||
5840 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 5691 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
5841 | IWL_WARNING("Exit pending; will not bring the NIC up\n"); | 5692 | IWL_WARNING("Exit pending; will not bring the NIC up\n"); |
@@ -5870,10 +5721,10 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
5870 | iwl_rfkill_set_hw_state(priv); | 5721 | iwl_rfkill_set_hw_state(priv); |
5871 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | 5722 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); |
5872 | 5723 | ||
5873 | rc = iwl4965_hw_nic_init(priv); | 5724 | ret = priv->cfg->ops->lib->hw_nic_init(priv); |
5874 | if (rc) { | 5725 | if (ret) { |
5875 | IWL_ERROR("Unable to int nic\n"); | 5726 | IWL_ERROR("Unable to init nic\n"); |
5876 | return rc; | 5727 | return ret; |
5877 | } | 5728 | } |
5878 | 5729 | ||
5879 | /* make sure rfkill handshake bits are cleared */ | 5730 | /* make sure rfkill handshake bits are cleared */ |
@@ -5906,10 +5757,10 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
5906 | /* load bootstrap state machine, | 5757 | /* load bootstrap state machine, |
5907 | * load bootstrap program into processor's memory, | 5758 | * load bootstrap program into processor's memory, |
5908 | * prepare to load the "initialize" uCode */ | 5759 | * prepare to load the "initialize" uCode */ |
5909 | rc = iwl4965_load_bsm(priv); | 5760 | ret = priv->cfg->ops->lib->load_ucode(priv); |
5910 | 5761 | ||
5911 | if (rc) { | 5762 | if (ret) { |
5912 | IWL_ERROR("Unable to set up bootstrap uCode: %d\n", rc); | 5763 | IWL_ERROR("Unable to set up bootstrap uCode: %d\n", ret); |
5913 | continue; | 5764 | continue; |
5914 | } | 5765 | } |
5915 | 5766 | ||