Skip to content

Commit

Permalink
iwlwifi: refactor pci prob flow
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Tomas Winkler authored and John W. Linville committed May 22, 2008
1 parent 445c2df commit 6ba8795
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 45 deletions.
61 changes: 33 additions & 28 deletions drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,12 +518,6 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
priv->bands[IEEE80211_BAND_2GHZ].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);

Expand All @@ -533,13 +527,12 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
/*
* 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_rates);
clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
}
EXPORT_SYMBOL(iwlcore_free_geos);

#ifdef CONFIG_IWL4965_HT
static u8 is_single_rx_stream(struct iwl_priv *priv)
Expand Down Expand Up @@ -767,8 +760,9 @@ int iwl_set_rxon_channel(struct iwl_priv *priv,
}
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;
hw->rate_control_algorithm = "iwl-4965-rs";

Expand All @@ -782,9 +776,29 @@ static void iwlcore_init_hw(struct iwl_priv *priv)
/* Enhanced value; more queues, to support 11n aggregation */
hw->ampdu_queues = 12;
#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 i;
Expand Down Expand Up @@ -821,6 +835,9 @@ static int iwlcore_init_drv(struct iwl_priv *priv)
/* Choose which receivers/antennas to use */
iwl_set_rxon_chain(priv);

if (priv->cfg->mod_params->enable_qos)
priv->qos_data.qos_enable = 1;

iwl_reset_qos(priv);

priv->qos_data.qos_active = 0;
Expand All @@ -845,34 +862,22 @@ static int iwlcore_init_drv(struct iwl_priv *priv)
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;

err_free_geos:
iwlcore_free_geos(priv);
err_free_channel_map:
iwl_free_channel_map(priv);
err:
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_init_hw(priv);
ret = iwlcore_init_drv(priv);
return ret;
iwlcore_free_geos(priv);
iwl_free_channel_map(priv);
}
EXPORT_SYMBOL(iwl_setup);
EXPORT_SYMBOL(iwl_uninit_drv);

/* Low level driver call this function to update iwlcore with
* driver status.
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/wireless/iwlwifi/iwl-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,13 @@ void iwl_set_rxon_chain(struct iwl_priv *priv);
int iwl_set_rxon_channel(struct iwl_priv *priv,
enum ieee80211_band band,
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);
u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
struct ieee80211_ht_info *sta_ht_inf);
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 */
int iwl_kw_init(struct iwl_priv *priv);
int iwl_kw_alloc(struct iwl_priv *priv);
Expand Down
1 change: 0 additions & 1 deletion drivers/net/wireless/iwlwifi/iwl-eeprom.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,6 @@ void iwl_free_channel_map(struct iwl_priv *priv)
kfree(priv->channel_info);
priv->channel_count = 0;
}
EXPORT_SYMBOL(iwl_free_channel_map);

/**
* iwl_get_channel_info - Find driver's private channel info
Expand Down
31 changes: 18 additions & 13 deletions drivers/net/wireless/iwlwifi/iwl4965-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
goto out_free_eeprom;
/* At this point both hw and priv are initialized. */
Expand All @@ -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");
}

if (priv->cfg->mod_params->enable_qos)
priv->qos_data.qos_enable = 1;

/********************
* 8. Setup services
********************/
Expand All @@ -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);
if (err) {
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_rx_handlers(priv);
Expand All @@ -5927,12 +5919,26 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_save_state(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 */
iwlcore_low_level_notify(priv, IWLCORE_INIT_EVT);
return 0;

out_remove_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
out_uninit_drv:
iwl_uninit_drv(priv);
out_free_eeprom:
iwl_eeprom_free(priv);
out_iounmap:
Expand Down Expand Up @@ -6014,8 +6020,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);

iwl_free_channel_map(priv);
iwlcore_free_geos(priv);
iwl_uninit_drv(priv);

if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
Expand Down

0 comments on commit 6ba8795

Please sign in to comment.