[RFC] libertas: automatically scan and re-associate when loosing MAC association

Dan Williams dcbw at redhat.com
Mon Jul 23 07:52:06 EDT 2007


On Fri, 2007-07-06 at 10:10 -0400, Dan Williams wrote:
> On Fri, 2007-07-06 at 09:41 +0200, Holger Schurig wrote:
> > Don't free pending_assoc_req in the association worker, keep it
> > as is. Free pending_assoc_req at adapter removal time. That way
> > we always have an already filled-in assoc_req for reassociation.
> > 
> > When we get a MAC level event saying that we've been
> > de-associated, use the alredy filled in association record to
> > make a new scan and re-associate.
> 
> Looks good in principle.  However, let's rate-limit the reconnection
> rate.  That means, basically, that if the we've hit this
> reconnect-on-disconnect more than, say, 3 times in the past 5 seconds,
> we stop retrying.

Got an updated patch at all?

dan

> Dan
> 
> > Also moved wlan_postpone_association_work() and
> > wlan_cancel_association_work() from a *.h file to the sole user,
> > into wext.h. Renamed them to libertas_XXX as well.
> > 
> > Signed-off-by: Holger Schurig <hs4233 at mail.mn-solutions.de>
> > ---
> > 
> > I've marked this patch as RFC so that I can get comments on it.
> > 
> > * I'm not sure when to totally clear the assoc req, maybe at
> >   "ifconfig eth0 down" time?  Maybe it's not needed at all, e.g.
> >   if "iwconfig eth1 key XXX" sets the key and and
> >   "ethconfig eth1 key off" completely removes the key in the
> >   assoc-req, but I haven't checked this yet.
> > 
> > * maybe I should rename "pending_assoc_req" into
> >   "current_assoc_req" as well?
> > 
> >  drivers/net/wireless/libertas/assoc.c   |    2 -
> >  drivers/net/wireless/libertas/assoc.h   |   20 +-------------
> >  drivers/net/wireless/libertas/cmdresp.c |    6 ++++
> >  drivers/net/wireless/libertas/main.c    |   15 +++++-----
> >  drivers/net/wireless/libertas/wext.c    |   46 ++++++++++++++++++++-----------
> >  5 files changed, 45 insertions(+), 44 deletions(-)
> > 
> > diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
> > index ffeec2f..f785b79 100644
> > --- a/drivers/net/wireless/libertas/assoc.c
> > +++ b/drivers/net/wireless/libertas/assoc.c
> > @@ -486,7 +486,6 @@ void libertas_association_worker(struct work_struct *work)
> >  
> >  	mutex_lock(&adapter->lock);
> >  	assoc_req = adapter->pending_assoc_req;
> > -	adapter->pending_assoc_req = NULL;
> >  	adapter->in_progress_assoc_req = assoc_req;
> >  	mutex_unlock(&adapter->lock);
> >  
> > @@ -654,7 +653,6 @@ out:
> >  	mutex_lock(&adapter->lock);
> >  	adapter->in_progress_assoc_req = NULL;
> >  	mutex_unlock(&adapter->lock);
> > -	kfree(assoc_req);
> >  
> >  done:
> >  	lbs_deb_leave(LBS_DEB_ASSOC);
> > diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h
> > index 5e9c31f..929c9af 100644
> > --- a/drivers/net/wireless/libertas/assoc.h
> > +++ b/drivers/net/wireless/libertas/assoc.h
> > @@ -11,22 +11,4 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter);
> >  
> >  void libertas_sync_channel(struct work_struct *work);
> >  
> > -#define ASSOC_DELAY (HZ / 2)
> > -static inline void wlan_postpone_association_work(wlan_private *priv)
> > -{
> > -	if (priv->adapter->surpriseremoved)
> > -		return;
> > -	cancel_delayed_work(&priv->assoc_work);
> > -	queue_delayed_work(priv->assoc_thread, &priv->assoc_work, ASSOC_DELAY);
> > -}
> > -
> > -static inline void wlan_cancel_association_work(wlan_private *priv)
> > -{
> > -	cancel_delayed_work(&priv->assoc_work);
> > -	if (priv->adapter->pending_assoc_req) {
> > -		kfree(priv->adapter->pending_assoc_req);
> > -		priv->adapter->pending_assoc_req = NULL;
> > -	}
> > -}
> > -
> > -#endif /* _WLAN_ASSOC_H */
> > +#endif
> > diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
> > index 93bf63b..e29c46a 100644
> > --- a/drivers/net/wireless/libertas/cmdresp.c
> > +++ b/drivers/net/wireless/libertas/cmdresp.c
> > @@ -79,6 +79,12 @@ void libertas_mac_event_disconnected(wlan_private * priv)
> >  		lbs_deb_cmd("disconnected, so exit PS mode\n");
> >  		libertas_ps_wakeup(priv, 0);
> >  	}
> > +
> > +	if (adapter->pending_assoc_req) {
> > +		cancel_delayed_work(&priv->assoc_work);
> > +		queue_delayed_work(priv->assoc_thread, &priv->assoc_work, HZ / 4);
> > +	}
> > +
> >  	lbs_deb_leave(LBS_DEB_CMD);
> >  }
> >  
> > diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
> > index 9ccc952..3002d26 100644
> > --- a/drivers/net/wireless/libertas/main.c
> > +++ b/drivers/net/wireless/libertas/main.c
> > @@ -394,11 +394,17 @@ static int libertas_open(struct net_device *dev)
> >  static int libertas_dev_close(struct net_device *dev)
> >  {
> >  	wlan_private *priv = dev->priv;
> > +	wlan_adapter *adapter = priv->adapter;
> >  
> >  	lbs_deb_enter(LBS_DEB_NET);
> >  
> > -	netif_carrier_off(priv->dev);
> > +	mutex_lock(&adapter->lock);
> >  	priv->open = 0;
> > +	adapter->connect_status = LIBERTAS_DISCONNECTED;
> > +	kfree(adapter->pending_assoc_req);
> > +	adapter->pending_assoc_req = NULL;
> > +	mutex_unlock(&adapter->lock);
> > +	netif_carrier_off(priv->dev);
> >  
> >  	lbs_deb_leave(LBS_DEB_NET);
> >  	return 0;
> > @@ -947,15 +953,10 @@ static void libertas_free_adapter(wlan_private * priv)
> >  		return;
> >  	}
> >  
> > -	lbs_deb_fw("free command buffer\n");
> >  	libertas_free_cmd_buffer(priv);
> > -
> > -	lbs_deb_fw("free command_timer\n");
> >  	del_timer(&adapter->command_timer);
> > -
> > -	lbs_deb_fw("free scan results table\n");
> >  	kfree(adapter->networks);
> > -	adapter->networks = NULL;
> > +	kfree(adapter->pending_assoc_req);
> >  
> >  	/* Free the adapter object itself */
> >  	lbs_deb_fw("free adapter\n");
> > diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
> > index 5922321..fe88b8a 100644
> > --- a/drivers/net/wireless/libertas/wext.c
> > +++ b/drivers/net/wireless/libertas/wext.c
> > @@ -21,6 +21,20 @@
> >  #include "assoc.h"
> >  
> > 
> > +static inline void libertas_postpone_association_work(wlan_private *priv)
> > +{
> > +	if (priv->adapter->surpriseremoved)
> > +		return;
> > +	cancel_delayed_work(&priv->assoc_work);
> > +	queue_delayed_work(priv->assoc_thread, &priv->assoc_work, HZ / 2);
> > +}
> > +
> > +static inline void libertas_cancel_association_work(wlan_private *priv)
> > +{
> > +	cancel_delayed_work(&priv->assoc_work);
> > +}
> > +
> > +
> >  /**
> >   *  @brief Convert mw value to dbm value
> >   *
> > @@ -1024,9 +1038,9 @@ static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
> >  out:
> >  	if (ret == 0) {
> >  		set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags);
> > -		wlan_postpone_association_work(priv);
> > +		libertas_postpone_association_work(priv);
> >  	} else {
> > -		wlan_cancel_association_work(priv);
> > +		libertas_cancel_association_work(priv);
> >  	}
> >  	mutex_unlock(&adapter->lock);
> >  
> > @@ -1125,11 +1139,11 @@ static int wlan_set_mode(struct net_device *dev,
> >  	assoc_req = wlan_get_association_request(adapter);
> >  	if (!assoc_req) {
> >  		ret = -ENOMEM;
> > -		wlan_cancel_association_work(priv);
> > +		libertas_cancel_association_work(priv);
> >  	} else {
> >  		assoc_req->mode = *uwrq;
> >  		set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
> > -		wlan_postpone_association_work(priv);
> > +		libertas_postpone_association_work(priv);
> >  		lbs_deb_wext("Switching to mode: 0x%x\n", *uwrq);
> >  	}
> >  	mutex_unlock(&adapter->lock);
> > @@ -1410,9 +1424,9 @@ static int wlan_set_encode(struct net_device *dev,
> >  out:
> >  	if (ret == 0) {
> >  		set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
> > -		wlan_postpone_association_work(priv);
> > +		libertas_postpone_association_work(priv);
> >  	} else {
> > -		wlan_cancel_association_work(priv);
> > +		libertas_cancel_association_work(priv);
> >  	}
> >  	mutex_unlock(&adapter->lock);
> >  
> > @@ -1654,9 +1668,9 @@ static int wlan_set_encodeext(struct net_device *dev,
> >  
> >  out:
> >  	if (ret == 0) {
> > -		wlan_postpone_association_work(priv);
> > +		libertas_postpone_association_work(priv);
> >  	} else {
> > -		wlan_cancel_association_work(priv);
> > +		libertas_cancel_association_work(priv);
> >  	}
> >  	mutex_unlock(&adapter->lock);
> >  
> > @@ -1701,9 +1715,9 @@ static int wlan_set_genie(struct net_device *dev,
> >  out:
> >  	if (ret == 0) {
> >  		set_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags);
> > -		wlan_postpone_association_work(priv);
> > +		libertas_postpone_association_work(priv);
> >  	} else {
> > -		wlan_cancel_association_work(priv);
> > +		libertas_cancel_association_work(priv);
> >  	}
> >  	mutex_unlock(&adapter->lock);
> >  
> > @@ -1830,9 +1844,9 @@ out:
> >  	if (ret == 0) {
> >  		if (updated)
> >  			set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
> > -		wlan_postpone_association_work(priv);
> > +		libertas_postpone_association_work(priv);
> >  	} else if (ret != -EOPNOTSUPP) {
> > -		wlan_cancel_association_work(priv);
> > +		libertas_cancel_association_work(priv);
> >  	}
> >  	mutex_unlock(&adapter->lock);
> >  
> > @@ -2018,13 +2032,13 @@ out:
> >  			memcpy(&assoc_req->ssid, &ssid, IW_ESSID_MAX_SIZE);
> >  			assoc_req->ssid_len = ssid_len;
> >  			set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
> > -			wlan_postpone_association_work(priv);
> > +			libertas_postpone_association_work(priv);
> >  		}
> >  	}
> >  
> >  	/* Cancel the association request if there was an error */
> >  	if (ret != 0) {
> > -		wlan_cancel_association_work(priv);
> > +		libertas_cancel_association_work(priv);
> >  	}
> >  
> >  	mutex_unlock(&adapter->lock);
> > @@ -2062,13 +2076,13 @@ static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info,
> >  	/* Get or create the current association request */
> >  	assoc_req = wlan_get_association_request(adapter);
> >  	if (!assoc_req) {
> > -		wlan_cancel_association_work(priv);
> > +		libertas_cancel_association_work(priv);
> >  		ret = -ENOMEM;
> >  	} else {
> >  		/* Copy the BSSID to the association request */
> >  		memcpy(&assoc_req->bssid, awrq->sa_data, ETH_ALEN);
> >  		set_bit(ASSOC_FLAG_BSSID, &assoc_req->flags);
> > -		wlan_postpone_association_work(priv);
> > +		libertas_postpone_association_work(priv);
> >  	}
> >  
> >  	mutex_unlock(&adapter->lock);
> 
> 
> _______________________________________________
> libertas-dev mailing list
> libertas-dev at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/libertas-dev




More information about the libertas-dev mailing list