mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-13 01:08:50 +00:00
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>
This commit is contained in:
parent
445c2dff40
commit
6ba8795622
@ -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)
|
|||||||
/*
|
/*
|
||||||
* 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,
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
/* 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 */
|
||||||
}
|
|
||||||
|
|
||||||
static int iwlcore_init_drv(struct iwl_priv *priv)
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
|||||||
/* 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)
|
|||||||
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);
|
|||||||
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)
|
|||||||
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
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
* 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
|
|||||||
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
|
|||||||
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
|
|||||||
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)
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user