aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2008-01-14 20:46:18 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:09:57 -0500
commit5a66926aa9230810704fd5a127966215fd58881e (patch)
tree347aa0458a71130357afcd89bb17a264cf728302 /drivers
parent3058f02137359efb412975cf94a9fa7c25413387 (diff)
iwlwifi: delay firmware loading from pci_probe to network interface open
This patch moves the firmware loading (read firmware from disk and load it into the device SRAM) from pci_probe time to the first network interface open time. There are two reasons for doing this: 1. To support kernel buildin iwlwifi drivers. Because kernel initializes network devices subsystem before hard disk and SATA subsystem, it is impossible to get the firmware image from hard disk in the PCI probe handler. Thus delaying the firmware loading into the network interface open time is the way to go. Note, we only read the firmware image from hard disk the first time the interface is open. After this is succeeded, we cache the firmware image into the host memory. This is a performance gain when user open and close the interface multiple times and is necessary for device suspend and resume. 2. For better power saving. When the iwlwifi modules are loaded (or buildin the kernel) but the wireless network interface is not being used, it is a good practice the wireless device consumes as less power as possible. Unloading the firmware from the wireless device and unregister the driver's interrupt handler in the network interface close handler provides users a way to achieve this. User space network configuration tools (i.e NetworkManager) can also contribute here when it detects a wired cable is connected and close the wireless interface automatically. This patch also includes the pci_save/restore_state() fixed by Ian Schram upon the first version. Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: Ian Schram <ischram@telenet.be> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c183
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c187
4 files changed, 217 insertions, 166 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 77e7202c026b..0779a23729e5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1004,14 +1004,6 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
1004 CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM); 1004 CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM);
1005 } 1005 }
1006 1006
1007 spin_unlock_irqrestore(&priv->lock, flags);
1008
1009 /* Initialize the EEPROM */
1010 rc = iwl3945_eeprom_init(priv);
1011 if (rc)
1012 return rc;
1013
1014 spin_lock_irqsave(&priv->lock, flags);
1015 if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom.sku_cap) { 1007 if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom.sku_cap) {
1016 IWL_DEBUG_INFO("SKU OP mode is mrc\n"); 1008 IWL_DEBUG_INFO("SKU OP mode is mrc\n");
1017 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, 1009 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index e6a0397266fc..5fcc2a6f5bf4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -506,11 +506,6 @@ int iwl4965_hw_nic_init(struct iwl4965_priv *priv)
506 506
507 spin_unlock_irqrestore(&priv->lock, flags); 507 spin_unlock_irqrestore(&priv->lock, flags);
508 508
509 /* Read the EEPROM */
510 rc = iwl4965_eeprom_init(priv);
511 if (rc)
512 return rc;
513
514 if (priv->eeprom.calib_version < EEPROM_TX_POWER_VERSION_NEW) { 509 if (priv->eeprom.calib_version < EEPROM_TX_POWER_VERSION_NEW) {
515 IWL_ERROR("Older EEPROM detected! Aborting.\n"); 510 IWL_ERROR("Older EEPROM detected! Aborting.\n");
516 return -EINVAL; 511 return -EINVAL;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 1830e13d5cfd..e0e9bbdf140f 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -6179,31 +6179,12 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
6179 } 6179 }
6180 6180
6181 iwl3945_init_geos(priv); 6181 iwl3945_init_geos(priv);
6182 iwl3945_reset_channel_flag(priv);
6182 6183
6183 if (iwl3945_is_rfkill(priv)) 6184 if (iwl3945_is_rfkill(priv))
6184 return; 6185 return;
6185 6186
6186 if (!priv->mac80211_registered) { 6187 ieee80211_start_queues(priv->hw);
6187 /* Unlock so any user space entry points can call back into
6188 * the driver without a deadlock... */
6189 mutex_unlock(&priv->mutex);
6190 iwl3945_rate_control_register(priv->hw);
6191 rc = ieee80211_register_hw(priv->hw);
6192 priv->hw->conf.beacon_int = 100;
6193 mutex_lock(&priv->mutex);
6194
6195 if (rc) {
6196 iwl3945_rate_control_unregister(priv->hw);
6197 IWL_ERROR("Failed to register network "
6198 "device (error %d)\n", rc);
6199 return;
6200 }
6201
6202 priv->mac80211_registered = 1;
6203
6204 iwl3945_reset_channel_flag(priv);
6205 } else
6206 ieee80211_start_queues(priv->hw);
6207 6188
6208 priv->active_rate = priv->rates_mask; 6189 priv->active_rate = priv->rates_mask;
6209 priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; 6190 priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
@@ -6236,6 +6217,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
6236 iwl3945_reg_txpower_periodic(priv); 6217 iwl3945_reg_txpower_periodic(priv);
6237 6218
6238 IWL_DEBUG_INFO("ALIVE processing complete.\n"); 6219 IWL_DEBUG_INFO("ALIVE processing complete.\n");
6220 wake_up_interruptible(&priv->wait_command_queue);
6239 6221
6240 if (priv->error_recovering) 6222 if (priv->error_recovering)
6241 iwl3945_error_recovery(priv); 6223 iwl3945_error_recovery(priv);
@@ -6348,7 +6330,6 @@ static void iwl3945_down(struct iwl3945_priv *priv)
6348 6330
6349static int __iwl3945_up(struct iwl3945_priv *priv) 6331static int __iwl3945_up(struct iwl3945_priv *priv)
6350{ 6332{
6351 DECLARE_MAC_BUF(mac);
6352 int rc, i; 6333 int rc, i;
6353 6334
6354 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { 6335 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
@@ -6392,7 +6373,7 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
6392 * This will be used to initialize the on-board processor's 6373 * This will be used to initialize the on-board processor's
6393 * data SRAM for a clean start when the runtime program first loads. */ 6374 * data SRAM for a clean start when the runtime program first loads. */
6394 memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, 6375 memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
6395 priv->ucode_data.len); 6376 priv->ucode_data.len);
6396 6377
6397 for (i = 0; i < MAX_HW_RESTARTS; i++) { 6378 for (i = 0; i < MAX_HW_RESTARTS; i++) {
6398 6379
@@ -6411,13 +6392,6 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
6411 /* start card; "initialize" will load runtime ucode */ 6392 /* start card; "initialize" will load runtime ucode */
6412 iwl3945_nic_start(priv); 6393 iwl3945_nic_start(priv);
6413 6394
6414 /* MAC Address location in EEPROM is same for 3945/4965 */
6415 get_eeprom_mac(priv, priv->mac_addr);
6416 IWL_DEBUG_INFO("MAC address: %s\n",
6417 print_mac(mac, priv->mac_addr));
6418
6419 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
6420
6421 IWL_DEBUG_INFO(DRV_NAME " is coming up\n"); 6395 IWL_DEBUG_INFO(DRV_NAME " is coming up\n");
6422 6396
6423 return 0; 6397 return 0;
@@ -6906,23 +6880,73 @@ static void iwl3945_bg_scan_completed(struct work_struct *work)
6906 * 6880 *
6907 *****************************************************************************/ 6881 *****************************************************************************/
6908 6882
6883#define UCODE_READY_TIMEOUT (2 * HZ)
6884
6909static int iwl3945_mac_start(struct ieee80211_hw *hw) 6885static int iwl3945_mac_start(struct ieee80211_hw *hw)
6910{ 6886{
6911 struct iwl3945_priv *priv = hw->priv; 6887 struct iwl3945_priv *priv = hw->priv;
6888 int ret;
6912 6889
6913 IWL_DEBUG_MAC80211("enter\n"); 6890 IWL_DEBUG_MAC80211("enter\n");
6914 6891
6892 if (pci_enable_device(priv->pci_dev)) {
6893 IWL_ERROR("Fail to pci_enable_device\n");
6894 return -ENODEV;
6895 }
6896 pci_restore_state(priv->pci_dev);
6897 pci_enable_msi(priv->pci_dev);
6898
6899 ret = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED,
6900 DRV_NAME, priv);
6901 if (ret) {
6902 IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq);
6903 goto out_disable_msi;
6904 }
6905
6915 /* we should be verifying the device is ready to be opened */ 6906 /* we should be verifying the device is ready to be opened */
6916 mutex_lock(&priv->mutex); 6907 mutex_lock(&priv->mutex);
6917 6908
6918 priv->is_open = 1; 6909 memset(&priv->staging_rxon, 0, sizeof(struct iwl3945_rxon_cmd));
6910 /* fetch ucode file from disk, alloc and copy to bus-master buffers ...
6911 * ucode filename and max sizes are card-specific. */
6919 6912
6920 if (!iwl3945_is_rfkill(priv)) 6913 if (!priv->ucode_code.len) {
6921 ieee80211_start_queues(priv->hw); 6914 ret = iwl3945_read_ucode(priv);
6915 if (ret) {
6916 IWL_ERROR("Could not read microcode: %d\n", ret);
6917 mutex_unlock(&priv->mutex);
6918 goto out_release_irq;
6919 }
6920 }
6922 6921
6922 IWL_DEBUG_INFO("Start UP work.\n");
6923 __iwl3945_up(priv);
6924
6925 priv->is_open = 1;
6923 mutex_unlock(&priv->mutex); 6926 mutex_unlock(&priv->mutex);
6927
6928 /* Wait for START_ALIVE from ucode. Otherwise callbacks from
6929 * mac80211 will not be run successfully. */
6930 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
6931 test_bit(STATUS_READY, &priv->status),
6932 UCODE_READY_TIMEOUT);
6933 if (!ret) {
6934 if (!test_bit(STATUS_READY, &priv->status)) {
6935 IWL_ERROR("Wait for START_ALIVE timeout after %dms.\n",
6936 jiffies_to_msecs(UCODE_READY_TIMEOUT));
6937 ret = -ETIMEDOUT;
6938 goto out_release_irq;
6939 }
6940 }
6941
6924 IWL_DEBUG_MAC80211("leave\n"); 6942 IWL_DEBUG_MAC80211("leave\n");
6925 return 0; 6943 return 0;
6944
6945out_release_irq:
6946 free_irq(priv->pci_dev->irq, priv);
6947out_disable_msi:
6948 pci_disable_msi(priv->pci_dev);
6949 return ret;
6926} 6950}
6927 6951
6928static void iwl3945_mac_stop(struct ieee80211_hw *hw) 6952static void iwl3945_mac_stop(struct ieee80211_hw *hw)
@@ -6931,23 +6955,25 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
6931 6955
6932 IWL_DEBUG_MAC80211("enter\n"); 6956 IWL_DEBUG_MAC80211("enter\n");
6933 6957
6934
6935 mutex_lock(&priv->mutex);
6936 /* stop mac, cancel any scan request and clear 6958 /* stop mac, cancel any scan request and clear
6937 * RXON_FILTER_ASSOC_MSK BIT 6959 * RXON_FILTER_ASSOC_MSK BIT
6938 */ 6960 */
6939 priv->is_open = 0; 6961 priv->is_open = 0;
6940 if (!iwl3945_is_ready_rf(priv)) { 6962
6941 IWL_DEBUG_MAC80211("leave - RF not ready\n"); 6963 if (iwl3945_is_ready_rf(priv)) {
6964 mutex_lock(&priv->mutex);
6965 iwl3945_scan_cancel_timeout(priv, 100);
6966 cancel_delayed_work(&priv->post_associate);
6942 mutex_unlock(&priv->mutex); 6967 mutex_unlock(&priv->mutex);
6943 return;
6944 } 6968 }
6945 6969
6946 iwl3945_scan_cancel_timeout(priv, 100); 6970 iwl3945_down(priv);
6947 cancel_delayed_work(&priv->post_associate); 6971
6948 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 6972 flush_workqueue(priv->workqueue);
6949 iwl3945_commit_rxon(priv); 6973 free_irq(priv->pci_dev->irq, priv);
6950 mutex_unlock(&priv->mutex); 6974 pci_disable_msi(priv->pci_dev);
6975 pci_save_state(priv->pci_dev);
6976 pci_disable_device(priv->pci_dev);
6951 6977
6952 IWL_DEBUG_MAC80211("leave\n"); 6978 IWL_DEBUG_MAC80211("leave\n");
6953} 6979}
@@ -7000,11 +7026,12 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
7000 memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); 7026 memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
7001 } 7027 }
7002 7028
7003 iwl3945_set_mode(priv, conf->type); 7029 if (iwl3945_is_ready(priv))
7030 iwl3945_set_mode(priv, conf->type);
7004 7031
7005 IWL_DEBUG_MAC80211("leave\n");
7006 mutex_unlock(&priv->mutex); 7032 mutex_unlock(&priv->mutex);
7007 7033
7034 IWL_DEBUG_MAC80211("leave\n");
7008 return 0; 7035 return 0;
7009} 7036}
7010 7037
@@ -7178,6 +7205,9 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
7178 return 0; 7205 return 0;
7179 } 7206 }
7180 7207
7208 if (!iwl3945_is_alive(priv))
7209 return -EAGAIN;
7210
7181 mutex_lock(&priv->mutex); 7211 mutex_lock(&priv->mutex);
7182 7212
7183 if (conf->bssid) 7213 if (conf->bssid)
@@ -8390,6 +8420,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8390 struct iwl3945_priv *priv; 8420 struct iwl3945_priv *priv;
8391 struct ieee80211_hw *hw; 8421 struct ieee80211_hw *hw;
8392 int i; 8422 int i;
8423 DECLARE_MAC_BUF(mac);
8393 8424
8394 /* Disabling hardware scan means that mac80211 will perform scans 8425 /* Disabling hardware scan means that mac80211 will perform scans
8395 * "the hard way", rather than using device's scan. */ 8426 * "the hard way", rather than using device's scan. */
@@ -8542,7 +8573,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8542 /* Device-specific setup */ 8573 /* Device-specific setup */
8543 if (iwl3945_hw_set_hw_setting(priv)) { 8574 if (iwl3945_hw_set_hw_setting(priv)) {
8544 IWL_ERROR("failed to set hw settings\n"); 8575 IWL_ERROR("failed to set hw settings\n");
8545 mutex_unlock(&priv->mutex);
8546 goto out_iounmap; 8576 goto out_iounmap;
8547 } 8577 }
8548 8578
@@ -8567,50 +8597,53 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8567 8597
8568 iwl3945_disable_interrupts(priv); 8598 iwl3945_disable_interrupts(priv);
8569 8599
8570 pci_enable_msi(pdev);
8571
8572 err = request_irq(pdev->irq, iwl3945_isr, IRQF_SHARED, DRV_NAME, priv);
8573 if (err) {
8574 IWL_ERROR("Error allocating IRQ %d\n", pdev->irq);
8575 goto out_disable_msi;
8576 }
8577
8578 mutex_lock(&priv->mutex);
8579
8580 err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group); 8600 err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group);
8581 if (err) { 8601 if (err) {
8582 IWL_ERROR("failed to create sysfs device attributes\n"); 8602 IWL_ERROR("failed to create sysfs device attributes\n");
8583 mutex_unlock(&priv->mutex);
8584 goto out_release_irq; 8603 goto out_release_irq;
8585 } 8604 }
8586 8605
8587 /* fetch ucode file from disk, alloc and copy to bus-master buffers ... 8606 /* nic init */
8588 * ucode filename and max sizes are card-specific. */ 8607 iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
8589 err = iwl3945_read_ucode(priv); 8608 CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
8609
8610 iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
8611 err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
8612 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
8613 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
8614 if (err < 0) {
8615 IWL_DEBUG_INFO("Failed to init the card\n");
8616 goto out_remove_sysfs;
8617 }
8618 /* Read the EEPROM */
8619 err = iwl3945_eeprom_init(priv);
8590 if (err) { 8620 if (err) {
8591 IWL_ERROR("Could not read microcode: %d\n", err); 8621 IWL_ERROR("Unable to init EEPROM\n");
8592 mutex_unlock(&priv->mutex); 8622 goto out_remove_sysfs;
8593 goto out_pci_alloc;
8594 } 8623 }
8624 /* MAC Address location in EEPROM same for 3945/4965 */
8625 get_eeprom_mac(priv, priv->mac_addr);
8626 IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
8627 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
8595 8628
8596 mutex_unlock(&priv->mutex); 8629 iwl3945_rate_control_register(priv->hw);
8597 8630 err = ieee80211_register_hw(priv->hw);
8598 IWL_DEBUG_INFO("Queueing UP work.\n"); 8631 if (err) {
8632 IWL_ERROR("Failed to register network device (error %d)\n", err);
8633 goto out_remove_sysfs;
8634 }
8599 8635
8600 queue_work(priv->workqueue, &priv->up); 8636 priv->hw->conf.beacon_int = 100;
8637 priv->mac80211_registered = 1;
8638 pci_save_state(pdev);
8639 pci_disable_device(pdev);
8601 8640
8602 return 0; 8641 return 0;
8603 8642
8604 out_pci_alloc: 8643 out_remove_sysfs:
8605 iwl3945_dealloc_ucode_pci(priv);
8606
8607 sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); 8644 sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
8608 8645
8609 out_release_irq: 8646 out_release_irq:
8610 free_irq(pdev->irq, priv);
8611
8612 out_disable_msi:
8613 pci_disable_msi(pdev);
8614 destroy_workqueue(priv->workqueue); 8647 destroy_workqueue(priv->workqueue);
8615 priv->workqueue = NULL; 8648 priv->workqueue = NULL;
8616 iwl3945_unset_hw_setting(priv); 8649 iwl3945_unset_hw_setting(priv);
@@ -8676,8 +8709,6 @@ static void iwl3945_pci_remove(struct pci_dev *pdev)
8676 destroy_workqueue(priv->workqueue); 8709 destroy_workqueue(priv->workqueue);
8677 priv->workqueue = NULL; 8710 priv->workqueue = NULL;
8678 8711
8679 free_irq(pdev->irq, priv);
8680 pci_disable_msi(pdev);
8681 pci_iounmap(pdev, priv->hw_base); 8712 pci_iounmap(pdev, priv->hw_base);
8682 pci_release_regions(pdev); 8713 pci_release_regions(pdev);
8683 pci_disable_device(pdev); 8714 pci_disable_device(pdev);
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
6778static int __iwl4965_up(struct iwl4965_priv *priv) 6761static 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
7368static int iwl4965_mac_start(struct ieee80211_hw *hw) 7345static 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
7405out_release_irq:
7406 free_irq(priv->pci_dev->irq, priv);
7407out_disable_msi:
7408 pci_disable_msi(priv->pci_dev);
7409 return ret;
7385} 7410}
7386 7411
7387static void iwl4965_mac_stop(struct ieee80211_hw *hw) 7412static 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);
7568out: 7596out:
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);