Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 2398

kernel-2.6.18-128.1.10.el5.src.rpm

From: John W. Linville <linville@redhat.com>
Date: Thu, 4 Dec 2008 14:48:05 -0500
Subject: [wireless] iwlwifi/mac80211: various small fixes
Message-id: 20081204194804.GA1951@redhat.com
O-Subject: [rhel5.3 patch] iwlwifi/mac80211: various small fixes
Bugzilla: 468967

This patch is an amalgamation of various small fixes that together
address the kernel side of the issue in bug 468967.

First, the mac80211 component is not notifying other stations when it leaves
a managed or ad-hoc network.  Not only is this bad etiquette, it also
can leave wpa_supplicant confused about the state of the network
connection.  We correct this by adding a specific deauthentication
request in ieee80211_stop.  I have sent an equivalent patch upstream.

Next, due to the use of a work queue, the mac80211 scan request handler has
no way to indicate that a scan has failed.  This is bad enough, but
at present a failed scan will leave the requestor waiting forever for
scan results.  This patch contains a fix to detect the scan failure
and issues an SIOWSCAN event so that at least the userland requestor
knows to stop waiting.  I (or Dan Williams, the original author)
will send an equivalent patch upstream.

Also, there is a simple fixup to fix a build problem when
CONFIG_IWLWIFI_DEBUG is selected (which we do not do in RHEL5).
It was discovered while investigating bug 468967 and is included
for completeness.

In addition this includes backported versions of the following fixes:

commit 3b7ee69d0caefbdb85a606a98bff841b8c63b97e
Author: Tomas Winkler <tomas.winkler@intel.com>
Date:   Mon Sep 8 17:33:38 2008 +0200

    mac80211: disassociate when moving to new BSS

    This patch makes the MLME cleanly disassociate from the current BSS
    when leaving it for a new one. This is not just nicer to the old AP
    (we're leaving it, might as well tell it!) but also required for some
    drivers that keep track of the station we're associated with, they'd
    get confused because they'd think we are associated with two APs.

    Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com>
    Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
    Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>

commit ce546fd2eacdbd8dc15f3d2ffd9a95661d082919
Author: Abhijeet Kolekar <abhijeet.kolekar@intel.com>
Date:   Wed Nov 19 15:32:22 2008 -0800

    iwl3945 : Fix ad-hoc mode for 3945

    Patch fixes the ad-hoc mode by
    1) Removing redundant clear_stations_table which prevented generation of
    beacons.
    2) Setting assoc_id to 1. It was never set so preventing tx flow
    in iwl3945_tx_skb.

    Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com>
    Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>

commit 2420ebc104d38567ee977a3c15dc675a9dd3b07c
Author: Mohamed Abbas <mohamed.abbas@intel.com>
Date:   Tue Nov 4 12:21:34 2008 -0800

    iwl3945: clear scanning bits upon failure

    This patch ensures we clear any scan status bit when
    an error occurs while sending the scan command. It is
    the implementation of patch:
    "iwlwifi: clear scanning bits upon failure"
    for iwl3945.

    Signed-off-by: Mohamed Abbas <mohamed.abbas@intel.com>
    Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>

commit 502c12e1ef14967e08dabb04c674cf0f000e8f7e
Author: Mohamed Abbas <mohamed.abbas@intel.com>
Date:   Thu Oct 23 23:48:54 2008 -0700

    iwlwifi: clear scanning bits upon failure

    In iwl_bg_request_scan function, if we could not send a
    scan command it will go to done.
    In done it does the right thing to call mac80211 with
    scan complete, but the problem is STATUS_SCAN_HW is still
    set causing any future scan to fail. Fix by clearing the scanning status
    bits if scan fails.

    Signed-off-by: Mohamed Abbas <mohamed.abbas@intel.com>
    Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>

Tested by Intel, Dan Williams, Zack Cerza and me with positive results.

diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index d2daa17..a9a91f0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -32,12 +32,12 @@
 #ifdef CONFIG_IWLWIFI_DEBUG
 #define IWL_DEBUG(level, fmt, args...) \
 do { if (priv->debug_level & (level)) \
-  dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
+  dev_printk(KERN_ERR, &(priv->pci_dev->dev), "%c %s " fmt, \
 	 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
 
 #define IWL_DEBUG_LIMIT(level, fmt, args...) \
 do { if ((priv->debug_level & (level)) && net_ratelimit()) \
-  dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
+  dev_printk(KERN_ERR, &(priv->pci_dev->dev), "%c %s " fmt, \
 	 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 4022bea..01a6faf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -900,6 +900,13 @@ static void iwl_bg_request_scan(void *p)
 	return;
 
  done:
+	/* Cannot perform scan. Make sure we clear scanning
+	* bits from status so next scan request can be performed.
+	* If we don't clear scanning status bit here all next scan
+	* will fail
+	*/
+	clear_bit(STATUS_SCAN_HW, &priv->status);
+	clear_bit(STATUS_SCANNING, &priv->status);
 	/* inform mac80211 scan aborted */
 	queue_work(priv->workqueue, &priv->scan_completed);
 	mutex_unlock(&priv->mutex);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 11dc792..fe77d2f 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -6273,6 +6273,14 @@ static void iwl3945_bg_request_scan(void *p)
 	return;
 
  done:
+	/* can not perform scan make sure we clear scanning
+	 * bits from status so next scan request can be performed.
+	 * if we dont clear scanning status bit here all next scan
+	 * will fail
+	*/
+	clear_bit(STATUS_SCAN_HW, &priv->status);
+	clear_bit(STATUS_SCANNING, &priv->status);
+
 	/* inform mac80211 scan aborted */
 	queue_work(priv->workqueue, &priv->scan_completed);
 	mutex_unlock(&priv->mutex);
@@ -6390,10 +6398,7 @@ static void iwl3945_bg_post_associate(void *p)
 
 	case IEEE80211_IF_TYPE_IBSS:
 
-		/* clear out the station table */
-		iwl3945_clear_stations_table(priv);
-
-		iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0);
+		priv->assoc_id = 1;
 		iwl3945_add_station(priv, priv->bssid, 0, 0);
 		iwl3945_sync_sta(priv, IWL_STA_ID,
 				 (priv->band == IEEE80211_BAND_5GHZ) ?
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d075c95..4e3cd34 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -509,9 +509,11 @@ static int ieee80211_stop(struct net_device *dev)
 		ieee80211_configure_filter(local);
 		netif_tx_unlock_bh(local->mdev);
 		break;
-	case IEEE80211_IF_TYPE_MESH_POINT:
 	case IEEE80211_IF_TYPE_STA:
 	case IEEE80211_IF_TYPE_IBSS:
+		/* Announce that we are leaving the network. */
+		ieee80211_sta_deauthenticate(dev, WLAN_REASON_DEAUTH_LEAVING);
+	case IEEE80211_IF_TYPE_MESH_POINT:
 		sdata->u.sta.state = IEEE80211_DISABLED;
 		memset(sdata->u.sta.bssid, 0, ETH_ALEN);
 		del_timer_sync(&sdata->u.sta.timer);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index cb91e08..5a83cce 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3317,10 +3317,16 @@ void ieee80211_sta_work(void *ptr)
 	if (ifsta->state != IEEE80211_AUTHENTICATE &&
 	    ifsta->state != IEEE80211_ASSOCIATE &&
 	    test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
+		int rc;
+
 		if (ifsta->scan_ssid_len)
-			ieee80211_sta_start_scan(dev, ifsta->scan_ssid, ifsta->scan_ssid_len);
+			rc = ieee80211_sta_start_scan(dev, ifsta->scan_ssid, ifsta->scan_ssid_len);
 		else
-			ieee80211_sta_start_scan(dev, NULL, 0);
+			rc = ieee80211_sta_start_scan(dev, NULL, 0);
+
+		if (rc)
+			ieee80211_scan_completed(local_to_hw(local));
+
 		return;
 	}
 
@@ -3410,9 +3416,13 @@ void ieee80211_sta_req_auth(struct net_device *dev,
 		return;
 
 	if ((ifsta->flags & (IEEE80211_STA_BSSID_SET |
-				IEEE80211_STA_AUTO_BSSID_SEL)) &&
+			     IEEE80211_STA_AUTO_BSSID_SEL)) &&
 	    (ifsta->flags & (IEEE80211_STA_SSID_SET |
-				IEEE80211_STA_AUTO_SSID_SEL))) {
+			     IEEE80211_STA_AUTO_SSID_SEL))) {
+
+		if (ifsta->state == IEEE80211_ASSOCIATED)
+			ieee80211_set_disassoc(dev, ifsta, 1);
+
 		set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
 		queue_work(local->hw.workqueue, &ifsta->work);
 	}