diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2008-05-15 01:54:17 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-21 21:48:06 -0400 |
commit | 6ba879562289bcad537a2374754ef750307c7d32 (patch) | |
tree | cdfe183883a2ab093419dd7c6544ea76877f3572 /drivers/net/wireless/iwlwifi | |
parent | 445c2dff409ef9de5d2f964d20917ab238fd266f (diff) |
iwlwifi: refactor pci prob flow
This patch refactores pci prob flow. It moves mac80211 registration
to the end, otherwise there is a race between error path in pci_probe
and mac_start.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 61 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-eeprom.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 31 |
4 files changed, 54 insertions, 45 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 79e46c5a35a4..21f481ef1ce2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -518,12 +518,6 @@ static int iwlcore_init_geos(struct iwl_priv *priv) | |||
518 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, | 518 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, |
519 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | 519 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); |
520 | 520 | ||
521 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
522 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
523 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
524 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
525 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
526 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
527 | 521 | ||
528 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 522 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
529 | 523 | ||
@@ -533,13 +527,12 @@ static int iwlcore_init_geos(struct iwl_priv *priv) | |||
533 | /* | 527 | /* |
534 | * iwlcore_free_geos - undo allocations in iwlcore_init_geos | 528 | * iwlcore_free_geos - undo allocations in iwlcore_init_geos |
535 | */ | 529 | */ |
536 | void iwlcore_free_geos(struct iwl_priv *priv) | 530 | static void iwlcore_free_geos(struct iwl_priv *priv) |
537 | { | 531 | { |
538 | kfree(priv->ieee_channels); | 532 | kfree(priv->ieee_channels); |
539 | kfree(priv->ieee_rates); | 533 | kfree(priv->ieee_rates); |
540 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | 534 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
541 | } | 535 | } |
542 | EXPORT_SYMBOL(iwlcore_free_geos); | ||
543 | 536 | ||
544 | #ifdef CONFIG_IWL4965_HT | 537 | #ifdef CONFIG_IWL4965_HT |
545 | static u8 is_single_rx_stream(struct iwl_priv *priv) | 538 | static u8 is_single_rx_stream(struct iwl_priv *priv) |
@@ -767,8 +760,9 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, | |||
767 | } | 760 | } |
768 | EXPORT_SYMBOL(iwl_set_rxon_channel); | 761 | EXPORT_SYMBOL(iwl_set_rxon_channel); |
769 | 762 | ||
770 | static void iwlcore_init_hw(struct iwl_priv *priv) | 763 | int iwl_setup_mac(struct iwl_priv *priv) |
771 | { | 764 | { |
765 | int ret; | ||
772 | struct ieee80211_hw *hw = priv->hw; | 766 | struct ieee80211_hw *hw = priv->hw; |
773 | hw->rate_control_algorithm = "iwl-4965-rs"; | 767 | hw->rate_control_algorithm = "iwl-4965-rs"; |
774 | 768 | ||
@@ -782,9 +776,29 @@ static void iwlcore_init_hw(struct iwl_priv *priv) | |||
782 | /* Enhanced value; more queues, to support 11n aggregation */ | 776 | /* Enhanced value; more queues, to support 11n aggregation */ |
783 | hw->ampdu_queues = 12; | 777 | hw->ampdu_queues = 12; |
784 | #endif /* CONFIG_IWL4965_HT */ | 778 | #endif /* CONFIG_IWL4965_HT */ |
779 | |||
780 | hw->conf.beacon_int = 100; | ||
781 | |||
782 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
783 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
784 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
785 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
786 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
787 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
788 | |||
789 | ret = ieee80211_register_hw(priv->hw); | ||
790 | if (ret) { | ||
791 | IWL_ERROR("Failed to register hw (error %d)\n", ret); | ||
792 | return ret; | ||
793 | } | ||
794 | priv->mac80211_registered = 1; | ||
795 | |||
796 | return 0; | ||
785 | } | 797 | } |
798 | EXPORT_SYMBOL(iwl_setup_mac); | ||
799 | |||
786 | 800 | ||
787 | static int iwlcore_init_drv(struct iwl_priv *priv) | 801 | int iwl_init_drv(struct iwl_priv *priv) |
788 | { | 802 | { |
789 | int ret; | 803 | int ret; |
790 | int i; | 804 | int i; |
@@ -821,6 +835,9 @@ static int iwlcore_init_drv(struct iwl_priv *priv) | |||
821 | /* Choose which receivers/antennas to use */ | 835 | /* Choose which receivers/antennas to use */ |
822 | iwl_set_rxon_chain(priv); | 836 | iwl_set_rxon_chain(priv); |
823 | 837 | ||
838 | if (priv->cfg->mod_params->enable_qos) | ||
839 | priv->qos_data.qos_enable = 1; | ||
840 | |||
824 | iwl_reset_qos(priv); | 841 | iwl_reset_qos(priv); |
825 | 842 | ||
826 | priv->qos_data.qos_active = 0; | 843 | priv->qos_data.qos_active = 0; |
@@ -845,34 +862,22 @@ static int iwlcore_init_drv(struct iwl_priv *priv) | |||
845 | goto err_free_channel_map; | 862 | goto err_free_channel_map; |
846 | } | 863 | } |
847 | 864 | ||
848 | ret = ieee80211_register_hw(priv->hw); | ||
849 | if (ret) { | ||
850 | IWL_ERROR("Failed to register network device (error %d)\n", | ||
851 | ret); | ||
852 | goto err_free_geos; | ||
853 | } | ||
854 | |||
855 | priv->hw->conf.beacon_int = 100; | ||
856 | priv->mac80211_registered = 1; | ||
857 | |||
858 | return 0; | 865 | return 0; |
859 | 866 | ||
860 | err_free_geos: | ||
861 | iwlcore_free_geos(priv); | ||
862 | err_free_channel_map: | 867 | err_free_channel_map: |
863 | iwl_free_channel_map(priv); | 868 | iwl_free_channel_map(priv); |
864 | err: | 869 | err: |
865 | return ret; | 870 | return ret; |
866 | } | 871 | } |
872 | EXPORT_SYMBOL(iwl_init_drv); | ||
873 | |||
867 | 874 | ||
868 | int iwl_setup(struct iwl_priv *priv) | 875 | void iwl_uninit_drv(struct iwl_priv *priv) |
869 | { | 876 | { |
870 | int ret = 0; | 877 | iwlcore_free_geos(priv); |
871 | iwlcore_init_hw(priv); | 878 | iwl_free_channel_map(priv); |
872 | ret = iwlcore_init_drv(priv); | ||
873 | return ret; | ||
874 | } | 879 | } |
875 | EXPORT_SYMBOL(iwl_setup); | 880 | EXPORT_SYMBOL(iwl_uninit_drv); |
876 | 881 | ||
877 | /* Low level driver call this function to update iwlcore with | 882 | /* Low level driver call this function to update iwlcore with |
878 | * driver status. | 883 | * driver status. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index b159fd3c93ca..774aa7c8a82a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -175,13 +175,13 @@ void iwl_set_rxon_chain(struct iwl_priv *priv); | |||
175 | int iwl_set_rxon_channel(struct iwl_priv *priv, | 175 | int iwl_set_rxon_channel(struct iwl_priv *priv, |
176 | enum ieee80211_band band, | 176 | enum ieee80211_band band, |
177 | u16 channel); | 177 | u16 channel); |
178 | void iwlcore_free_geos(struct iwl_priv *priv); | ||
179 | int iwl_setup(struct iwl_priv *priv); | ||
180 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info); | 178 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info); |
181 | u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, | 179 | u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, |
182 | struct ieee80211_ht_info *sta_ht_inf); | 180 | struct ieee80211_ht_info *sta_ht_inf); |
183 | int iwl_hw_nic_init(struct iwl_priv *priv); | 181 | int iwl_hw_nic_init(struct iwl_priv *priv); |
184 | 182 | int iwl_setup_mac(struct iwl_priv *priv); | |
183 | int iwl_init_drv(struct iwl_priv *priv); | ||
184 | void iwl_uninit_drv(struct iwl_priv *priv); | ||
185 | /* "keep warm" functions */ | 185 | /* "keep warm" functions */ |
186 | int iwl_kw_init(struct iwl_priv *priv); | 186 | int iwl_kw_init(struct iwl_priv *priv); |
187 | int iwl_kw_alloc(struct iwl_priv *priv); | 187 | int iwl_kw_alloc(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 300ef8e74156..e559c19fd361 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -567,7 +567,6 @@ void iwl_free_channel_map(struct iwl_priv *priv) | |||
567 | kfree(priv->channel_info); | 567 | kfree(priv->channel_info); |
568 | priv->channel_count = 0; | 568 | priv->channel_count = 0; |
569 | } | 569 | } |
570 | EXPORT_SYMBOL(iwl_free_channel_map); | ||
571 | 570 | ||
572 | /** | 571 | /** |
573 | * iwl_get_channel_info - Find driver's private channel info | 572 | * iwl_get_channel_info - Find driver's private channel info |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index e06142d9da59..05edde178302 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -5878,10 +5878,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
5878 | } | 5878 | } |
5879 | 5879 | ||
5880 | /******************* | 5880 | /******************* |
5881 | * 6. Setup hw/priv | 5881 | * 6. Setup priv |
5882 | *******************/ | 5882 | *******************/ |
5883 | 5883 | ||
5884 | err = iwl_setup(priv); | 5884 | err = iwl_init_drv(priv); |
5885 | if (err) | 5885 | if (err) |
5886 | goto out_free_eeprom; | 5886 | goto out_free_eeprom; |
5887 | /* At this point both hw and priv are initialized. */ | 5887 | /* At this point both hw and priv are initialized. */ |
@@ -5896,9 +5896,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
5896 | IWL_DEBUG_INFO("Radio disabled.\n"); | 5896 | IWL_DEBUG_INFO("Radio disabled.\n"); |
5897 | } | 5897 | } |
5898 | 5898 | ||
5899 | if (priv->cfg->mod_params->enable_qos) | ||
5900 | priv->qos_data.qos_enable = 1; | ||
5901 | |||
5902 | /******************** | 5899 | /******************** |
5903 | * 8. Setup services | 5900 | * 8. Setup services |
5904 | ********************/ | 5901 | ********************/ |
@@ -5909,14 +5906,9 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
5909 | err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group); | 5906 | err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group); |
5910 | if (err) { | 5907 | if (err) { |
5911 | IWL_ERROR("failed to create sysfs device attributes\n"); | 5908 | IWL_ERROR("failed to create sysfs device attributes\n"); |
5912 | goto out_free_eeprom; | 5909 | goto out_uninit_drv; |
5913 | } | 5910 | } |
5914 | 5911 | ||
5915 | err = iwl_dbgfs_register(priv, DRV_NAME); | ||
5916 | if (err) { | ||
5917 | IWL_ERROR("failed to create debugfs files\n"); | ||
5918 | goto out_remove_sysfs; | ||
5919 | } | ||
5920 | 5912 | ||
5921 | iwl4965_setup_deferred_work(priv); | 5913 | iwl4965_setup_deferred_work(priv); |
5922 | iwl4965_setup_rx_handlers(priv); | 5914 | iwl4965_setup_rx_handlers(priv); |
@@ -5927,12 +5919,26 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
5927 | pci_save_state(pdev); | 5919 | pci_save_state(pdev); |
5928 | pci_disable_device(pdev); | 5920 | pci_disable_device(pdev); |
5929 | 5921 | ||
5922 | /********************************** | ||
5923 | * 10. Setup and register mac80211 | ||
5924 | **********************************/ | ||
5925 | |||
5926 | err = iwl_setup_mac(priv); | ||
5927 | if (err) | ||
5928 | goto out_remove_sysfs; | ||
5929 | |||
5930 | err = iwl_dbgfs_register(priv, DRV_NAME); | ||
5931 | if (err) | ||
5932 | IWL_ERROR("failed to create debugfs files\n"); | ||
5933 | |||
5930 | /* notify iwlcore to init */ | 5934 | /* notify iwlcore to init */ |
5931 | iwlcore_low_level_notify(priv, IWLCORE_INIT_EVT); | 5935 | iwlcore_low_level_notify(priv, IWLCORE_INIT_EVT); |
5932 | return 0; | 5936 | return 0; |
5933 | 5937 | ||
5934 | out_remove_sysfs: | 5938 | out_remove_sysfs: |
5935 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); | 5939 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); |
5940 | out_uninit_drv: | ||
5941 | iwl_uninit_drv(priv); | ||
5936 | out_free_eeprom: | 5942 | out_free_eeprom: |
5937 | iwl_eeprom_free(priv); | 5943 | iwl_eeprom_free(priv); |
5938 | out_iounmap: | 5944 | out_iounmap: |
@@ -6014,8 +6020,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
6014 | pci_disable_device(pdev); | 6020 | pci_disable_device(pdev); |
6015 | pci_set_drvdata(pdev, NULL); | 6021 | pci_set_drvdata(pdev, NULL); |
6016 | 6022 | ||
6017 | iwl_free_channel_map(priv); | 6023 | iwl_uninit_drv(priv); |
6018 | iwlcore_free_geos(priv); | ||
6019 | 6024 | ||
6020 | if (priv->ibss_beacon) | 6025 | if (priv->ibss_beacon) |
6021 | dev_kfree_skb(priv->ibss_beacon); | 6026 | dev_kfree_skb(priv->ibss_beacon); |