aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-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/iwl3945-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/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c54
1 files changed, 40 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 0bfb925ebda8..f96a1a2e90f4 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -5146,6 +5146,15 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
5146 return 0; 5146 return 0;
5147} 5147}
5148 5148
5149/*
5150 * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map
5151 */
5152static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
5153{
5154 kfree(priv->channel_info);
5155 priv->channel_count = 0;
5156}
5157
5149/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after 5158/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
5150 * sending probe req. This should be set long enough to hear probe responses 5159 * sending probe req. This should be set long enough to hear probe responses
5151 * from more than one AP. */ 5160 * from more than one AP. */
@@ -5471,6 +5480,17 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
5471 return 0; 5480 return 0;
5472} 5481}
5473 5482
5483/*
5484 * iwl3945_free_geos - undo allocations in iwl3945_init_geos
5485 */
5486static void iwl3945_free_geos(struct iwl3945_priv *priv)
5487{
5488 kfree(priv->modes);
5489 kfree(priv->ieee_channels);
5490 kfree(priv->ieee_rates);
5491 clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
5492}
5493
5474/****************************************************************************** 5494/******************************************************************************
5475 * 5495 *
5476 * uCode download functions 5496 * uCode download functions
@@ -6130,15 +6150,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
6130 /* Clear out the uCode error bit if it is set */ 6150 /* Clear out the uCode error bit if it is set */
6131 clear_bit(STATUS_FW_ERROR, &priv->status); 6151 clear_bit(STATUS_FW_ERROR, &priv->status);
6132 6152
6133 rc = iwl3945_init_channel_map(priv);
6134 if (rc) {
6135 IWL_ERROR("initializing regulatory failed: %d\n", rc);
6136 return;
6137 }
6138
6139 iwl3945_init_geos(priv);
6140 iwl3945_reset_channel_flag(priv);
6141
6142 if (iwl3945_is_rfkill(priv)) 6153 if (iwl3945_is_rfkill(priv))
6143 return; 6154 return;
6144 6155
@@ -8614,11 +8625,24 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8614 IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr)); 8625 IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
8615 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); 8626 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
8616 8627
8628 err = iwl3945_init_channel_map(priv);
8629 if (err) {
8630 IWL_ERROR("initializing regulatory failed: %d\n", err);
8631 goto out_remove_sysfs;
8632 }
8633
8634 err = iwl3945_init_geos(priv);
8635 if (err) {
8636 IWL_ERROR("initializing geos failed: %d\n", err);
8637 goto out_free_channel_map;
8638 }
8639 iwl3945_reset_channel_flag(priv);
8640
8617 iwl3945_rate_control_register(priv->hw); 8641 iwl3945_rate_control_register(priv->hw);
8618 err = ieee80211_register_hw(priv->hw); 8642 err = ieee80211_register_hw(priv->hw);
8619 if (err) { 8643 if (err) {
8620 IWL_ERROR("Failed to register network device (error %d)\n", err); 8644 IWL_ERROR("Failed to register network device (error %d)\n", err);
8621 goto out_remove_sysfs; 8645 goto out_free_geos;
8622 } 8646 }
8623 8647
8624 priv->hw->conf.beacon_int = 100; 8648 priv->hw->conf.beacon_int = 100;
@@ -8628,6 +8652,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8628 8652
8629 return 0; 8653 return 0;
8630 8654
8655 out_free_geos:
8656 iwl3945_free_geos(priv);
8657 out_free_channel_map:
8658 iwl3945_free_channel_map(priv);
8631 out_remove_sysfs: 8659 out_remove_sysfs:
8632 sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); 8660 sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
8633 8661
@@ -8702,10 +8730,8 @@ static void iwl3945_pci_remove(struct pci_dev *pdev)
8702 pci_disable_device(pdev); 8730 pci_disable_device(pdev);
8703 pci_set_drvdata(pdev, NULL); 8731 pci_set_drvdata(pdev, NULL);
8704 8732
8705 kfree(priv->channel_info); 8733 iwl3945_free_channel_map(priv);
8706 8734 iwl3945_free_geos(priv);
8707 kfree(priv->ieee_channels);
8708 kfree(priv->ieee_rates);
8709 8735
8710 if (priv->ibss_beacon) 8736 if (priv->ibss_beacon)
8711 dev_kfree_skb(priv->ibss_beacon); 8737 dev_kfree_skb(priv->ibss_beacon);