From 5e46882e2ecacd2ebd1bfba3caaa4a25ffbcb94d Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Wed, 28 Jan 2009 09:38:30 -0800 Subject: [PATCH 1/2] iwlwifi: clean key table in iwl_clear_stations_table Cleans uCode key table bit map iwl_clear_stations_table since all stations are cleared also the key table must be. Since the keys are not removed properly on suspend by mac80211 this may result in exhausting key table on resume leading to memory corruption during removal Signed-off-by: Tomas Winkler Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-sta.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 412f66bac1a..70a8b21ca39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -480,6 +480,9 @@ void iwl_clear_stations_table(struct iwl_priv *priv) priv->num_stations = 0; memset(priv->stations, 0, sizeof(priv->stations)); + /* clean ucode key table bit map */ + priv->ucode_key_table = 0; + spin_unlock_irqrestore(&priv->sta_lock, flags); } EXPORT_SYMBOL(iwl_clear_stations_table); From c4e061ace75513aee227090486cc46dec7810c00 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Tue, 3 Feb 2009 10:20:03 -0800 Subject: [PATCH 2/2] iwlwifi: save PCI state before suspend, restore after resume This is the right thing to do and fixes the following warning: [ 115.012278] ------------[ cut here ]------------ [ 115.012281] WARNING: at drivers/pci/pci-driver.c:370 pci_legacy_suspend+0x85/0xc2() [ 115.012285] Hardware name: Latitude D630 [ 115.012301] PCI PM: Device state not saved by iwl3945_pci_suspend+0x0/0x4c [iwl3945] [ 115.012304] Modules linked in: fuse nfsd lockd nfs_acl auth_rpcgss exportfs sunrpc ipv6 acpi_cpufreq kvm_intel kvm snd_hda_codec_idt snd_hda_intel snd_hda_codec snd_hwdep arc4 snd_seq_device snd_pcm_oss snd_mixer_oss ecb snd_pcm cryptomgr aead snd_timer crypto_blkcipher snd snd_page_alloc ohci1394 crypto_hash crypto_algapi ch341 ieee1394 usbserial thermal iwl3945 mac80211 led_class lib80211 tg3 processor i2c_i801 i2c_core sg cfg80211 libphy usbhid battery ac button sr_mod cdrom evdev dcdbas ata_generic ata_piix libata sd_mod scsi_mod ext3 jbd mbcache uhci_hcd ohci_hcd ehci_hcd usbcore [last unloaded: microcode] [ 115.012374] Pid: 4163, comm: pm-suspend Not tainted 2.6.29-rc3-00227-gf1dd849-dirty #67 [ 115.012377] Call Trace: [ 115.012382] [] warn_slowpath+0xb1/0xed [ 115.012387] [] ? _spin_unlock_irqrestore+0x5c/0x78 [ 115.012390] [] ? up+0x34/0x39 [ 115.012394] [] ? acpi_ut_release_mutex+0x5d/0x61 [ 115.012397] [] ? acpi_get_data+0x5e/0x70 [ 115.012400] [] ? acpi_bus_get_device+0x25/0x39 [ 115.012403] [] ? acpi_bus_power_manageable+0x11/0x29 [ 115.012406] [] ? acpi_pci_power_manageable+0x17/0x19 [ 115.012410] [] ? pci_set_power_state+0xcc/0x101 [ 115.012418] [] ? iwl3945_pci_suspend+0x0/0x4c [iwl3945] [ 115.012422] [] pci_legacy_suspend+0x85/0xc2 [ 115.012425] [] pci_pm_suspend+0x34/0x86 [ 115.012429] [] pm_op+0x52/0xe5 [ 115.012432] [] device_suspend+0x32a/0x451 [ 115.012436] [] suspend_devices_and_enter+0x3e/0x13a [ 115.012439] [] enter_state+0x110/0x164 [ 115.012442] [] state_store+0xb7/0xd7 [ 115.012446] [] kobj_attr_store+0x17/0x19 [ 115.012449] [] sysfs_write_file+0xe4/0x119 [ 115.012453] [] vfs_write+0xae/0x137 [ 115.012456] [] sys_write+0x47/0x70 [ 115.012459] [] system_call_fastpath+0x16/0x1b [ 115.012467] ---[ end trace 829828966f6f24dc ]--- Signed-off-by: Reinette Chatre Tested-by: Ming Lei Cc: Rafael J. Wysocki Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 ++ drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b35c8813bef..c01ea48da5f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4042,6 +4042,7 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) priv->is_open = 1; } + pci_save_state(pdev); pci_set_power_state(pdev, PCI_D3hot); return 0; @@ -4052,6 +4053,7 @@ static int iwl_pci_resume(struct pci_dev *pdev) struct iwl_priv *priv = pci_get_drvdata(pdev); pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); if (priv->is_open) iwl_mac_start(priv->hw); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 95d01984c80..5b44d322b99 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -8143,6 +8143,7 @@ static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state) priv->is_open = 1; } + pci_save_state(pdev); pci_set_power_state(pdev, PCI_D3hot); return 0; @@ -8153,6 +8154,7 @@ static int iwl3945_pci_resume(struct pci_dev *pdev) struct iwl3945_priv *priv = pci_get_drvdata(pdev); pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); if (priv->is_open) iwl3945_mac_start(priv->hw);