[RFC] libertas: automatically scan and re-associate when loosing MAC association
Dan Williams
dcbw at redhat.com
Fri Jul 6 10:10:38 EDT 2007
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.
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);
More information about the libertas-dev
mailing list