2013-01-31 13:05:41

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 1/2] mac80211: send deauth when connection is lost

From: Johannes Berg <[email protected]>

If the driver determines the connection is lost,
send a deauth frame to the AP anyway just in case
it still considers the connection alive. The frame
might not go through, but at least we've tried.

Signed-off-by: Johannes Berg <[email protected]>
---
net/mac80211/mlme.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 84b8afb..f93b98f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1821,8 +1821,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
}
EXPORT_SYMBOL(ieee80211_ap_probereq_get);

-static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata,
- bool transmit_frame)
+static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_local *local = sdata->local;
@@ -1836,7 +1835,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata,

ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
- transmit_frame, frame_buf);
+ true, frame_buf);
ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
mutex_unlock(&ifmgd->mtx);

@@ -1870,7 +1869,7 @@ static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) {
sdata_info(sdata, "Connection to AP %pM lost\n",
ifmgd->bssid);
- __ieee80211_disconnect(sdata, false);
+ __ieee80211_disconnect(sdata);
} else {
ieee80211_mgd_probe_ap(sdata, true);
}
@@ -1884,7 +1883,7 @@ static void ieee80211_csa_connection_drop_work(struct work_struct *work)

ieee80211_wake_queues_by_reason(&sdata->local->hw,
IEEE80211_QUEUE_STOP_REASON_CSA);
- __ieee80211_disconnect(sdata, true);
+ __ieee80211_disconnect(sdata);
}

void ieee80211_beacon_loss(struct ieee80211_vif *vif)
--
1.8.0



2013-01-31 13:05:41

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 2/2] mac80211: always allow calling ieee80211_connection_loss()

From: Johannes Berg <[email protected]>

With multi-channel, there's a corner case where a driver
doesn't receive a beacon soon enough to be able to sync
its timers with the AP. In this case, the only recovery
(after trying again) is to disconnect from the AP. Allow
calling ieee80211_connection_loss() for such cases. To
make that possible, modify the work function to not rely
on the IEEE80211_HW_CONNECTION_MONITOR flag but use new
state kept in the interface instead.

Signed-off-by: Johannes Berg <[email protected]>
---
include/net/mac80211.h | 2 ++
net/mac80211/ieee80211_i.h | 1 +
net/mac80211/mlme.c | 6 ++++--
3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 434f26d..1d3cbdc 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3882,6 +3882,8 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif);
* When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER, and
* %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver
* needs to inform if the connection to the AP has been lost.
+ * The function may also be called if the connection needs to be terminated
+ * for some other reason, even if %IEEE80211_HW_CONNECTION_MONITOR isn't set.
*
* This function will cause immediate change to disassociated state,
* without connection recovery attempts.
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index bb80190..4b71477 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -424,6 +424,7 @@ struct ieee80211_if_managed {
unsigned long probe_timeout;
int probe_send_count;
bool nullfunc_failed;
+ bool connection_loss;

struct mutex mtx;
struct cfg80211_bss *associated;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f93b98f..199969c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1866,7 +1866,7 @@ static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
rcu_read_unlock();
}

- if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) {
+ if (ifmgd->connection_loss) {
sdata_info(sdata, "Connection to AP %pM lost\n",
ifmgd->bssid);
__ieee80211_disconnect(sdata);
@@ -1894,6 +1894,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif)
trace_api_beacon_loss(sdata);

WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR);
+ sdata->u.mgd.connection_loss = false;
ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
}
EXPORT_SYMBOL(ieee80211_beacon_loss);
@@ -1905,7 +1906,7 @@ void ieee80211_connection_loss(struct ieee80211_vif *vif)

trace_api_connection_loss(sdata);

- WARN_ON(!(hw->flags & IEEE80211_HW_CONNECTION_MONITOR));
+ sdata->u.mgd.connection_loss = true;
ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
}
EXPORT_SYMBOL(ieee80211_connection_loss);
@@ -3121,6 +3122,7 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data)
if (local->quiescing)
return;

+ sdata->u.mgd.connection_loss = false;
ieee80211_queue_work(&sdata->local->hw,
&sdata->u.mgd.beacon_connection_loss_work);
}
--
1.8.0


2013-02-04 15:09:10

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/2] mac80211: always allow calling ieee80211_connection_loss()

On Thu, 2013-01-31 at 14:06 +0100, Johannes Berg wrote:
> From: Johannes Berg <[email protected]>
>
> With multi-channel, there's a corner case where a driver
> doesn't receive a beacon soon enough to be able to sync
> its timers with the AP. In this case, the only recovery
> (after trying again) is to disconnect from the AP. Allow
> calling ieee80211_connection_loss() for such cases. To
> make that possible, modify the work function to not rely
> on the IEEE80211_HW_CONNECTION_MONITOR flag but use new
> state kept in the interface instead.

Applied.

johannes


2013-02-04 15:08:54

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/2] mac80211: send deauth when connection is lost

On Thu, 2013-01-31 at 14:06 +0100, Johannes Berg wrote:
> From: Johannes Berg <[email protected]>
>
> If the driver determines the connection is lost,
> send a deauth frame to the AP anyway just in case
> it still considers the connection alive. The frame
> might not go through, but at least we've tried.

Applied.

johannes