aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211_i.h20
-rw-r--r--net/mac80211/mlme.c257
-rw-r--r--net/mac80211/rx.c22
3 files changed, 227 insertions, 72 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 06b3411530f2..a34bca2dc52f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -256,12 +256,13 @@ struct ieee80211_mgd_work {
256 256
257/* flags used in struct ieee80211_if_managed.flags */ 257/* flags used in struct ieee80211_if_managed.flags */
258enum ieee80211_sta_flags { 258enum ieee80211_sta_flags {
259 IEEE80211_STA_PROBEREQ_POLL = BIT(3), 259 IEEE80211_STA_BEACON_POLL = BIT(0),
260 IEEE80211_STA_CONTROL_PORT = BIT(4), 260 IEEE80211_STA_CONNECTION_POLL = BIT(1),
261 IEEE80211_STA_WMM_ENABLED = BIT(5), 261 IEEE80211_STA_CONTROL_PORT = BIT(2),
262 IEEE80211_STA_DISABLE_11N = BIT(6), 262 IEEE80211_STA_WMM_ENABLED = BIT(3),
263 IEEE80211_STA_CSA_RECEIVED = BIT(7), 263 IEEE80211_STA_DISABLE_11N = BIT(4),
264 IEEE80211_STA_MFP_ENABLED = BIT(8), 264 IEEE80211_STA_CSA_RECEIVED = BIT(5),
265 IEEE80211_STA_MFP_ENABLED = BIT(6),
265}; 266};
266 267
267/* flags for MLME request */ 268/* flags for MLME request */
@@ -271,11 +272,16 @@ enum ieee80211_sta_request {
271 272
272struct ieee80211_if_managed { 273struct ieee80211_if_managed {
273 struct timer_list timer; 274 struct timer_list timer;
275 struct timer_list conn_mon_timer;
276 struct timer_list bcn_mon_timer;
274 struct timer_list chswitch_timer; 277 struct timer_list chswitch_timer;
275 struct work_struct work; 278 struct work_struct work;
279 struct work_struct monitor_work;
276 struct work_struct chswitch_work; 280 struct work_struct chswitch_work;
277 struct work_struct beacon_loss_work; 281 struct work_struct beacon_loss_work;
278 282
283 unsigned long probe_timeout;
284
279 struct mutex mtx; 285 struct mutex mtx;
280 struct ieee80211_bss *associated; 286 struct ieee80211_bss *associated;
281 struct list_head work_list; 287 struct list_head work_list;
@@ -292,8 +298,6 @@ struct ieee80211_if_managed {
292 298
293 unsigned long request; 299 unsigned long request;
294 300
295 unsigned long last_beacon;
296
297 unsigned int flags; 301 unsigned int flags;
298 302
299 u32 beacon_crc; 303 u32 beacon_crc;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c1114bb8095b..18dad229344c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -31,8 +31,23 @@
31#define IEEE80211_AUTH_MAX_TRIES 3 31#define IEEE80211_AUTH_MAX_TRIES 3
32#define IEEE80211_ASSOC_TIMEOUT (HZ / 5) 32#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
33#define IEEE80211_ASSOC_MAX_TRIES 3 33#define IEEE80211_ASSOC_MAX_TRIES 3
34#define IEEE80211_MONITORING_INTERVAL (2 * HZ) 34
35#define IEEE80211_PROBE_WAIT (HZ / 5) 35/*
36 * beacon loss detection timeout
37 * XXX: should depend on beacon interval
38 */
39#define IEEE80211_BEACON_LOSS_TIME (2 * HZ)
40/*
41 * Time the connection can be idle before we probe
42 * it to see if we can still talk to the AP.
43 */
44#define IEEE80211_CONNECTION_IDLE_TIME (2 * HZ)
45/*
46 * Time we wait for a probe response after sending
47 * a probe request because of beacon loss or for
48 * checking the connection still works.
49 */
50#define IEEE80211_PROBE_WAIT (HZ / 5)
36 51
37#define TMR_RUNNING_TIMER 0 52#define TMR_RUNNING_TIMER 0
38#define TMR_RUNNING_CHANSW 1 53#define TMR_RUNNING_CHANSW 1
@@ -92,6 +107,15 @@ static void run_again(struct ieee80211_if_managed *ifmgd,
92 mod_timer(&ifmgd->timer, timeout); 107 mod_timer(&ifmgd->timer, timeout);
93} 108}
94 109
110static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata)
111{
112 if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER)
113 return;
114
115 mod_timer(&sdata->u.mgd.bcn_mon_timer,
116 round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME));
117}
118
95static int ecw2cw(int ecw) 119static int ecw2cw(int ecw)
96{ 120{
97 return (1 << ecw) - 1; 121 return (1 << ecw) - 1;
@@ -666,7 +690,8 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
666 690
667 if (count == 1 && found->u.mgd.powersave && 691 if (count == 1 && found->u.mgd.powersave &&
668 found->u.mgd.associated && list_empty(&found->u.mgd.work_list) && 692 found->u.mgd.associated && list_empty(&found->u.mgd.work_list) &&
669 !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) { 693 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
694 IEEE80211_STA_CONNECTION_POLL))) {
670 s32 beaconint_us; 695 s32 beaconint_us;
671 696
672 if (latency < 0) 697 if (latency < 0)
@@ -872,6 +897,10 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
872 sdata->u.mgd.associated = bss; 897 sdata->u.mgd.associated = bss;
873 memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN); 898 memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN);
874 899
900 /* just to be sure */
901 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
902 IEEE80211_STA_BEACON_POLL);
903
875 ieee80211_led_assoc(local, 1); 904 ieee80211_led_assoc(local, 1);
876 905
877 sdata->vif.bss_conf.assoc = 1; 906 sdata->vif.bss_conf.assoc = 1;
@@ -983,16 +1012,21 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
983 return RX_MGMT_NONE; 1012 return RX_MGMT_NONE;
984} 1013}
985 1014
986static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, 1015static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
987 const u8 *bssid, bool deauth)
988{ 1016{
989 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1017 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
990 struct ieee80211_local *local = sdata->local; 1018 struct ieee80211_local *local = sdata->local;
991 struct sta_info *sta; 1019 struct sta_info *sta;
992 u32 changed = 0, config_changed = 0; 1020 u32 changed = 0, config_changed = 0;
1021 u8 bssid[ETH_ALEN];
993 1022
994 ASSERT_MGD_MTX(ifmgd); 1023 ASSERT_MGD_MTX(ifmgd);
995 1024
1025 if (WARN_ON(!ifmgd->associated))
1026 return;
1027
1028 memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN);
1029
996 ifmgd->associated = NULL; 1030 ifmgd->associated = NULL;
997 memset(ifmgd->bssid, 0, ETH_ALEN); 1031 memset(ifmgd->bssid, 0, ETH_ALEN);
998 1032
@@ -1112,32 +1146,22 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1112 * from AP because we know that the connection is working both ways 1146 * from AP because we know that the connection is working both ways
1113 * at that time. But multicast frames (and hence also beacons) must 1147 * at that time. But multicast frames (and hence also beacons) must
1114 * be ignored here, because we need to trigger the timer during 1148 * be ignored here, because we need to trigger the timer during
1115 * data idle periods for sending the periodical probe request to 1149 * data idle periods for sending the periodic probe request to the
1116 * the AP. 1150 * AP we're connected to.
1117 */ 1151 */
1118 if (!is_multicast_ether_addr(hdr->addr1)) 1152 if (is_multicast_ether_addr(hdr->addr1))
1119 mod_timer(&sdata->u.mgd.timer, 1153 return;
1120 jiffies + IEEE80211_MONITORING_INTERVAL); 1154
1155 mod_timer(&sdata->u.mgd.conn_mon_timer,
1156 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
1121} 1157}
1122 1158
1123void ieee80211_beacon_loss_work(struct work_struct *work) 1159static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
1160 bool beacon)
1124{ 1161{
1125 struct ieee80211_sub_if_data *sdata =
1126 container_of(work, struct ieee80211_sub_if_data,
1127 u.mgd.beacon_loss_work);
1128 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1162 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1129 const u8 *ssid; 1163 const u8 *ssid;
1130 1164 bool already = false;
1131 /*
1132 * The driver has already reported this event and we have
1133 * already sent a probe request. Maybe the AP died and the
1134 * driver keeps reporting until we disassociate... We have
1135 * to ignore that because otherwise we would continually
1136 * reset the timer and never check whether we received a
1137 * probe response!
1138 */
1139 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL)
1140 return;
1141 1165
1142 mutex_lock(&ifmgd->mtx); 1166 mutex_lock(&ifmgd->mtx);
1143 1167
@@ -1145,12 +1169,35 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
1145 goto out; 1169 goto out;
1146 1170
1147#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1171#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1148 if (net_ratelimit()) 1172 if (beacon && net_ratelimit())
1149 printk(KERN_DEBUG "%s: driver reports beacon loss from AP " 1173 printk(KERN_DEBUG "%s: detected beacon loss from AP "
1150 "- sending probe request\n", sdata->dev->name); 1174 "- sending probe request\n", sdata->dev->name);
1151#endif 1175#endif
1152 1176
1153 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; 1177 /*
1178 * The driver/our work has already reported this event or the
1179 * connection monitoring has kicked in and we have already sent
1180 * a probe request. Or maybe the AP died and the driver keeps
1181 * reporting until we disassociate...
1182 *
1183 * In either case we have to ignore the current call to this
1184 * function (except for setting the correct probe reason bit)
1185 * because otherwise we would reset the timer every time and
1186 * never check whether we received a probe response!
1187 */
1188 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
1189 IEEE80211_STA_CONNECTION_POLL))
1190 already = true;
1191
1192 if (beacon)
1193 ifmgd->flags |= IEEE80211_STA_BEACON_POLL;
1194 else
1195 ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;
1196
1197 if (already)
1198 goto out;
1199
1200 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
1154 1201
1155 mutex_lock(&sdata->local->iflist_mtx); 1202 mutex_lock(&sdata->local->iflist_mtx);
1156 ieee80211_recalc_ps(sdata->local, -1); 1203 ieee80211_recalc_ps(sdata->local, -1);
@@ -1160,11 +1207,21 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
1160 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, 1207 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid,
1161 ssid + 2, ssid[1], NULL, 0); 1208 ssid + 2, ssid[1], NULL, 0);
1162 1209
1163 run_again(ifmgd, jiffies + IEEE80211_PROBE_WAIT); 1210 run_again(ifmgd, ifmgd->probe_timeout);
1211
1164 out: 1212 out:
1165 mutex_unlock(&ifmgd->mtx); 1213 mutex_unlock(&ifmgd->mtx);
1166} 1214}
1167 1215
1216void ieee80211_beacon_loss_work(struct work_struct *work)
1217{
1218 struct ieee80211_sub_if_data *sdata =
1219 container_of(work, struct ieee80211_sub_if_data,
1220 u.mgd.beacon_loss_work);
1221
1222 ieee80211_mgd_probe_ap(sdata, true);
1223}
1224
1168void ieee80211_beacon_loss(struct ieee80211_vif *vif) 1225void ieee80211_beacon_loss(struct ieee80211_vif *vif)
1169{ 1226{
1170 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 1227 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
@@ -1278,7 +1335,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1278 sdata->dev->name, bssid, reason_code); 1335 sdata->dev->name, bssid, reason_code);
1279 1336
1280 if (!wk) { 1337 if (!wk) {
1281 ieee80211_set_disassoc(sdata, bssid, true); 1338 ieee80211_set_disassoc(sdata);
1282 } else { 1339 } else {
1283 list_del(&wk->list); 1340 list_del(&wk->list);
1284 kfree(wk); 1341 kfree(wk);
@@ -1311,7 +1368,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1311 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n", 1368 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n",
1312 sdata->dev->name, reason_code); 1369 sdata->dev->name, reason_code);
1313 1370
1314 ieee80211_set_disassoc(sdata, ifmgd->associated->cbss.bssid, false); 1371 ieee80211_set_disassoc(sdata);
1315 return RX_MGMT_CFG80211_DISASSOC; 1372 return RX_MGMT_CFG80211_DISASSOC;
1316} 1373}
1317 1374
@@ -1412,9 +1469,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1412 return RX_MGMT_NONE; 1469 return RX_MGMT_NONE;
1413 } 1470 }
1414 1471
1415 /* update new sta with its last rx activity */
1416 sta->last_rx = jiffies;
1417
1418 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | 1472 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC |
1419 WLAN_STA_ASSOC_AP); 1473 WLAN_STA_ASSOC_AP);
1420 if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) 1474 if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
@@ -1517,10 +1571,11 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1517 ieee80211_set_associated(sdata, wk->bss, changed); 1571 ieee80211_set_associated(sdata, wk->bss, changed);
1518 1572
1519 /* 1573 /*
1520 * initialise the time of last beacon to be the association time, 1574 * Start timer to probe the connection to the AP now.
1521 * otherwise beacon loss check will trigger immediately 1575 * Also start the timer that will detect beacon loss.
1522 */ 1576 */
1523 ifmgd->last_beacon = jiffies; 1577 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
1578 mod_beacon_timer(sdata);
1524 1579
1525 list_del(&wk->list); 1580 list_del(&wk->list);
1526 kfree(wk); 1581 kfree(wk);
@@ -1604,11 +1659,22 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1604 1659
1605 if (ifmgd->associated && 1660 if (ifmgd->associated &&
1606 memcmp(mgmt->bssid, ifmgd->associated->cbss.bssid, ETH_ALEN) == 0 && 1661 memcmp(mgmt->bssid, ifmgd->associated->cbss.bssid, ETH_ALEN) == 0 &&
1607 ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) { 1662 ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
1608 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; 1663 IEEE80211_STA_CONNECTION_POLL)) {
1664 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
1665 IEEE80211_STA_BEACON_POLL);
1609 mutex_lock(&sdata->local->iflist_mtx); 1666 mutex_lock(&sdata->local->iflist_mtx);
1610 ieee80211_recalc_ps(sdata->local, -1); 1667 ieee80211_recalc_ps(sdata->local, -1);
1611 mutex_unlock(&sdata->local->iflist_mtx); 1668 mutex_unlock(&sdata->local->iflist_mtx);
1669 /*
1670 * We've received a probe response, but are not sure whether
1671 * we have or will be receiving any beacons or data, so let's
1672 * schedule the timers again, just in case.
1673 */
1674 mod_beacon_timer(sdata);
1675 mod_timer(&ifmgd->conn_mon_timer,
1676 round_jiffies_up(jiffies +
1677 IEEE80211_CONNECTION_IDLE_TIME));
1612 } 1678 }
1613} 1679}
1614 1680
@@ -1658,27 +1724,41 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1658 if (rx_status->freq != local->hw.conf.channel->center_freq) 1724 if (rx_status->freq != local->hw.conf.channel->center_freq)
1659 return; 1725 return;
1660 1726
1661 if (WARN_ON(!ifmgd->associated)) 1727 /*
1728 * We might have received a number of frames, among them a
1729 * disassoc frame and a beacon...
1730 */
1731 if (!ifmgd->associated)
1662 return; 1732 return;
1663 1733
1664 bssid = ifmgd->associated->cbss.bssid; 1734 bssid = ifmgd->associated->cbss.bssid;
1665 1735
1666 if (WARN_ON(memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)) 1736 /*
1737 * And in theory even frames from a different AP we were just
1738 * associated to a split-second ago!
1739 */
1740 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
1667 return; 1741 return;
1668 1742
1669 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) { 1743 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
1670#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1744#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1671 if (net_ratelimit()) { 1745 if (net_ratelimit()) {
1672 printk(KERN_DEBUG "%s: cancelling probereq poll due " 1746 printk(KERN_DEBUG "%s: cancelling probereq poll due "
1673 "to a received beacon\n", sdata->dev->name); 1747 "to a received beacon\n", sdata->dev->name);
1674 } 1748 }
1675#endif 1749#endif
1676 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; 1750 ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
1677 mutex_lock(&local->iflist_mtx); 1751 mutex_lock(&local->iflist_mtx);
1678 ieee80211_recalc_ps(local, -1); 1752 ieee80211_recalc_ps(local, -1);
1679 mutex_unlock(&local->iflist_mtx); 1753 mutex_unlock(&local->iflist_mtx);
1680 } 1754 }
1681 1755
1756 /*
1757 * Push the beacon loss detection into the future since
1758 * we are processing a beacon from the AP just now.
1759 */
1760 mod_beacon_timer(sdata);
1761
1682 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); 1762 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
1683 ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, 1763 ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
1684 len - baselen, &elems, 1764 len - baselen, &elems,
@@ -1980,6 +2060,37 @@ static void ieee80211_sta_work(struct work_struct *work)
1980 /* then process the rest of the work */ 2060 /* then process the rest of the work */
1981 mutex_lock(&ifmgd->mtx); 2061 mutex_lock(&ifmgd->mtx);
1982 2062
2063 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
2064 IEEE80211_STA_CONNECTION_POLL) &&
2065 ifmgd->associated) {
2066 if (time_is_after_jiffies(ifmgd->probe_timeout))
2067 run_again(ifmgd, ifmgd->probe_timeout);
2068 else {
2069 u8 bssid[ETH_ALEN];
2070 /*
2071 * We actually lost the connection ... or did we?
2072 * Let's make sure!
2073 */
2074 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
2075 IEEE80211_STA_BEACON_POLL);
2076 memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN);
2077 printk(KERN_DEBUG "No probe response from AP %pM"
2078 " after %dms, disconnecting.\n",
2079 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
2080 ieee80211_set_disassoc(sdata);
2081 mutex_unlock(&ifmgd->mtx);
2082 /*
2083 * must be outside lock due to cfg80211,
2084 * but that's not a problem.
2085 */
2086 ieee80211_send_deauth_disassoc(sdata, bssid,
2087 IEEE80211_STYPE_DEAUTH,
2088 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
2089 NULL);
2090 mutex_lock(&ifmgd->mtx);
2091 }
2092 }
2093
1983 list_for_each_entry(wk, &ifmgd->work_list, list) { 2094 list_for_each_entry(wk, &ifmgd->work_list, list) {
1984 if (wk->state != IEEE80211_MGD_STATE_IDLE) { 2095 if (wk->state != IEEE80211_MGD_STATE_IDLE) {
1985 anybusy = true; 2096 anybusy = true;
@@ -2067,15 +2178,51 @@ static void ieee80211_sta_work(struct work_struct *work)
2067 ieee80211_recalc_idle(local); 2178 ieee80211_recalc_idle(local);
2068} 2179}
2069 2180
2181static void ieee80211_sta_bcn_mon_timer(unsigned long data)
2182{
2183 struct ieee80211_sub_if_data *sdata =
2184 (struct ieee80211_sub_if_data *) data;
2185 struct ieee80211_local *local = sdata->local;
2186
2187 if (local->quiescing)
2188 return;
2189
2190 queue_work(sdata->local->hw.workqueue,
2191 &sdata->u.mgd.beacon_loss_work);
2192}
2193
2194static void ieee80211_sta_conn_mon_timer(unsigned long data)
2195{
2196 struct ieee80211_sub_if_data *sdata =
2197 (struct ieee80211_sub_if_data *) data;
2198 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2199 struct ieee80211_local *local = sdata->local;
2200
2201 if (local->quiescing)
2202 return;
2203
2204 queue_work(local->hw.workqueue, &ifmgd->monitor_work);
2205}
2206
2207static void ieee80211_sta_monitor_work(struct work_struct *work)
2208{
2209 struct ieee80211_sub_if_data *sdata =
2210 container_of(work, struct ieee80211_sub_if_data,
2211 u.mgd.monitor_work);
2212
2213 ieee80211_mgd_probe_ap(sdata, false);
2214}
2215
2070static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) 2216static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
2071{ 2217{
2072 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 2218 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
2073 /* 2219 sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL |
2074 * Need to update last_beacon to avoid beacon loss 2220 IEEE80211_STA_CONNECTION_POLL);
2075 * test to trigger.
2076 */
2077 sdata->u.mgd.last_beacon = jiffies;
2078 2221
2222 /* let's probe the connection once */
2223 queue_work(sdata->local->hw.workqueue,
2224 &sdata->u.mgd.monitor_work);
2225 /* and do all the other regular work too */
2079 queue_work(sdata->local->hw.workqueue, 2226 queue_work(sdata->local->hw.workqueue,
2080 &sdata->u.mgd.work); 2227 &sdata->u.mgd.work);
2081 } 2228 }
@@ -2100,6 +2247,11 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
2100 cancel_work_sync(&ifmgd->chswitch_work); 2247 cancel_work_sync(&ifmgd->chswitch_work);
2101 if (del_timer_sync(&ifmgd->chswitch_timer)) 2248 if (del_timer_sync(&ifmgd->chswitch_timer))
2102 set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); 2249 set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
2250
2251 cancel_work_sync(&ifmgd->monitor_work);
2252 /* these will just be re-established on connection */
2253 del_timer_sync(&ifmgd->conn_mon_timer);
2254 del_timer_sync(&ifmgd->bcn_mon_timer);
2103} 2255}
2104 2256
2105void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) 2257void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
@@ -2120,10 +2272,15 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
2120 2272
2121 ifmgd = &sdata->u.mgd; 2273 ifmgd = &sdata->u.mgd;
2122 INIT_WORK(&ifmgd->work, ieee80211_sta_work); 2274 INIT_WORK(&ifmgd->work, ieee80211_sta_work);
2275 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
2123 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); 2276 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
2124 INIT_WORK(&ifmgd->beacon_loss_work, ieee80211_beacon_loss_work); 2277 INIT_WORK(&ifmgd->beacon_loss_work, ieee80211_beacon_loss_work);
2125 setup_timer(&ifmgd->timer, ieee80211_sta_timer, 2278 setup_timer(&ifmgd->timer, ieee80211_sta_timer,
2126 (unsigned long) sdata); 2279 (unsigned long) sdata);
2280 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer,
2281 (unsigned long) sdata);
2282 setup_timer(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer,
2283 (unsigned long) sdata);
2127 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, 2284 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer,
2128 (unsigned long) sdata); 2285 (unsigned long) sdata);
2129 skb_queue_head_init(&ifmgd->skb_queue); 2286 skb_queue_head_init(&ifmgd->skb_queue);
@@ -2323,7 +2480,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2323 2480
2324 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) { 2481 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) {
2325 bssid = req->bss->bssid; 2482 bssid = req->bss->bssid;
2326 ieee80211_set_disassoc(sdata, bssid, true); 2483 ieee80211_set_disassoc(sdata);
2327 } else list_for_each_entry(wk, &ifmgd->work_list, list) { 2484 } else list_for_each_entry(wk, &ifmgd->work_list, list) {
2328 if (&wk->bss->cbss == req->bss) { 2485 if (&wk->bss->cbss == req->bss) {
2329 bssid = req->bss->bssid; 2486 bssid = req->bss->bssid;
@@ -2365,7 +2522,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2365 return -ENOLINK; 2522 return -ENOLINK;
2366 } 2523 }
2367 2524
2368 ieee80211_set_disassoc(sdata, req->bss->bssid, false); 2525 ieee80211_set_disassoc(sdata);
2369 2526
2370 mutex_unlock(&ifmgd->mtx); 2527 mutex_unlock(&ifmgd->mtx);
2371 2528
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fe6b99059531..b513fb791153 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -833,28 +833,22 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
833 if (!sta) 833 if (!sta)
834 return RX_CONTINUE; 834 return RX_CONTINUE;
835 835
836 /* Update last_rx only for IBSS packets which are for the current 836 /*
837 * BSSID to avoid keeping the current IBSS network alive in cases where 837 * Update last_rx only for IBSS packets which are for the current
838 * other STAs are using different BSSID. */ 838 * BSSID to avoid keeping the current IBSS network alive in cases
839 * where other STAs start using different BSSID.
840 */
839 if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) { 841 if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) {
840 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, 842 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len,
841 NL80211_IFTYPE_ADHOC); 843 NL80211_IFTYPE_ADHOC);
842 if (compare_ether_addr(bssid, rx->sdata->u.ibss.bssid) == 0) 844 if (compare_ether_addr(bssid, rx->sdata->u.ibss.bssid) == 0)
843 sta->last_rx = jiffies; 845 sta->last_rx = jiffies;
844 } else 846 } else if (!is_multicast_ether_addr(hdr->addr1)) {
845 if (!is_multicast_ether_addr(hdr->addr1) || 847 /*
846 rx->sdata->vif.type == NL80211_IFTYPE_STATION) {
847 /* Update last_rx only for unicast frames in order to prevent
848 * the Probe Request frames (the only broadcast frames from a
849 * STA in infrastructure mode) from keeping a connection alive.
850 * Mesh beacons will update last_rx when if they are found to 848 * Mesh beacons will update last_rx when if they are found to
851 * match the current local configuration when processed. 849 * match the current local configuration when processed.
852 */ 850 */
853 if (rx->sdata->vif.type == NL80211_IFTYPE_STATION && 851 sta->last_rx = jiffies;
854 ieee80211_is_beacon(hdr->frame_control)) {
855 rx->sdata->u.mgd.last_beacon = jiffies;
856 } else
857 sta->last_rx = jiffies;
858 } 852 }
859 853
860 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 854 if (!(rx->flags & IEEE80211_RX_RA_MATCH))