aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c88
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
5500static 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
5501static void iwl3945_bg_scan_check(struct work_struct *data) 5521static 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
5964out_release_irq: 5974out_release_irq:
5965 free_irq(priv->pci_dev->irq, priv);
5966out_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);