aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl4965-base.c
diff options
context:
space:
mode:
authorReinette Chatre <reinette.chatre@intel.com>2008-01-23 13:15:18 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-31 22:26:41 -0500
commit849e0dcea6b28a900e4743c1ada6db752fced5a9 (patch)
tree91abfca69729ef1b633012412012b7bf64f7610f /drivers/net/wireless/iwlwifi/iwl4965-base.c
parent75849d287ce5d75f3c79f153eaf74759ae95511f (diff)
iwlwifi: initialize geo/channel information during probe
The geo/channel information is obtained from the EEPROM, which is read during probe. We can thus set up channel information at this time. This helps us to support ioctl commands that rely on this before the interface is brought up. Clearly matches _init_channel_map with _free_channel_map and _init_geos with _free_geos to ensure functions calling these routines can also call their cleanup routines. Fixes a few bugs: - if channel information is not available when ioctl commands are issued then we get a NULL pointer oops. Having channel information set up during probe we can deal with ioctl commands without requiring interface to be brought up. This fixes bug: http://www.bughost.org/bugzilla/show_bug.cgi?id=1552 - Fix potential problem if user triggers probe/remove/probe sequence. The value of priv->channel_count was used to determine if channel map is set up. This value was never reset when channel map was removed. - Fix memory leak: priv->modes need to be freed when device removed. Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c54
1 files changed, 40 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index ac8967bc7c59..77c635287035 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -5576,6 +5576,15 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv)
5576 return 0; 5576 return 0;
5577} 5577}
5578 5578
5579/*
5580 * iwl4965_free_channel_map - undo allocations in iwl4965_init_channel_map
5581 */
5582static void iwl4965_free_channel_map(struct iwl4965_priv *priv)
5583{
5584 kfree(priv->channel_info);
5585 priv->channel_count = 0;
5586}
5587
5579/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after 5588/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
5580 * sending probe req. This should be set long enough to hear probe responses 5589 * sending probe req. This should be set long enough to hear probe responses
5581 * from more than one AP. */ 5590 * from more than one AP. */
@@ -5909,6 +5918,17 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv)
5909 return 0; 5918 return 0;
5910} 5919}
5911 5920
5921/*
5922 * iwl4965_free_geos - undo allocations in iwl4965_init_geos
5923 */
5924static void iwl4965_free_geos(struct iwl4965_priv *priv)
5925{
5926 kfree(priv->modes);
5927 kfree(priv->ieee_channels);
5928 kfree(priv->ieee_rates);
5929 clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
5930}
5931
5912/****************************************************************************** 5932/******************************************************************************
5913 * 5933 *
5914 * uCode download functions 5934 * uCode download functions
@@ -6560,15 +6580,6 @@ static void iwl4965_alive_start(struct iwl4965_priv *priv)
6560 /* Clear out the uCode error bit if it is set */ 6580 /* Clear out the uCode error bit if it is set */
6561 clear_bit(STATUS_FW_ERROR, &priv->status); 6581 clear_bit(STATUS_FW_ERROR, &priv->status);
6562 6582
6563 rc = iwl4965_init_channel_map(priv);
6564 if (rc) {
6565 IWL_ERROR("initializing regulatory failed: %d\n", rc);
6566 return;
6567 }
6568
6569 iwl4965_init_geos(priv);
6570 iwl4965_reset_channel_flag(priv);
6571
6572 if (iwl4965_is_rfkill(priv)) 6583 if (iwl4965_is_rfkill(priv))
6573 return; 6584 return;
6574 6585
@@ -9198,11 +9209,24 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
9198 IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr)); 9209 IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
9199 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); 9210 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
9200 9211
9212 err = iwl4965_init_channel_map(priv);
9213 if (err) {
9214 IWL_ERROR("initializing regulatory failed: %d\n", err);
9215 goto out_remove_sysfs;
9216 }
9217
9218 err = iwl4965_init_geos(priv);
9219 if (err) {
9220 IWL_ERROR("initializing geos failed: %d\n", err);
9221 goto out_free_channel_map;
9222 }
9223 iwl4965_reset_channel_flag(priv);
9224
9201 iwl4965_rate_control_register(priv->hw); 9225 iwl4965_rate_control_register(priv->hw);
9202 err = ieee80211_register_hw(priv->hw); 9226 err = ieee80211_register_hw(priv->hw);
9203 if (err) { 9227 if (err) {
9204 IWL_ERROR("Failed to register network device (error %d)\n", err); 9228 IWL_ERROR("Failed to register network device (error %d)\n", err);
9205 goto out_remove_sysfs; 9229 goto out_free_geos;
9206 } 9230 }
9207 9231
9208 priv->hw->conf.beacon_int = 100; 9232 priv->hw->conf.beacon_int = 100;
@@ -9212,6 +9236,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
9212 9236
9213 return 0; 9237 return 0;
9214 9238
9239 out_free_geos:
9240 iwl4965_free_geos(priv);
9241 out_free_channel_map:
9242 iwl4965_free_channel_map(priv);
9215 out_remove_sysfs: 9243 out_remove_sysfs:
9216 sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); 9244 sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
9217 9245
@@ -9286,10 +9314,8 @@ static void iwl4965_pci_remove(struct pci_dev *pdev)
9286 pci_disable_device(pdev); 9314 pci_disable_device(pdev);
9287 pci_set_drvdata(pdev, NULL); 9315 pci_set_drvdata(pdev, NULL);
9288 9316
9289 kfree(priv->channel_info); 9317 iwl4965_free_channel_map(priv);
9290 9318 iwl4965_free_geos(priv);
9291 kfree(priv->ieee_channels);
9292 kfree(priv->ieee_rates);
9293 9319
9294 if (priv->ibss_beacon) 9320 if (priv->ibss_beacon)
9295 dev_kfree_skb(priv->ibss_beacon); 9321 dev_kfree_skb(priv->ibss_beacon);