diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 88 |
2 files changed, 57 insertions, 32 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index fd34ba81a0df..4d437cf50c8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1041,6 +1041,7 @@ struct iwl_priv { | |||
1041 | 1041 | ||
1042 | /*For 3945 only*/ | 1042 | /*For 3945 only*/ |
1043 | struct delayed_work thermal_periodic; | 1043 | struct delayed_work thermal_periodic; |
1044 | struct delayed_work rfkill_poll; | ||
1044 | 1045 | ||
1045 | /* TX Power */ | 1046 | /* TX Power */ |
1046 | s8 tx_power_user_lmt; | 1047 | s8 tx_power_user_lmt; |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 1b04284c4ca8..050d532475ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -5479,7 +5479,8 @@ static void iwl3945_bg_rf_kill(struct work_struct *work) | |||
5479 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL, | 5479 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL, |
5480 | "HW and/or SW RF Kill no longer active, restarting " | 5480 | "HW and/or SW RF Kill no longer active, restarting " |
5481 | "device\n"); | 5481 | "device\n"); |
5482 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | 5482 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status) && |
5483 | test_bit(STATUS_ALIVE, &priv->status)) | ||
5483 | queue_work(priv->workqueue, &priv->restart); | 5484 | queue_work(priv->workqueue, &priv->restart); |
5484 | } else { | 5485 | } else { |
5485 | 5486 | ||
@@ -5496,6 +5497,25 @@ static void iwl3945_bg_rf_kill(struct work_struct *work) | |||
5496 | iwl3945_rfkill_set_hw_state(priv); | 5497 | iwl3945_rfkill_set_hw_state(priv); |
5497 | } | 5498 | } |
5498 | 5499 | ||
5500 | static void iwl3945_rfkill_poll(struct work_struct *data) | ||
5501 | { | ||
5502 | struct iwl_priv *priv = | ||
5503 | container_of(data, struct iwl_priv, rfkill_poll.work); | ||
5504 | unsigned long status = priv->status; | ||
5505 | |||
5506 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | ||
5507 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
5508 | else | ||
5509 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
5510 | |||
5511 | if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status)) | ||
5512 | queue_work(priv->workqueue, &priv->rf_kill); | ||
5513 | |||
5514 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | ||
5515 | round_jiffies_relative(2 * HZ)); | ||
5516 | |||
5517 | } | ||
5518 | |||
5499 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) | 5519 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) |
5500 | 5520 | ||
5501 | static void iwl3945_bg_scan_check(struct work_struct *data) | 5521 | static void iwl3945_bg_scan_check(struct work_struct *data) |
@@ -5898,20 +5918,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
5898 | 5918 | ||
5899 | IWL_DEBUG_MAC80211("enter\n"); | 5919 | IWL_DEBUG_MAC80211("enter\n"); |
5900 | 5920 | ||
5901 | if (pci_enable_device(priv->pci_dev)) { | ||
5902 | IWL_ERR(priv, "Fail to pci_enable_device\n"); | ||
5903 | return -ENODEV; | ||
5904 | } | ||
5905 | pci_restore_state(priv->pci_dev); | ||
5906 | pci_enable_msi(priv->pci_dev); | ||
5907 | |||
5908 | ret = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED, | ||
5909 | DRV_NAME, priv); | ||
5910 | if (ret) { | ||
5911 | IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); | ||
5912 | goto out_disable_msi; | ||
5913 | } | ||
5914 | |||
5915 | /* we should be verifying the device is ready to be opened */ | 5921 | /* we should be verifying the device is ready to be opened */ |
5916 | mutex_lock(&priv->mutex); | 5922 | mutex_lock(&priv->mutex); |
5917 | 5923 | ||
@@ -5957,15 +5963,15 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
5957 | } | 5963 | } |
5958 | } | 5964 | } |
5959 | 5965 | ||
5966 | /* ucode is running and will send rfkill notifications, | ||
5967 | * no need to poll the killswitch state anymore */ | ||
5968 | cancel_delayed_work(&priv->rfkill_poll); | ||
5969 | |||
5960 | priv->is_open = 1; | 5970 | priv->is_open = 1; |
5961 | IWL_DEBUG_MAC80211("leave\n"); | 5971 | IWL_DEBUG_MAC80211("leave\n"); |
5962 | return 0; | 5972 | return 0; |
5963 | 5973 | ||
5964 | out_release_irq: | 5974 | out_release_irq: |
5965 | free_irq(priv->pci_dev->irq, priv); | ||
5966 | out_disable_msi: | ||
5967 | pci_disable_msi(priv->pci_dev); | ||
5968 | pci_disable_device(priv->pci_dev); | ||
5969 | priv->is_open = 0; | 5975 | priv->is_open = 0; |
5970 | IWL_DEBUG_MAC80211("leave - failed\n"); | 5976 | IWL_DEBUG_MAC80211("leave - failed\n"); |
5971 | return ret; | 5977 | return ret; |
@@ -5996,10 +6002,10 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw) | |||
5996 | iwl3945_down(priv); | 6002 | iwl3945_down(priv); |
5997 | 6003 | ||
5998 | flush_workqueue(priv->workqueue); | 6004 | flush_workqueue(priv->workqueue); |
5999 | free_irq(priv->pci_dev->irq, priv); | 6005 | |
6000 | pci_disable_msi(priv->pci_dev); | 6006 | /* start polling the killswitch state again */ |
6001 | pci_save_state(priv->pci_dev); | 6007 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, |
6002 | pci_disable_device(priv->pci_dev); | 6008 | round_jiffies_relative(2 * HZ)); |
6003 | 6009 | ||
6004 | IWL_DEBUG_MAC80211("leave\n"); | 6010 | IWL_DEBUG_MAC80211("leave\n"); |
6005 | } | 6011 | } |
@@ -7207,6 +7213,7 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv) | |||
7207 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); | 7213 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); |
7208 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); | 7214 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); |
7209 | INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check); | 7215 | INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check); |
7216 | INIT_DELAYED_WORK(&priv->rfkill_poll, iwl3945_rfkill_poll); | ||
7210 | 7217 | ||
7211 | iwl3945_hw_setup_deferred_work(priv); | 7218 | iwl3945_hw_setup_deferred_work(priv); |
7212 | 7219 | ||
@@ -7497,6 +7504,15 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7497 | iwl3945_disable_interrupts(priv); | 7504 | iwl3945_disable_interrupts(priv); |
7498 | spin_unlock_irqrestore(&priv->lock, flags); | 7505 | spin_unlock_irqrestore(&priv->lock, flags); |
7499 | 7506 | ||
7507 | pci_enable_msi(priv->pci_dev); | ||
7508 | |||
7509 | err = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED, | ||
7510 | DRV_NAME, priv); | ||
7511 | if (err) { | ||
7512 | IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); | ||
7513 | goto out_disable_msi; | ||
7514 | } | ||
7515 | |||
7500 | err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 7516 | err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
7501 | if (err) { | 7517 | if (err) { |
7502 | IWL_ERR(priv, "failed to create sysfs device attributes\n"); | 7518 | IWL_ERR(priv, "failed to create sysfs device attributes\n"); |
@@ -7507,14 +7523,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7507 | iwl3945_setup_deferred_work(priv); | 7523 | iwl3945_setup_deferred_work(priv); |
7508 | iwl3945_setup_rx_handlers(priv); | 7524 | iwl3945_setup_rx_handlers(priv); |
7509 | 7525 | ||
7510 | /*********************** | ||
7511 | * 9. Conclude | ||
7512 | * ********************/ | ||
7513 | pci_save_state(pdev); | ||
7514 | pci_disable_device(pdev); | ||
7515 | |||
7516 | /********************************* | 7526 | /********************************* |
7517 | * 10. Setup and Register mac80211 | 7527 | * 9. Setup and Register mac80211 |
7518 | * *******************************/ | 7528 | * *******************************/ |
7519 | 7529 | ||
7520 | err = ieee80211_register_hw(priv->hw); | 7530 | err = ieee80211_register_hw(priv->hw); |
@@ -7531,6 +7541,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7531 | IWL_ERR(priv, "Unable to initialize RFKILL system. " | 7541 | IWL_ERR(priv, "Unable to initialize RFKILL system. " |
7532 | "Ignoring error: %d\n", err); | 7542 | "Ignoring error: %d\n", err); |
7533 | 7543 | ||
7544 | /* Start monitoring the killswitch */ | ||
7545 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | ||
7546 | 2 * HZ); | ||
7547 | |||
7534 | return 0; | 7548 | return 0; |
7535 | 7549 | ||
7536 | out_remove_sysfs: | 7550 | out_remove_sysfs: |
@@ -7539,10 +7553,12 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7539 | iwl3945_free_geos(priv); | 7553 | iwl3945_free_geos(priv); |
7540 | 7554 | ||
7541 | out_release_irq: | 7555 | out_release_irq: |
7556 | free_irq(priv->pci_dev->irq, priv); | ||
7542 | destroy_workqueue(priv->workqueue); | 7557 | destroy_workqueue(priv->workqueue); |
7543 | priv->workqueue = NULL; | 7558 | priv->workqueue = NULL; |
7544 | iwl3945_unset_hw_params(priv); | 7559 | iwl3945_unset_hw_params(priv); |
7545 | 7560 | out_disable_msi: | |
7561 | pci_disable_msi(priv->pci_dev); | ||
7546 | out_iounmap: | 7562 | out_iounmap: |
7547 | pci_iounmap(pdev, priv->hw_base); | 7563 | pci_iounmap(pdev, priv->hw_base); |
7548 | out_pci_release_regions: | 7564 | out_pci_release_regions: |
@@ -7587,6 +7603,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
7587 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 7603 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
7588 | 7604 | ||
7589 | iwl3945_rfkill_unregister(priv); | 7605 | iwl3945_rfkill_unregister(priv); |
7606 | cancel_delayed_work(&priv->rfkill_poll); | ||
7607 | |||
7590 | iwl3945_dealloc_ucode_pci(priv); | 7608 | iwl3945_dealloc_ucode_pci(priv); |
7591 | 7609 | ||
7592 | if (priv->rxq.bd) | 7610 | if (priv->rxq.bd) |
@@ -7605,6 +7623,9 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
7605 | destroy_workqueue(priv->workqueue); | 7623 | destroy_workqueue(priv->workqueue); |
7606 | priv->workqueue = NULL; | 7624 | priv->workqueue = NULL; |
7607 | 7625 | ||
7626 | free_irq(pdev->irq, priv); | ||
7627 | pci_disable_msi(pdev); | ||
7628 | |||
7608 | pci_iounmap(pdev, priv->hw_base); | 7629 | pci_iounmap(pdev, priv->hw_base); |
7609 | pci_release_regions(pdev); | 7630 | pci_release_regions(pdev); |
7610 | pci_disable_device(pdev); | 7631 | pci_disable_device(pdev); |
@@ -7630,7 +7651,8 @@ static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
7630 | iwl3945_mac_stop(priv->hw); | 7651 | iwl3945_mac_stop(priv->hw); |
7631 | priv->is_open = 1; | 7652 | priv->is_open = 1; |
7632 | } | 7653 | } |
7633 | 7654 | pci_save_state(pdev); | |
7655 | pci_disable_device(pdev); | ||
7634 | pci_set_power_state(pdev, PCI_D3hot); | 7656 | pci_set_power_state(pdev, PCI_D3hot); |
7635 | 7657 | ||
7636 | return 0; | 7658 | return 0; |
@@ -7641,6 +7663,8 @@ static int iwl3945_pci_resume(struct pci_dev *pdev) | |||
7641 | struct iwl_priv *priv = pci_get_drvdata(pdev); | 7663 | struct iwl_priv *priv = pci_get_drvdata(pdev); |
7642 | 7664 | ||
7643 | pci_set_power_state(pdev, PCI_D0); | 7665 | pci_set_power_state(pdev, PCI_D0); |
7666 | pci_enable_device(pdev); | ||
7667 | pci_restore_state(pdev); | ||
7644 | 7668 | ||
7645 | if (priv->is_open) | 7669 | if (priv->is_open) |
7646 | iwl3945_mac_start(priv->hw); | 7670 | iwl3945_mac_start(priv->hw); |