diff options
-rw-r--r-- | drivers/net/wireless/ipw2200.c | 114 |
1 files changed, 63 insertions, 51 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 624f29500490..c42eb54f379a 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -2772,22 +2772,25 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, | |||
2772 | 2772 | ||
2773 | static int ipw_fw_dma_wait(struct ipw_priv *priv) | 2773 | static int ipw_fw_dma_wait(struct ipw_priv *priv) |
2774 | { | 2774 | { |
2775 | u32 current_index = 0; | 2775 | u32 current_index = 0, previous_index; |
2776 | u32 watchdog = 0; | 2776 | u32 watchdog = 0; |
2777 | 2777 | ||
2778 | IPW_DEBUG_FW(">> : \n"); | 2778 | IPW_DEBUG_FW(">> : \n"); |
2779 | 2779 | ||
2780 | current_index = ipw_fw_dma_command_block_index(priv); | 2780 | current_index = ipw_fw_dma_command_block_index(priv); |
2781 | IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n", | 2781 | IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n", |
2782 | (int)priv->sram_desc.last_cb_index); | 2782 | (int)priv->sram_desc.last_cb_index); |
2783 | 2783 | ||
2784 | while (current_index < priv->sram_desc.last_cb_index) { | 2784 | while (current_index < priv->sram_desc.last_cb_index) { |
2785 | udelay(50); | 2785 | udelay(50); |
2786 | previous_index = current_index; | ||
2786 | current_index = ipw_fw_dma_command_block_index(priv); | 2787 | current_index = ipw_fw_dma_command_block_index(priv); |
2787 | 2788 | ||
2788 | watchdog++; | 2789 | if (previous_index < current_index) { |
2789 | 2790 | watchdog = 0; | |
2790 | if (watchdog > 400) { | 2791 | continue; |
2792 | } | ||
2793 | if (++watchdog > 400) { | ||
2791 | IPW_DEBUG_FW_INFO("Timeout\n"); | 2794 | IPW_DEBUG_FW_INFO("Timeout\n"); |
2792 | ipw_fw_dma_dump_command_block(priv); | 2795 | ipw_fw_dma_dump_command_block(priv); |
2793 | ipw_fw_dma_abort(priv); | 2796 | ipw_fw_dma_abort(priv); |
@@ -3276,55 +3279,31 @@ static int ipw_load(struct ipw_priv *priv) | |||
3276 | const struct firmware *firmware = NULL; | 3279 | const struct firmware *firmware = NULL; |
3277 | const struct firmware *ucode = NULL; | 3280 | const struct firmware *ucode = NULL; |
3278 | #endif | 3281 | #endif |
3282 | char *ucode_name; | ||
3283 | char *fw_name; | ||
3279 | int rc = 0, retries = 3; | 3284 | int rc = 0, retries = 3; |
3280 | 3285 | ||
3281 | #ifdef CONFIG_PM | 3286 | switch (priv->ieee->iw_mode) { |
3282 | if (!fw_loaded) { | 3287 | case IW_MODE_ADHOC: |
3283 | #endif | 3288 | ucode_name = IPW_FW_NAME("ibss_ucode"); |
3284 | rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot")); | 3289 | fw_name = IPW_FW_NAME("ibss"); |
3285 | if (rc) | 3290 | break; |
3286 | goto error; | ||
3287 | |||
3288 | switch (priv->ieee->iw_mode) { | ||
3289 | case IW_MODE_ADHOC: | ||
3290 | rc = ipw_get_fw(priv, &ucode, | ||
3291 | IPW_FW_NAME("ibss_ucode")); | ||
3292 | if (rc) | ||
3293 | goto error; | ||
3294 | |||
3295 | rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss")); | ||
3296 | break; | ||
3297 | |||
3298 | #ifdef CONFIG_IPW2200_MONITOR | 3291 | #ifdef CONFIG_IPW2200_MONITOR |
3299 | case IW_MODE_MONITOR: | 3292 | case IW_MODE_MONITOR: |
3300 | rc = ipw_get_fw(priv, &ucode, | 3293 | ucode_name = IPW_FW_NAME("sniffer_ucode"); |
3301 | IPW_FW_NAME("sniffer_ucode")); | 3294 | fw_name = IPW_FW_NAME("sniffer"); |
3302 | if (rc) | 3295 | break; |
3303 | goto error; | ||
3304 | |||
3305 | rc = ipw_get_fw(priv, &firmware, | ||
3306 | IPW_FW_NAME("sniffer")); | ||
3307 | break; | ||
3308 | #endif | 3296 | #endif |
3309 | case IW_MODE_INFRA: | 3297 | case IW_MODE_INFRA: |
3310 | rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("bss_ucode")); | 3298 | ucode_name = IPW_FW_NAME("bss_ucode"); |
3311 | if (rc) | 3299 | fw_name = IPW_FW_NAME("bss"); |
3312 | goto error; | 3300 | break; |
3313 | 3301 | default: | |
3314 | rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("bss")); | 3302 | rc = -EINVAL; |
3315 | break; | ||
3316 | |||
3317 | default: | ||
3318 | rc = -EINVAL; | ||
3319 | } | ||
3320 | |||
3321 | if (rc) | ||
3322 | goto error; | ||
3323 | |||
3324 | #ifdef CONFIG_PM | ||
3325 | fw_loaded = 1; | ||
3326 | } | 3303 | } |
3327 | #endif | 3304 | |
3305 | if (rc < 0) | ||
3306 | goto error; | ||
3328 | 3307 | ||
3329 | if (!priv->rxq) | 3308 | if (!priv->rxq) |
3330 | priv->rxq = ipw_rx_queue_alloc(priv); | 3309 | priv->rxq = ipw_rx_queue_alloc(priv); |
@@ -3346,7 +3325,7 @@ static int ipw_load(struct ipw_priv *priv) | |||
3346 | ipw_stop_nic(priv); | 3325 | ipw_stop_nic(priv); |
3347 | 3326 | ||
3348 | rc = ipw_reset_nic(priv); | 3327 | rc = ipw_reset_nic(priv); |
3349 | if (rc) { | 3328 | if (rc < 0) { |
3350 | IPW_ERROR("Unable to reset NIC\n"); | 3329 | IPW_ERROR("Unable to reset NIC\n"); |
3351 | goto error; | 3330 | goto error; |
3352 | } | 3331 | } |
@@ -3354,6 +3333,15 @@ static int ipw_load(struct ipw_priv *priv) | |||
3354 | ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND, | 3333 | ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND, |
3355 | IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND); | 3334 | IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND); |
3356 | 3335 | ||
3336 | #ifdef CONFIG_PM | ||
3337 | if (!fw_loaded) { | ||
3338 | #endif | ||
3339 | rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot")); | ||
3340 | if (rc < 0) | ||
3341 | goto error; | ||
3342 | #ifdef CONFIG_PM | ||
3343 | } | ||
3344 | #endif | ||
3357 | /* DMA the initial boot firmware into the device */ | 3345 | /* DMA the initial boot firmware into the device */ |
3358 | rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), | 3346 | rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), |
3359 | bootfw->size - sizeof(struct fw_header)); | 3347 | bootfw->size - sizeof(struct fw_header)); |
@@ -3377,6 +3365,16 @@ static int ipw_load(struct ipw_priv *priv) | |||
3377 | /* ack fw init done interrupt */ | 3365 | /* ack fw init done interrupt */ |
3378 | ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE); | 3366 | ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE); |
3379 | 3367 | ||
3368 | #ifdef CONFIG_PM | ||
3369 | if (!fw_loaded) { | ||
3370 | #endif | ||
3371 | rc = ipw_get_fw(priv, &ucode, ucode_name); | ||
3372 | if (rc < 0) | ||
3373 | goto error; | ||
3374 | #ifdef CONFIG_PM | ||
3375 | } | ||
3376 | #endif | ||
3377 | |||
3380 | /* DMA the ucode into the device */ | 3378 | /* DMA the ucode into the device */ |
3381 | rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), | 3379 | rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), |
3382 | ucode->size - sizeof(struct fw_header)); | 3380 | ucode->size - sizeof(struct fw_header)); |
@@ -3388,6 +3386,16 @@ static int ipw_load(struct ipw_priv *priv) | |||
3388 | /* stop nic */ | 3386 | /* stop nic */ |
3389 | ipw_stop_nic(priv); | 3387 | ipw_stop_nic(priv); |
3390 | 3388 | ||
3389 | #ifdef CONFIG_PM | ||
3390 | if (!fw_loaded) { | ||
3391 | #endif | ||
3392 | rc = ipw_get_fw(priv, &firmware, fw_name); | ||
3393 | if (rc < 0) | ||
3394 | goto error; | ||
3395 | #ifdef CONFIG_PM | ||
3396 | } | ||
3397 | #endif | ||
3398 | |||
3391 | /* DMA bss firmware into the device */ | 3399 | /* DMA bss firmware into the device */ |
3392 | rc = ipw_load_firmware(priv, firmware->data + | 3400 | rc = ipw_load_firmware(priv, firmware->data + |
3393 | sizeof(struct fw_header), | 3401 | sizeof(struct fw_header), |
@@ -3397,10 +3405,14 @@ static int ipw_load(struct ipw_priv *priv) | |||
3397 | goto error; | 3405 | goto error; |
3398 | } | 3406 | } |
3399 | 3407 | ||
3408 | #ifdef CONFIG_PM | ||
3409 | fw_loaded = 1; | ||
3410 | #endif | ||
3411 | |||
3400 | ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0); | 3412 | ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0); |
3401 | 3413 | ||
3402 | rc = ipw_queue_reset(priv); | 3414 | rc = ipw_queue_reset(priv); |
3403 | if (rc) { | 3415 | if (rc < 0) { |
3404 | IPW_ERROR("Unable to initialize queues\n"); | 3416 | IPW_ERROR("Unable to initialize queues\n"); |
3405 | goto error; | 3417 | goto error; |
3406 | } | 3418 | } |