aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c124
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c133
2 files changed, 90 insertions, 167 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index e0e9bbdf140f..b9a74f5eea51 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -6340,7 +6340,19 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
6340 if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { 6340 if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
6341 IWL_WARNING("Radio disabled by SW RF kill (module " 6341 IWL_WARNING("Radio disabled by SW RF kill (module "
6342 "parameter)\n"); 6342 "parameter)\n");
6343 return 0; 6343 return -ENODEV;
6344 }
6345
6346 /* If platform's RF_KILL switch is NOT set to KILL */
6347 if (iwl3945_read32(priv, CSR_GP_CNTRL) &
6348 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
6349 clear_bit(STATUS_RF_KILL_HW, &priv->status);
6350 else {
6351 set_bit(STATUS_RF_KILL_HW, &priv->status);
6352 if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
6353 IWL_WARNING("Radio disabled by HW RF Kill switch\n");
6354 return -ENODEV;
6355 }
6344 } 6356 }
6345 6357
6346 if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { 6358 if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
@@ -6375,6 +6387,10 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
6375 memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, 6387 memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
6376 priv->ucode_data.len); 6388 priv->ucode_data.len);
6377 6389
6390 /* We return success when we resume from suspend and rf_kill is on. */
6391 if (test_bit(STATUS_RF_KILL_HW, &priv->status))
6392 return 0;
6393
6378 for (i = 0; i < MAX_HW_RESTARTS; i++) { 6394 for (i = 0; i < MAX_HW_RESTARTS; i++) {
6379 6395
6380 iwl3945_clear_stations_table(priv); 6396 iwl3945_clear_stations_table(priv);
@@ -6919,12 +6935,18 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
6919 } 6935 }
6920 } 6936 }
6921 6937
6922 IWL_DEBUG_INFO("Start UP work.\n"); 6938 ret = __iwl3945_up(priv);
6923 __iwl3945_up(priv);
6924 6939
6925 priv->is_open = 1;
6926 mutex_unlock(&priv->mutex); 6940 mutex_unlock(&priv->mutex);
6927 6941
6942 if (ret)
6943 goto out_release_irq;
6944
6945 IWL_DEBUG_INFO("Start UP work.\n");
6946
6947 if (test_bit(STATUS_IN_SUSPEND, &priv->status))
6948 return 0;
6949
6928 /* Wait for START_ALIVE from ucode. Otherwise callbacks from 6950 /* Wait for START_ALIVE from ucode. Otherwise callbacks from
6929 * mac80211 will not be run successfully. */ 6951 * mac80211 will not be run successfully. */
6930 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 6952 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -6939,6 +6961,7 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
6939 } 6961 }
6940 } 6962 }
6941 6963
6964 priv->is_open = 1;
6942 IWL_DEBUG_MAC80211("leave\n"); 6965 IWL_DEBUG_MAC80211("leave\n");
6943 return 0; 6966 return 0;
6944 6967
@@ -6946,6 +6969,9 @@ out_release_irq:
6946 free_irq(priv->pci_dev->irq, priv); 6969 free_irq(priv->pci_dev->irq, priv);
6947out_disable_msi: 6970out_disable_msi:
6948 pci_disable_msi(priv->pci_dev); 6971 pci_disable_msi(priv->pci_dev);
6972 pci_disable_device(priv->pci_dev);
6973 priv->is_open = 0;
6974 IWL_DEBUG_MAC80211("leave - failed\n");
6949 return ret; 6975 return ret;
6950} 6976}
6951 6977
@@ -6955,12 +6981,17 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
6955 6981
6956 IWL_DEBUG_MAC80211("enter\n"); 6982 IWL_DEBUG_MAC80211("enter\n");
6957 6983
6958 /* stop mac, cancel any scan request and clear 6984 if (!priv->is_open) {
6959 * RXON_FILTER_ASSOC_MSK BIT 6985 IWL_DEBUG_MAC80211("leave - skip\n");
6960 */ 6986 return;
6987 }
6988
6961 priv->is_open = 0; 6989 priv->is_open = 0;
6962 6990
6963 if (iwl3945_is_ready_rf(priv)) { 6991 if (iwl3945_is_ready_rf(priv)) {
6992 /* stop mac, cancel any scan request and clear
6993 * RXON_FILTER_ASSOC_MSK BIT
6994 */
6964 mutex_lock(&priv->mutex); 6995 mutex_lock(&priv->mutex);
6965 iwl3945_scan_cancel_timeout(priv, 100); 6996 iwl3945_scan_cancel_timeout(priv, 100);
6966 cancel_delayed_work(&priv->post_associate); 6997 cancel_delayed_work(&priv->post_associate);
@@ -7334,7 +7365,6 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
7334 mutex_unlock(&priv->mutex); 7365 mutex_unlock(&priv->mutex);
7335 7366
7336 IWL_DEBUG_MAC80211("leave\n"); 7367 IWL_DEBUG_MAC80211("leave\n");
7337
7338} 7368}
7339 7369
7340static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) 7370static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
@@ -8731,89 +8761,27 @@ static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
8731{ 8761{
8732 struct iwl3945_priv *priv = pci_get_drvdata(pdev); 8762 struct iwl3945_priv *priv = pci_get_drvdata(pdev);
8733 8763
8734 set_bit(STATUS_IN_SUSPEND, &priv->status); 8764 if (priv->is_open) {
8735 8765 set_bit(STATUS_IN_SUSPEND, &priv->status);
8736 /* Take down the device; powers it off, etc. */ 8766 iwl3945_mac_stop(priv->hw);
8737 iwl3945_down(priv); 8767 priv->is_open = 1;
8738 8768 }
8739 if (priv->mac80211_registered)
8740 ieee80211_stop_queues(priv->hw);
8741 8769
8742 pci_save_state(pdev);
8743 pci_disable_device(pdev);
8744 pci_set_power_state(pdev, PCI_D3hot); 8770 pci_set_power_state(pdev, PCI_D3hot);
8745 8771
8746 return 0; 8772 return 0;
8747} 8773}
8748 8774
8749static void iwl3945_resume(struct iwl3945_priv *priv)
8750{
8751 unsigned long flags;
8752
8753 /* The following it a temporary work around due to the
8754 * suspend / resume not fully initializing the NIC correctly.
8755 * Without all of the following, resume will not attempt to take
8756 * down the NIC (it shouldn't really need to) and will just try
8757 * and bring the NIC back up. However that fails during the
8758 * ucode verification process. This then causes iwl3945_down to be
8759 * called *after* iwl3945_hw_nic_init() has succeeded -- which
8760 * then lets the next init sequence succeed. So, we've
8761 * replicated all of that NIC init code here... */
8762
8763 iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
8764
8765 iwl3945_hw_nic_init(priv);
8766
8767 iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
8768 iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR,
8769 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
8770 iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
8771 iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
8772 iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
8773
8774 /* tell the device to stop sending interrupts */
8775 iwl3945_disable_interrupts(priv);
8776
8777 spin_lock_irqsave(&priv->lock, flags);
8778 iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
8779
8780 if (!iwl3945_grab_nic_access(priv)) {
8781 iwl3945_write_prph(priv, APMG_CLK_DIS_REG,
8782 APMG_CLK_VAL_DMA_CLK_RQT);
8783 iwl3945_release_nic_access(priv);
8784 }
8785 spin_unlock_irqrestore(&priv->lock, flags);
8786
8787 udelay(5);
8788
8789 iwl3945_hw_nic_reset(priv);
8790
8791 /* Bring the device back up */
8792 clear_bit(STATUS_IN_SUSPEND, &priv->status);
8793 queue_work(priv->workqueue, &priv->up);
8794}
8795
8796static int iwl3945_pci_resume(struct pci_dev *pdev) 8775static int iwl3945_pci_resume(struct pci_dev *pdev)
8797{ 8776{
8798 struct iwl3945_priv *priv = pci_get_drvdata(pdev); 8777 struct iwl3945_priv *priv = pci_get_drvdata(pdev);
8799 int err;
8800
8801 printk(KERN_INFO "Coming out of suspend...\n");
8802 8778
8803 pci_set_power_state(pdev, PCI_D0); 8779 pci_set_power_state(pdev, PCI_D0);
8804 err = pci_enable_device(pdev);
8805 pci_restore_state(pdev);
8806 8780
8807 /* 8781 if (priv->is_open)
8808 * Suspend/Resume resets the PCI configuration space, so we have to 8782 iwl3945_mac_start(priv->hw);
8809 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
8810 * from interfering with C3 CPU state. pci_restore_state won't help
8811 * here since it only restores the first 64 bytes pci config header.
8812 */
8813 pci_write_config_byte(pdev, 0x41, 0x00);
8814
8815 iwl3945_resume(priv);
8816 8783
8784 clear_bit(STATUS_IN_SUSPEND, &priv->status);
8817 return 0; 8785 return 0;
8818} 8786}
8819 8787
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 98f09e6e9f8c..811e41b7f664 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -6761,7 +6761,6 @@ static void iwl4965_down(struct iwl4965_priv *priv)
6761static int __iwl4965_up(struct iwl4965_priv *priv) 6761static int __iwl4965_up(struct iwl4965_priv *priv)
6762{ 6762{
6763 int rc, i; 6763 int rc, i;
6764 u32 hw_rf_kill = 0;
6765 6764
6766 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { 6765 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
6767 IWL_WARNING("Exit pending; will not bring the NIC up\n"); 6766 IWL_WARNING("Exit pending; will not bring the NIC up\n");
@@ -6771,7 +6770,19 @@ static int __iwl4965_up(struct iwl4965_priv *priv)
6771 if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { 6770 if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
6772 IWL_WARNING("Radio disabled by SW RF kill (module " 6771 IWL_WARNING("Radio disabled by SW RF kill (module "
6773 "parameter)\n"); 6772 "parameter)\n");
6774 return 0; 6773 return -ENODEV;
6774 }
6775
6776 /* If platform's RF_KILL switch is NOT set to KILL */
6777 if (iwl4965_read32(priv, CSR_GP_CNTRL) &
6778 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
6779 clear_bit(STATUS_RF_KILL_HW, &priv->status);
6780 else {
6781 set_bit(STATUS_RF_KILL_HW, &priv->status);
6782 if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
6783 IWL_WARNING("Radio disabled by HW RF Kill switch\n");
6784 return -ENODEV;
6785 }
6775 } 6786 }
6776 6787
6777 if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { 6788 if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
@@ -6806,17 +6817,9 @@ static int __iwl4965_up(struct iwl4965_priv *priv)
6806 memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, 6817 memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
6807 priv->ucode_data.len); 6818 priv->ucode_data.len);
6808 6819
6809 /* If platform's RF_KILL switch is set to KILL, 6820 /* We return success when we resume from suspend and rf_kill is on. */
6810 * wait for BIT_INT_RF_KILL interrupt before loading uCode 6821 if (test_bit(STATUS_RF_KILL_HW, &priv->status))
6811 * and getting things started */
6812 if (!(iwl4965_read32(priv, CSR_GP_CNTRL) &
6813 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
6814 hw_rf_kill = 1;
6815
6816 if (test_bit(STATUS_RF_KILL_HW, &priv->status) || hw_rf_kill) {
6817 IWL_WARNING("Radio disabled by HW RF Kill switch\n");
6818 return 0; 6822 return 0;
6819 }
6820 6823
6821 for (i = 0; i < MAX_HW_RESTARTS; i++) { 6824 for (i = 0; i < MAX_HW_RESTARTS; i++) {
6822 6825
@@ -7379,12 +7382,18 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
7379 } 7382 }
7380 } 7383 }
7381 7384
7382 IWL_DEBUG_INFO("Start UP work.\n"); 7385 ret = __iwl4965_up(priv);
7383 __iwl4965_up(priv);
7384 7386
7385 priv->is_open = 1;
7386 mutex_unlock(&priv->mutex); 7387 mutex_unlock(&priv->mutex);
7387 7388
7389 if (ret)
7390 goto out_release_irq;
7391
7392 IWL_DEBUG_INFO("Start UP work done.\n");
7393
7394 if (test_bit(STATUS_IN_SUSPEND, &priv->status))
7395 return 0;
7396
7388 /* Wait for START_ALIVE from ucode. Otherwise callbacks from 7397 /* Wait for START_ALIVE from ucode. Otherwise callbacks from
7389 * mac80211 will not be run successfully. */ 7398 * mac80211 will not be run successfully. */
7390 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 7399 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -7399,6 +7408,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
7399 } 7408 }
7400 } 7409 }
7401 7410
7411 priv->is_open = 1;
7402 IWL_DEBUG_MAC80211("leave\n"); 7412 IWL_DEBUG_MAC80211("leave\n");
7403 return 0; 7413 return 0;
7404 7414
@@ -7406,6 +7416,9 @@ out_release_irq:
7406 free_irq(priv->pci_dev->irq, priv); 7416 free_irq(priv->pci_dev->irq, priv);
7407out_disable_msi: 7417out_disable_msi:
7408 pci_disable_msi(priv->pci_dev); 7418 pci_disable_msi(priv->pci_dev);
7419 pci_disable_device(priv->pci_dev);
7420 priv->is_open = 0;
7421 IWL_DEBUG_MAC80211("leave - failed\n");
7409 return ret; 7422 return ret;
7410} 7423}
7411 7424
@@ -7415,12 +7428,17 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw)
7415 7428
7416 IWL_DEBUG_MAC80211("enter\n"); 7429 IWL_DEBUG_MAC80211("enter\n");
7417 7430
7418 /* stop mac, cancel any scan request and clear 7431 if (!priv->is_open) {
7419 * RXON_FILTER_ASSOC_MSK BIT 7432 IWL_DEBUG_MAC80211("leave - skip\n");
7420 */ 7433 return;
7434 }
7435
7421 priv->is_open = 0; 7436 priv->is_open = 0;
7422 7437
7423 if (iwl4965_is_ready_rf(priv)) { 7438 if (iwl4965_is_ready_rf(priv)) {
7439 /* stop mac, cancel any scan request and clear
7440 * RXON_FILTER_ASSOC_MSK BIT
7441 */
7424 mutex_lock(&priv->mutex); 7442 mutex_lock(&priv->mutex);
7425 iwl4965_scan_cancel_timeout(priv, 100); 7443 iwl4965_scan_cancel_timeout(priv, 100);
7426 cancel_delayed_work(&priv->post_associate); 7444 cancel_delayed_work(&priv->post_associate);
@@ -8152,7 +8170,6 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
8152 mutex_unlock(&priv->mutex); 8170 mutex_unlock(&priv->mutex);
8153 8171
8154 IWL_DEBUG_MAC80211("leave\n"); 8172 IWL_DEBUG_MAC80211("leave\n");
8155
8156} 8173}
8157 8174
8158static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, 8175static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
@@ -9327,89 +9344,27 @@ static int iwl4965_pci_suspend(struct pci_dev *pdev, pm_message_t state)
9327{ 9344{
9328 struct iwl4965_priv *priv = pci_get_drvdata(pdev); 9345 struct iwl4965_priv *priv = pci_get_drvdata(pdev);
9329 9346
9330 set_bit(STATUS_IN_SUSPEND, &priv->status); 9347 if (priv->is_open) {
9331 9348 set_bit(STATUS_IN_SUSPEND, &priv->status);
9332 /* Take down the device; powers it off, etc. */ 9349 iwl4965_mac_stop(priv->hw);
9333 iwl4965_down(priv); 9350 priv->is_open = 1;
9334 9351 }
9335 if (priv->mac80211_registered)
9336 ieee80211_stop_queues(priv->hw);
9337 9352
9338 pci_save_state(pdev);
9339 pci_disable_device(pdev);
9340 pci_set_power_state(pdev, PCI_D3hot); 9353 pci_set_power_state(pdev, PCI_D3hot);
9341 9354
9342 return 0; 9355 return 0;
9343} 9356}
9344 9357
9345static void iwl4965_resume(struct iwl4965_priv *priv)
9346{
9347 unsigned long flags;
9348
9349 /* The following it a temporary work around due to the
9350 * suspend / resume not fully initializing the NIC correctly.
9351 * Without all of the following, resume will not attempt to take
9352 * down the NIC (it shouldn't really need to) and will just try
9353 * and bring the NIC back up. However that fails during the
9354 * ucode verification process. This then causes iwl4965_down to be
9355 * called *after* iwl4965_hw_nic_init() has succeeded -- which
9356 * then lets the next init sequence succeed. So, we've
9357 * replicated all of that NIC init code here... */
9358
9359 iwl4965_write32(priv, CSR_INT, 0xFFFFFFFF);
9360
9361 iwl4965_hw_nic_init(priv);
9362
9363 iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
9364 iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR,
9365 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
9366 iwl4965_write32(priv, CSR_INT, 0xFFFFFFFF);
9367 iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
9368 iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
9369
9370 /* tell the device to stop sending interrupts */
9371 iwl4965_disable_interrupts(priv);
9372
9373 spin_lock_irqsave(&priv->lock, flags);
9374 iwl4965_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
9375
9376 if (!iwl4965_grab_nic_access(priv)) {
9377 iwl4965_write_prph(priv, APMG_CLK_DIS_REG,
9378 APMG_CLK_VAL_DMA_CLK_RQT);
9379 iwl4965_release_nic_access(priv);
9380 }
9381 spin_unlock_irqrestore(&priv->lock, flags);
9382
9383 udelay(5);
9384
9385 iwl4965_hw_nic_reset(priv);
9386
9387 /* Bring the device back up */
9388 clear_bit(STATUS_IN_SUSPEND, &priv->status);
9389 queue_work(priv->workqueue, &priv->up);
9390}
9391
9392static int iwl4965_pci_resume(struct pci_dev *pdev) 9358static int iwl4965_pci_resume(struct pci_dev *pdev)
9393{ 9359{
9394 struct iwl4965_priv *priv = pci_get_drvdata(pdev); 9360 struct iwl4965_priv *priv = pci_get_drvdata(pdev);
9395 int err;
9396
9397 printk(KERN_INFO "Coming out of suspend...\n");
9398 9361
9399 pci_set_power_state(pdev, PCI_D0); 9362 pci_set_power_state(pdev, PCI_D0);
9400 err = pci_enable_device(pdev);
9401 pci_restore_state(pdev);
9402 9363
9403 /* 9364 if (priv->is_open)
9404 * Suspend/Resume resets the PCI configuration space, so we have to 9365 iwl4965_mac_start(priv->hw);
9405 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
9406 * from interfering with C3 CPU state. pci_restore_state won't help
9407 * here since it only restores the first 64 bytes pci config header.
9408 */
9409 pci_write_config_byte(pdev, 0x41, 0x00);
9410
9411 iwl4965_resume(priv);
9412 9366
9367 clear_bit(STATUS_IN_SUSPEND, &priv->status);
9413 return 0; 9368 return 0;
9414} 9369}
9415 9370