Skip to content

Commit

Permalink
mac80211: always allow calling ieee80211_connection_loss()
Browse files Browse the repository at this point in the history
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 <johannes.berg@intel.com>
  • Loading branch information
Johannes Berg committed Feb 4, 2013
1 parent eef9e54 commit 682bd38
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 2 deletions.
2 changes: 2 additions & 0 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -3877,6 +3877,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.
Expand Down
1 change: 1 addition & 0 deletions net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,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;
Expand Down
6 changes: 4 additions & 2 deletions net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -1872,7 +1872,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);
Expand Down Expand Up @@ -1900,6 +1900,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);
Expand All @@ -1911,7 +1912,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);
Expand Down Expand Up @@ -3154,6 +3155,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);
}
Expand Down

0 comments on commit 682bd38

Please sign in to comment.