aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl4965-base.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-04-15 00:16:03 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-16 15:59:57 -0400
commit57aab75a39089744aba4bd126df2de526481b128 (patch)
tree34c7a4a3a29aea852e7886e68fc8778390f809e7 /drivers/net/wireless/iwlwifi/iwl4965-base.c
parentb454048cb933eb69dd9d46c16bf01e9df997fa3d (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.c179
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 */
5180static 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 */
5242static 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
5328static void iwl4965_nic_start(struct iwl_priv *priv) 5178static 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 */
5635static void iwl4965_alive_start(struct iwl_priv *priv) 5485static 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
5836static int __iwl4965_up(struct iwl_priv *priv) 5686static 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