提交 6ba87956 编写于 作者: T Tomas Winkler 提交者: John W. Linville

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: NTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 445c2dff
...@@ -518,12 +518,6 @@ static int iwlcore_init_geos(struct iwl_priv *priv) ...@@ -518,12 +518,6 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
priv->bands[IEEE80211_BAND_2GHZ].n_channels, priv->bands[IEEE80211_BAND_2GHZ].n_channels,
priv->bands[IEEE80211_BAND_5GHZ].n_channels); priv->bands[IEEE80211_BAND_5GHZ].n_channels);
if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&priv->bands[IEEE80211_BAND_2GHZ];
if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&priv->bands[IEEE80211_BAND_5GHZ];
set_bit(STATUS_GEO_CONFIGURED, &priv->status); set_bit(STATUS_GEO_CONFIGURED, &priv->status);
...@@ -533,13 +527,12 @@ static int iwlcore_init_geos(struct iwl_priv *priv) ...@@ -533,13 +527,12 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
/* /*
* iwlcore_free_geos - undo allocations in iwlcore_init_geos * iwlcore_free_geos - undo allocations in iwlcore_init_geos
*/ */
void iwlcore_free_geos(struct iwl_priv *priv) static void iwlcore_free_geos(struct iwl_priv *priv)
{ {
kfree(priv->ieee_channels); kfree(priv->ieee_channels);
kfree(priv->ieee_rates); kfree(priv->ieee_rates);
clear_bit(STATUS_GEO_CONFIGURED, &priv->status); clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
} }
EXPORT_SYMBOL(iwlcore_free_geos);
#ifdef CONFIG_IWL4965_HT #ifdef CONFIG_IWL4965_HT
static u8 is_single_rx_stream(struct iwl_priv *priv) static u8 is_single_rx_stream(struct iwl_priv *priv)
...@@ -767,8 +760,9 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, ...@@ -767,8 +760,9 @@ int iwl_set_rxon_channel(struct iwl_priv *priv,
} }
EXPORT_SYMBOL(iwl_set_rxon_channel); EXPORT_SYMBOL(iwl_set_rxon_channel);
static void iwlcore_init_hw(struct iwl_priv *priv) int iwl_setup_mac(struct iwl_priv *priv)
{ {
int ret;
struct ieee80211_hw *hw = priv->hw; struct ieee80211_hw *hw = priv->hw;
hw->rate_control_algorithm = "iwl-4965-rs"; hw->rate_control_algorithm = "iwl-4965-rs";
...@@ -782,9 +776,29 @@ static void iwlcore_init_hw(struct iwl_priv *priv) ...@@ -782,9 +776,29 @@ static void iwlcore_init_hw(struct iwl_priv *priv)
/* Enhanced value; more queues, to support 11n aggregation */ /* Enhanced value; more queues, to support 11n aggregation */
hw->ampdu_queues = 12; hw->ampdu_queues = 12;
#endif /* CONFIG_IWL4965_HT */ #endif /* CONFIG_IWL4965_HT */
hw->conf.beacon_int = 100;
if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&priv->bands[IEEE80211_BAND_2GHZ];
if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&priv->bands[IEEE80211_BAND_5GHZ];
ret = ieee80211_register_hw(priv->hw);
if (ret) {
IWL_ERROR("Failed to register hw (error %d)\n", ret);
return ret;
}
priv->mac80211_registered = 1;
return 0;
} }
EXPORT_SYMBOL(iwl_setup_mac);
static int iwlcore_init_drv(struct iwl_priv *priv) int iwl_init_drv(struct iwl_priv *priv)
{ {
int ret; int ret;
int i; int i;
...@@ -821,6 +835,9 @@ static int iwlcore_init_drv(struct iwl_priv *priv) ...@@ -821,6 +835,9 @@ static int iwlcore_init_drv(struct iwl_priv *priv)
/* Choose which receivers/antennas to use */ /* Choose which receivers/antennas to use */
iwl_set_rxon_chain(priv); iwl_set_rxon_chain(priv);
if (priv->cfg->mod_params->enable_qos)
priv->qos_data.qos_enable = 1;
iwl_reset_qos(priv); iwl_reset_qos(priv);
priv->qos_data.qos_active = 0; priv->qos_data.qos_active = 0;
...@@ -845,34 +862,22 @@ static int iwlcore_init_drv(struct iwl_priv *priv) ...@@ -845,34 +862,22 @@ static int iwlcore_init_drv(struct iwl_priv *priv)
goto err_free_channel_map; goto err_free_channel_map;
} }
ret = ieee80211_register_hw(priv->hw);
if (ret) {
IWL_ERROR("Failed to register network device (error %d)\n",
ret);
goto err_free_geos;
}
priv->hw->conf.beacon_int = 100;
priv->mac80211_registered = 1;
return 0; return 0;
err_free_geos:
iwlcore_free_geos(priv);
err_free_channel_map: err_free_channel_map:
iwl_free_channel_map(priv); iwl_free_channel_map(priv);
err: err:
return ret; return ret;
} }
EXPORT_SYMBOL(iwl_init_drv);
int iwl_setup(struct iwl_priv *priv) void iwl_uninit_drv(struct iwl_priv *priv)
{ {
int ret = 0; iwlcore_free_geos(priv);
iwlcore_init_hw(priv); iwl_free_channel_map(priv);
ret = iwlcore_init_drv(priv);
return ret;
} }
EXPORT_SYMBOL(iwl_setup); EXPORT_SYMBOL(iwl_uninit_drv);
/* Low level driver call this function to update iwlcore with /* Low level driver call this function to update iwlcore with
* driver status. * driver status.
......
...@@ -175,13 +175,13 @@ void iwl_set_rxon_chain(struct iwl_priv *priv); ...@@ -175,13 +175,13 @@ void iwl_set_rxon_chain(struct iwl_priv *priv);
int iwl_set_rxon_channel(struct iwl_priv *priv, int iwl_set_rxon_channel(struct iwl_priv *priv,
enum ieee80211_band band, enum ieee80211_band band,
u16 channel); u16 channel);
void iwlcore_free_geos(struct iwl_priv *priv);
int iwl_setup(struct iwl_priv *priv);
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info); void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info);
u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
struct ieee80211_ht_info *sta_ht_inf); struct ieee80211_ht_info *sta_ht_inf);
int iwl_hw_nic_init(struct iwl_priv *priv); int iwl_hw_nic_init(struct iwl_priv *priv);
int iwl_setup_mac(struct iwl_priv *priv);
int iwl_init_drv(struct iwl_priv *priv);
void iwl_uninit_drv(struct iwl_priv *priv);
/* "keep warm" functions */ /* "keep warm" functions */
int iwl_kw_init(struct iwl_priv *priv); int iwl_kw_init(struct iwl_priv *priv);
int iwl_kw_alloc(struct iwl_priv *priv); int iwl_kw_alloc(struct iwl_priv *priv);
......
...@@ -567,7 +567,6 @@ void iwl_free_channel_map(struct iwl_priv *priv) ...@@ -567,7 +567,6 @@ void iwl_free_channel_map(struct iwl_priv *priv)
kfree(priv->channel_info); kfree(priv->channel_info);
priv->channel_count = 0; priv->channel_count = 0;
} }
EXPORT_SYMBOL(iwl_free_channel_map);
/** /**
* iwl_get_channel_info - Find driver's private channel info * iwl_get_channel_info - Find driver's private channel info
......
...@@ -5878,10 +5878,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e ...@@ -5878,10 +5878,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
} }
/******************* /*******************
* 6. Setup hw/priv * 6. Setup priv
*******************/ *******************/
err = iwl_setup(priv); err = iwl_init_drv(priv);
if (err) if (err)
goto out_free_eeprom; goto out_free_eeprom;
/* At this point both hw and priv are initialized. */ /* 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,9 +5896,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_DEBUG_INFO("Radio disabled.\n"); IWL_DEBUG_INFO("Radio disabled.\n");
} }
if (priv->cfg->mod_params->enable_qos)
priv->qos_data.qos_enable = 1;
/******************** /********************
* 8. Setup services * 8. Setup services
********************/ ********************/
...@@ -5909,14 +5906,9 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e ...@@ -5909,14 +5906,9 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group); err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group);
if (err) { if (err) {
IWL_ERROR("failed to create sysfs device attributes\n"); IWL_ERROR("failed to create sysfs device attributes\n");
goto out_free_eeprom; goto out_uninit_drv;
} }
err = iwl_dbgfs_register(priv, DRV_NAME);
if (err) {
IWL_ERROR("failed to create debugfs files\n");
goto out_remove_sysfs;
}
iwl4965_setup_deferred_work(priv); iwl4965_setup_deferred_work(priv);
iwl4965_setup_rx_handlers(priv); 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,12 +5919,26 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_save_state(pdev); pci_save_state(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
/**********************************
* 10. Setup and register mac80211
**********************************/
err = iwl_setup_mac(priv);
if (err)
goto out_remove_sysfs;
err = iwl_dbgfs_register(priv, DRV_NAME);
if (err)
IWL_ERROR("failed to create debugfs files\n");
/* notify iwlcore to init */ /* notify iwlcore to init */
iwlcore_low_level_notify(priv, IWLCORE_INIT_EVT); iwlcore_low_level_notify(priv, IWLCORE_INIT_EVT);
return 0; return 0;
out_remove_sysfs: out_remove_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
out_uninit_drv:
iwl_uninit_drv(priv);
out_free_eeprom: out_free_eeprom:
iwl_eeprom_free(priv); iwl_eeprom_free(priv);
out_iounmap: out_iounmap:
...@@ -6014,8 +6020,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) ...@@ -6014,8 +6020,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
iwl_free_channel_map(priv); iwl_uninit_drv(priv);
iwlcore_free_geos(priv);
if (priv->ibss_beacon) if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon); dev_kfree_skb(priv->ibss_beacon);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册