[PATCH] normalize ipw3945 association behaviour

Alexander Sack asac at jwsdot.com
Fri Sep 7 14:37:07 UTC 2007


Hi,

here a patch ment to fix multiple association issues for the
ipw3945 driver (version 1.2.1 and 1.2.2). Please comment and if there
are no hard issues with it, please update gutsy lum asap ... if we
have good experience with this, we should consider to update feisty
module as well.

Here what the patch does:

 * bumps module version ...

 * if essid is set to ANY/OFF, honour the assocate module
   configuration and don't forget about it. (so interpret ANY/OFF as
   OFF if associate=0 and ANY if associate=1.

 * if essid is set to the same value the driver is currently
   associated with, explicitly send association event to user space.

 * always associate explicitly if essid has changed.

 - Alexander


(patch against 1.2.2 upstream sources)

=== modified file 'ipw3945.c'
--- ipw3945.c	2007-09-04 11:06:26 +0000
+++ ipw3945.c	2007-09-04 11:12:08 +0000
@@ -97,17 +97,17 @@
 #endif
 
 #ifdef CONFIG_IPW3945_QOS
 #define VQ "q"
 #else
 #define VQ
 #endif
 
-#define IPW3945_VERSION "1.2.2" VD VM VP VR VQ
+#define IPW3945_VERSION "1.2.2" VD VM VP VR VQ ".ubuntu1"
 
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 3945 Network Connection driver for Linux"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2006 Intel Corporation"
 #define DRV_VERSION     IPW3945_VERSION
 
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR(DRV_COPYRIGHT);
@@ -12218,44 +12218,52 @@ static int ipw_wx_set_essid(struct net_d
 	if (wrqu->essid.flags && wrqu->essid.length) {
 		length = wrqu->essid.length - IW_ESSID_FIX;
 		essid = extra;
 	}
 
 	if (length == 0) {
 		IPW_DEBUG_WX("Setting ESSID to ANY\n");
 		priv->config &= ~CFG_STATIC_ESSID;
-		priv->config |= CFG_ASSOCIATE;
-		if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
+		if((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))
+			&& !(priv->config & CFG_ASSOCIATE)) {
+			IPW_DEBUG_ASSOC
+			    ("Deassociating because OFF/ANY set with auto association"
+				" disabled.\n");
+			ipw_disassociate(priv);
+		}
+		if ((priv->config & CFG_ASSOCIATE) &&
+			!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
 			IPW_DEBUG_ASSOC
 			    ("Attempting to associate with new "
-			     "parameters.\n");
+			     "parameters because auto association is enabled.\n");
 			ipw_associate(priv);
 		}
 		mutex_unlock(&priv->mutex);
 		return 0;
 	}
 
 	length = min(length, IW_ESSID_MAX_SIZE);
 	priv->config |= CFG_STATIC_ESSID;
 	if (priv->essid_len == length && !memcmp(priv->essid, extra, length)
 	    && (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
 		IPW_DEBUG_WX("ESSID set to current ESSID.\n");
+		queue_work(priv->workqueue, &priv->link_up);
 		mutex_unlock(&priv->mutex);
 		return 0;
 	}
 
 	IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n",
 		     escape_essid(essid, length), length);
 	priv->essid_len = length;
 	memcpy(priv->essid, essid, priv->essid_len);
 	/* Network configuration changed -- force [re]association */
 	IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
-	if (!ipw_disassociate(priv))
-		ipw_associate(priv);
+	ipw_disassociate(priv);
+	ipw_associate(priv);
 
 	mutex_unlock(&priv->mutex);
 	return 0;
 }
 
 static int ipw_wx_get_essid(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)









More information about the kernel-team mailing list