[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