diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 187 |
1 files changed, 110 insertions, 77 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index ad824c607f36..98f09e6e9f8c 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -6608,31 +6608,12 @@ static void iwl4965_alive_start(struct iwl4965_priv *priv) | |||
6608 | } | 6608 | } |
6609 | 6609 | ||
6610 | iwl4965_init_geos(priv); | 6610 | iwl4965_init_geos(priv); |
6611 | iwl4965_reset_channel_flag(priv); | ||
6611 | 6612 | ||
6612 | if (iwl4965_is_rfkill(priv)) | 6613 | if (iwl4965_is_rfkill(priv)) |
6613 | return; | 6614 | return; |
6614 | 6615 | ||
6615 | if (!priv->mac80211_registered) { | 6616 | ieee80211_start_queues(priv->hw); |
6616 | /* Unlock so any user space entry points can call back into | ||
6617 | * the driver without a deadlock... */ | ||
6618 | mutex_unlock(&priv->mutex); | ||
6619 | iwl4965_rate_control_register(priv->hw); | ||
6620 | rc = ieee80211_register_hw(priv->hw); | ||
6621 | priv->hw->conf.beacon_int = 100; | ||
6622 | mutex_lock(&priv->mutex); | ||
6623 | |||
6624 | if (rc) { | ||
6625 | iwl4965_rate_control_unregister(priv->hw); | ||
6626 | IWL_ERROR("Failed to register network " | ||
6627 | "device (error %d)\n", rc); | ||
6628 | return; | ||
6629 | } | ||
6630 | |||
6631 | priv->mac80211_registered = 1; | ||
6632 | |||
6633 | iwl4965_reset_channel_flag(priv); | ||
6634 | } else | ||
6635 | ieee80211_start_queues(priv->hw); | ||
6636 | 6617 | ||
6637 | priv->active_rate = priv->rates_mask; | 6618 | priv->active_rate = priv->rates_mask; |
6638 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; | 6619 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; |
@@ -6663,7 +6644,9 @@ static void iwl4965_alive_start(struct iwl4965_priv *priv) | |||
6663 | set_bit(STATUS_READY, &priv->status); | 6644 | set_bit(STATUS_READY, &priv->status); |
6664 | 6645 | ||
6665 | iwl4965_rf_kill_ct_config(priv); | 6646 | iwl4965_rf_kill_ct_config(priv); |
6647 | |||
6666 | IWL_DEBUG_INFO("ALIVE processing complete.\n"); | 6648 | IWL_DEBUG_INFO("ALIVE processing complete.\n"); |
6649 | wake_up_interruptible(&priv->wait_command_queue); | ||
6667 | 6650 | ||
6668 | if (priv->error_recovering) | 6651 | if (priv->error_recovering) |
6669 | iwl4965_error_recovery(priv); | 6652 | iwl4965_error_recovery(priv); |
@@ -6777,7 +6760,6 @@ static void iwl4965_down(struct iwl4965_priv *priv) | |||
6777 | 6760 | ||
6778 | static int __iwl4965_up(struct iwl4965_priv *priv) | 6761 | static int __iwl4965_up(struct iwl4965_priv *priv) |
6779 | { | 6762 | { |
6780 | DECLARE_MAC_BUF(mac); | ||
6781 | int rc, i; | 6763 | int rc, i; |
6782 | u32 hw_rf_kill = 0; | 6764 | u32 hw_rf_kill = 0; |
6783 | 6765 | ||
@@ -6822,7 +6804,7 @@ static int __iwl4965_up(struct iwl4965_priv *priv) | |||
6822 | * This will be used to initialize the on-board processor's | 6804 | * This will be used to initialize the on-board processor's |
6823 | * data SRAM for a clean start when the runtime program first loads. */ | 6805 | * data SRAM for a clean start when the runtime program first loads. */ |
6824 | memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, | 6806 | memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, |
6825 | priv->ucode_data.len); | 6807 | priv->ucode_data.len); |
6826 | 6808 | ||
6827 | /* If platform's RF_KILL switch is set to KILL, | 6809 | /* If platform's RF_KILL switch is set to KILL, |
6828 | * wait for BIT_INT_RF_KILL interrupt before loading uCode | 6810 | * wait for BIT_INT_RF_KILL interrupt before loading uCode |
@@ -6853,13 +6835,6 @@ static int __iwl4965_up(struct iwl4965_priv *priv) | |||
6853 | /* start card; "initialize" will load runtime ucode */ | 6835 | /* start card; "initialize" will load runtime ucode */ |
6854 | iwl4965_nic_start(priv); | 6836 | iwl4965_nic_start(priv); |
6855 | 6837 | ||
6856 | /* MAC Address location in EEPROM is same for 3945/4965 */ | ||
6857 | get_eeprom_mac(priv, priv->mac_addr); | ||
6858 | IWL_DEBUG_INFO("MAC address: %s\n", | ||
6859 | print_mac(mac, priv->mac_addr)); | ||
6860 | |||
6861 | SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); | ||
6862 | |||
6863 | IWL_DEBUG_INFO(DRV_NAME " is coming up\n"); | 6838 | IWL_DEBUG_INFO(DRV_NAME " is coming up\n"); |
6864 | 6839 | ||
6865 | return 0; | 6840 | return 0; |
@@ -7365,23 +7340,73 @@ static void iwl4965_bg_scan_completed(struct work_struct *work) | |||
7365 | * | 7340 | * |
7366 | *****************************************************************************/ | 7341 | *****************************************************************************/ |
7367 | 7342 | ||
7343 | #define UCODE_READY_TIMEOUT (2 * HZ) | ||
7344 | |||
7368 | static int iwl4965_mac_start(struct ieee80211_hw *hw) | 7345 | static int iwl4965_mac_start(struct ieee80211_hw *hw) |
7369 | { | 7346 | { |
7370 | struct iwl4965_priv *priv = hw->priv; | 7347 | struct iwl4965_priv *priv = hw->priv; |
7348 | int ret; | ||
7371 | 7349 | ||
7372 | IWL_DEBUG_MAC80211("enter\n"); | 7350 | IWL_DEBUG_MAC80211("enter\n"); |
7373 | 7351 | ||
7352 | if (pci_enable_device(priv->pci_dev)) { | ||
7353 | IWL_ERROR("Fail to pci_enable_device\n"); | ||
7354 | return -ENODEV; | ||
7355 | } | ||
7356 | pci_restore_state(priv->pci_dev); | ||
7357 | pci_enable_msi(priv->pci_dev); | ||
7358 | |||
7359 | ret = request_irq(priv->pci_dev->irq, iwl4965_isr, IRQF_SHARED, | ||
7360 | DRV_NAME, priv); | ||
7361 | if (ret) { | ||
7362 | IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq); | ||
7363 | goto out_disable_msi; | ||
7364 | } | ||
7365 | |||
7374 | /* we should be verifying the device is ready to be opened */ | 7366 | /* we should be verifying the device is ready to be opened */ |
7375 | mutex_lock(&priv->mutex); | 7367 | mutex_lock(&priv->mutex); |
7376 | 7368 | ||
7377 | priv->is_open = 1; | 7369 | memset(&priv->staging_rxon, 0, sizeof(struct iwl4965_rxon_cmd)); |
7370 | /* fetch ucode file from disk, alloc and copy to bus-master buffers ... | ||
7371 | * ucode filename and max sizes are card-specific. */ | ||
7378 | 7372 | ||
7379 | if (!iwl4965_is_rfkill(priv)) | 7373 | if (!priv->ucode_code.len) { |
7380 | ieee80211_start_queues(priv->hw); | 7374 | ret = iwl4965_read_ucode(priv); |
7375 | if (ret) { | ||
7376 | IWL_ERROR("Could not read microcode: %d\n", ret); | ||
7377 | mutex_unlock(&priv->mutex); | ||
7378 | goto out_release_irq; | ||
7379 | } | ||
7380 | } | ||
7381 | 7381 | ||
7382 | IWL_DEBUG_INFO("Start UP work.\n"); | ||
7383 | __iwl4965_up(priv); | ||
7384 | |||
7385 | priv->is_open = 1; | ||
7382 | mutex_unlock(&priv->mutex); | 7386 | mutex_unlock(&priv->mutex); |
7387 | |||
7388 | /* Wait for START_ALIVE from ucode. Otherwise callbacks from | ||
7389 | * mac80211 will not be run successfully. */ | ||
7390 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | ||
7391 | test_bit(STATUS_READY, &priv->status), | ||
7392 | UCODE_READY_TIMEOUT); | ||
7393 | if (!ret) { | ||
7394 | if (!test_bit(STATUS_READY, &priv->status)) { | ||
7395 | IWL_ERROR("Wait for START_ALIVE timeout after %dms.\n", | ||
7396 | jiffies_to_msecs(UCODE_READY_TIMEOUT)); | ||
7397 | ret = -ETIMEDOUT; | ||
7398 | goto out_release_irq; | ||
7399 | } | ||
7400 | } | ||
7401 | |||
7383 | IWL_DEBUG_MAC80211("leave\n"); | 7402 | IWL_DEBUG_MAC80211("leave\n"); |
7384 | return 0; | 7403 | return 0; |
7404 | |||
7405 | out_release_irq: | ||
7406 | free_irq(priv->pci_dev->irq, priv); | ||
7407 | out_disable_msi: | ||
7408 | pci_disable_msi(priv->pci_dev); | ||
7409 | return ret; | ||
7385 | } | 7410 | } |
7386 | 7411 | ||
7387 | static void iwl4965_mac_stop(struct ieee80211_hw *hw) | 7412 | static void iwl4965_mac_stop(struct ieee80211_hw *hw) |
@@ -7390,23 +7415,25 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw) | |||
7390 | 7415 | ||
7391 | IWL_DEBUG_MAC80211("enter\n"); | 7416 | IWL_DEBUG_MAC80211("enter\n"); |
7392 | 7417 | ||
7393 | |||
7394 | mutex_lock(&priv->mutex); | ||
7395 | /* stop mac, cancel any scan request and clear | 7418 | /* stop mac, cancel any scan request and clear |
7396 | * RXON_FILTER_ASSOC_MSK BIT | 7419 | * RXON_FILTER_ASSOC_MSK BIT |
7397 | */ | 7420 | */ |
7398 | priv->is_open = 0; | 7421 | priv->is_open = 0; |
7399 | if (!iwl4965_is_ready_rf(priv)) { | 7422 | |
7400 | IWL_DEBUG_MAC80211("leave - RF not ready\n"); | 7423 | if (iwl4965_is_ready_rf(priv)) { |
7424 | mutex_lock(&priv->mutex); | ||
7425 | iwl4965_scan_cancel_timeout(priv, 100); | ||
7426 | cancel_delayed_work(&priv->post_associate); | ||
7401 | mutex_unlock(&priv->mutex); | 7427 | mutex_unlock(&priv->mutex); |
7402 | return; | ||
7403 | } | 7428 | } |
7404 | 7429 | ||
7405 | iwl4965_scan_cancel_timeout(priv, 100); | 7430 | iwl4965_down(priv); |
7406 | cancel_delayed_work(&priv->post_associate); | 7431 | |
7407 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 7432 | flush_workqueue(priv->workqueue); |
7408 | iwl4965_commit_rxon(priv); | 7433 | free_irq(priv->pci_dev->irq, priv); |
7409 | mutex_unlock(&priv->mutex); | 7434 | pci_disable_msi(priv->pci_dev); |
7435 | pci_save_state(priv->pci_dev); | ||
7436 | pci_disable_device(priv->pci_dev); | ||
7410 | 7437 | ||
7411 | IWL_DEBUG_MAC80211("leave\n"); | 7438 | IWL_DEBUG_MAC80211("leave\n"); |
7412 | } | 7439 | } |
@@ -7458,11 +7485,13 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw, | |||
7458 | IWL_DEBUG_MAC80211("Set %s\n", print_mac(mac, conf->mac_addr)); | 7485 | IWL_DEBUG_MAC80211("Set %s\n", print_mac(mac, conf->mac_addr)); |
7459 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); | 7486 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); |
7460 | } | 7487 | } |
7461 | iwl4965_set_mode(priv, conf->type); | ||
7462 | 7488 | ||
7463 | IWL_DEBUG_MAC80211("leave\n"); | 7489 | if (iwl4965_is_ready(priv)) |
7490 | iwl4965_set_mode(priv, conf->type); | ||
7491 | |||
7464 | mutex_unlock(&priv->mutex); | 7492 | mutex_unlock(&priv->mutex); |
7465 | 7493 | ||
7494 | IWL_DEBUG_MAC80211("leave\n"); | ||
7466 | return 0; | 7495 | return 0; |
7467 | } | 7496 | } |
7468 | 7497 | ||
@@ -7564,9 +7593,9 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7564 | 7593 | ||
7565 | IWL_DEBUG_MAC80211("leave\n"); | 7594 | IWL_DEBUG_MAC80211("leave\n"); |
7566 | 7595 | ||
7567 | mutex_unlock(&priv->mutex); | ||
7568 | out: | 7596 | out: |
7569 | clear_bit(STATUS_CONF_PENDING, &priv->status); | 7597 | clear_bit(STATUS_CONF_PENDING, &priv->status); |
7598 | mutex_unlock(&priv->mutex); | ||
7570 | return ret; | 7599 | return ret; |
7571 | } | 7600 | } |
7572 | 7601 | ||
@@ -7651,6 +7680,9 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, | |||
7651 | return 0; | 7680 | return 0; |
7652 | } | 7681 | } |
7653 | 7682 | ||
7683 | if (!iwl4965_is_alive(priv)) | ||
7684 | return -EAGAIN; | ||
7685 | |||
7654 | mutex_lock(&priv->mutex); | 7686 | mutex_lock(&priv->mutex); |
7655 | 7687 | ||
7656 | if (conf->bssid) | 7688 | if (conf->bssid) |
@@ -8995,6 +9027,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8995 | struct iwl4965_priv *priv; | 9027 | struct iwl4965_priv *priv; |
8996 | struct ieee80211_hw *hw; | 9028 | struct ieee80211_hw *hw; |
8997 | int i; | 9029 | int i; |
9030 | DECLARE_MAC_BUF(mac); | ||
8998 | 9031 | ||
8999 | /* Disabling hardware scan means that mac80211 will perform scans | 9032 | /* Disabling hardware scan means that mac80211 will perform scans |
9000 | * "the hard way", rather than using device's scan. */ | 9033 | * "the hard way", rather than using device's scan. */ |
@@ -9136,7 +9169,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9136 | /* Device-specific setup */ | 9169 | /* Device-specific setup */ |
9137 | if (iwl4965_hw_set_hw_setting(priv)) { | 9170 | if (iwl4965_hw_set_hw_setting(priv)) { |
9138 | IWL_ERROR("failed to set hw settings\n"); | 9171 | IWL_ERROR("failed to set hw settings\n"); |
9139 | mutex_unlock(&priv->mutex); | ||
9140 | goto out_iounmap; | 9172 | goto out_iounmap; |
9141 | } | 9173 | } |
9142 | 9174 | ||
@@ -9161,50 +9193,53 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9161 | 9193 | ||
9162 | iwl4965_disable_interrupts(priv); | 9194 | iwl4965_disable_interrupts(priv); |
9163 | 9195 | ||
9164 | pci_enable_msi(pdev); | ||
9165 | |||
9166 | err = request_irq(pdev->irq, iwl4965_isr, IRQF_SHARED, DRV_NAME, priv); | ||
9167 | if (err) { | ||
9168 | IWL_ERROR("Error allocating IRQ %d\n", pdev->irq); | ||
9169 | goto out_disable_msi; | ||
9170 | } | ||
9171 | |||
9172 | mutex_lock(&priv->mutex); | ||
9173 | |||
9174 | err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group); | 9196 | err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group); |
9175 | if (err) { | 9197 | if (err) { |
9176 | IWL_ERROR("failed to create sysfs device attributes\n"); | 9198 | IWL_ERROR("failed to create sysfs device attributes\n"); |
9177 | mutex_unlock(&priv->mutex); | ||
9178 | goto out_release_irq; | 9199 | goto out_release_irq; |
9179 | } | 9200 | } |
9180 | 9201 | ||
9181 | /* fetch ucode file from disk, alloc and copy to bus-master buffers ... | 9202 | /* nic init */ |
9182 | * ucode filename and max sizes are card-specific. */ | 9203 | iwl4965_set_bit(priv, CSR_GIO_CHICKEN_BITS, |
9183 | err = iwl4965_read_ucode(priv); | 9204 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); |
9205 | |||
9206 | iwl4965_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
9207 | err = iwl4965_poll_bit(priv, CSR_GP_CNTRL, | ||
9208 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
9209 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
9210 | if (err < 0) { | ||
9211 | IWL_DEBUG_INFO("Failed to init the card\n"); | ||
9212 | goto out_remove_sysfs; | ||
9213 | } | ||
9214 | /* Read the EEPROM */ | ||
9215 | err = iwl4965_eeprom_init(priv); | ||
9184 | if (err) { | 9216 | if (err) { |
9185 | IWL_ERROR("Could not read microcode: %d\n", err); | 9217 | IWL_ERROR("Unable to init EEPROM\n"); |
9186 | mutex_unlock(&priv->mutex); | 9218 | goto out_remove_sysfs; |
9187 | goto out_pci_alloc; | ||
9188 | } | 9219 | } |
9220 | /* MAC Address location in EEPROM same for 3945/4965 */ | ||
9221 | get_eeprom_mac(priv, priv->mac_addr); | ||
9222 | IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr)); | ||
9223 | SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); | ||
9189 | 9224 | ||
9190 | mutex_unlock(&priv->mutex); | 9225 | iwl4965_rate_control_register(priv->hw); |
9191 | 9226 | err = ieee80211_register_hw(priv->hw); | |
9192 | IWL_DEBUG_INFO("Queueing UP work.\n"); | 9227 | if (err) { |
9228 | IWL_ERROR("Failed to register network device (error %d)\n", err); | ||
9229 | goto out_remove_sysfs; | ||
9230 | } | ||
9193 | 9231 | ||
9194 | queue_work(priv->workqueue, &priv->up); | 9232 | priv->hw->conf.beacon_int = 100; |
9233 | priv->mac80211_registered = 1; | ||
9234 | pci_save_state(pdev); | ||
9235 | pci_disable_device(pdev); | ||
9195 | 9236 | ||
9196 | return 0; | 9237 | return 0; |
9197 | 9238 | ||
9198 | out_pci_alloc: | 9239 | out_remove_sysfs: |
9199 | iwl4965_dealloc_ucode_pci(priv); | ||
9200 | |||
9201 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); | 9240 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); |
9202 | 9241 | ||
9203 | out_release_irq: | 9242 | out_release_irq: |
9204 | free_irq(pdev->irq, priv); | ||
9205 | |||
9206 | out_disable_msi: | ||
9207 | pci_disable_msi(pdev); | ||
9208 | destroy_workqueue(priv->workqueue); | 9243 | destroy_workqueue(priv->workqueue); |
9209 | priv->workqueue = NULL; | 9244 | priv->workqueue = NULL; |
9210 | iwl4965_unset_hw_setting(priv); | 9245 | iwl4965_unset_hw_setting(priv); |
@@ -9270,8 +9305,6 @@ static void iwl4965_pci_remove(struct pci_dev *pdev) | |||
9270 | destroy_workqueue(priv->workqueue); | 9305 | destroy_workqueue(priv->workqueue); |
9271 | priv->workqueue = NULL; | 9306 | priv->workqueue = NULL; |
9272 | 9307 | ||
9273 | free_irq(pdev->irq, priv); | ||
9274 | pci_disable_msi(pdev); | ||
9275 | pci_iounmap(pdev, priv->hw_base); | 9308 | pci_iounmap(pdev, priv->hw_base); |
9276 | pci_release_regions(pdev); | 9309 | pci_release_regions(pdev); |
9277 | pci_disable_device(pdev); | 9310 | pci_disable_device(pdev); |