aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-01-29 07:13:50 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-04 10:09:58 -0500
commit682bd38b8ac1fa3e84e84cddd1f1d7eeebce1212 (patch)
treeb05470db358c1a0b86552e5f659a098fc2968bfa
parenteef9e54ce8b8dd08e281e0c399cced807c98959e (diff)
mac80211: always allow calling ieee80211_connection_loss()
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>
-rw-r--r--include/net/mac80211.h2
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/mlme.c6
3 files changed, 7 insertions, 2 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 164fd4b6503c..7da11211825d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3877,6 +3877,8 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif);
3877 * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER, and 3877 * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER, and
3878 * %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver 3878 * %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver
3879 * needs to inform if the connection to the AP has been lost. 3879 * needs to inform if the connection to the AP has been lost.
3880 * The function may also be called if the connection needs to be terminated
3881 * for some other reason, even if %IEEE80211_HW_CONNECTION_MONITOR isn't set.
3880 * 3882 *
3881 * This function will cause immediate change to disassociated state, 3883 * This function will cause immediate change to disassociated state,
3882 * without connection recovery attempts. 3884 * without connection recovery attempts.
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c9c66dec170a..25a0647ada8f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -391,6 +391,7 @@ struct ieee80211_if_managed {
391 unsigned long probe_timeout; 391 unsigned long probe_timeout;
392 int probe_send_count; 392 int probe_send_count;
393 bool nullfunc_failed; 393 bool nullfunc_failed;
394 bool connection_loss;
394 395
395 struct mutex mtx; 396 struct mutex mtx;
396 struct cfg80211_bss *associated; 397 struct cfg80211_bss *associated;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 756df39f1aba..5e188a5d812f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1872,7 +1872,7 @@ static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
1872 rcu_read_unlock(); 1872 rcu_read_unlock();
1873 } 1873 }
1874 1874
1875 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) { 1875 if (ifmgd->connection_loss) {
1876 sdata_info(sdata, "Connection to AP %pM lost\n", 1876 sdata_info(sdata, "Connection to AP %pM lost\n",
1877 ifmgd->bssid); 1877 ifmgd->bssid);
1878 __ieee80211_disconnect(sdata); 1878 __ieee80211_disconnect(sdata);
@@ -1900,6 +1900,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif)
1900 trace_api_beacon_loss(sdata); 1900 trace_api_beacon_loss(sdata);
1901 1901
1902 WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR); 1902 WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR);
1903 sdata->u.mgd.connection_loss = false;
1903 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work); 1904 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
1904} 1905}
1905EXPORT_SYMBOL(ieee80211_beacon_loss); 1906EXPORT_SYMBOL(ieee80211_beacon_loss);
@@ -1911,7 +1912,7 @@ void ieee80211_connection_loss(struct ieee80211_vif *vif)
1911 1912
1912 trace_api_connection_loss(sdata); 1913 trace_api_connection_loss(sdata);
1913 1914
1914 WARN_ON(!(hw->flags & IEEE80211_HW_CONNECTION_MONITOR)); 1915 sdata->u.mgd.connection_loss = true;
1915 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work); 1916 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
1916} 1917}
1917EXPORT_SYMBOL(ieee80211_connection_loss); 1918EXPORT_SYMBOL(ieee80211_connection_loss);
@@ -3154,6 +3155,7 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data)
3154 if (local->quiescing) 3155 if (local->quiescing)
3155 return; 3156 return;
3156 3157
3158 sdata->u.mgd.connection_loss = false;
3157 ieee80211_queue_work(&sdata->local->hw, 3159 ieee80211_queue_work(&sdata->local->hw,
3158 &sdata->u.mgd.beacon_connection_loss_work); 3160 &sdata->u.mgd.beacon_connection_loss_work);
3159} 3161}