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 | } |
