aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 0cb822cc12e..8b733cf6f3e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -92,7 +92,7 @@ enum rx_mgmt_action {
92/* utils */ 92/* utils */
93static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd) 93static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
94{ 94{
95 WARN_ON(!mutex_is_locked(&ifmgd->mtx)); 95 lockdep_assert_held(&ifmgd->mtx);
96} 96}
97 97
98/* 98/*
@@ -115,7 +115,7 @@ static void run_again(struct ieee80211_if_managed *ifmgd,
115 mod_timer(&ifmgd->timer, timeout); 115 mod_timer(&ifmgd->timer, timeout);
116} 116}
117 117
118static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata) 118void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
119{ 119{
120 if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER) 120 if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER)
121 return; 121 return;
@@ -124,6 +124,19 @@ static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata)
124 round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME)); 124 round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME));
125} 125}
126 126
127void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
128{
129 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
130
131 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
132 return;
133
134 mod_timer(&sdata->u.mgd.conn_mon_timer,
135 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
136
137 ifmgd->probe_send_count = 0;
138}
139
127static int ecw2cw(int ecw) 140static int ecw2cw(int ecw)
128{ 141{
129 return (1 << ecw) - 1; 142 return (1 << ecw) - 1;
@@ -1018,21 +1031,26 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1018 if (is_multicast_ether_addr(hdr->addr1)) 1031 if (is_multicast_ether_addr(hdr->addr1))
1019 return; 1032 return;
1020 1033
1021 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) 1034 ieee80211_sta_reset_conn_monitor(sdata);
1022 return;
1023
1024 mod_timer(&sdata->u.mgd.conn_mon_timer,
1025 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
1026} 1035}
1027 1036
1028static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) 1037static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1029{ 1038{
1030 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1039 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1031 const u8 *ssid; 1040 const u8 *ssid;
1041 u8 *dst = ifmgd->associated->bssid;
1042 u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3);
1043
1044 /*
1045 * Try sending broadcast probe requests for the last three
1046 * probe requests after the first ones failed since some
1047 * buggy APs only support broadcast probe requests.
1048 */
1049 if (ifmgd->probe_send_count >= unicast_limit)
1050 dst = NULL;
1032 1051
1033 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); 1052 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
1034 ieee80211_send_probe_req(sdata, ifmgd->associated->bssid, 1053 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
1035 ssid + 2, ssid[1], NULL, 0);
1036 1054
1037 ifmgd->probe_send_count++; 1055 ifmgd->probe_send_count++;
1038 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; 1056 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
@@ -1381,7 +1399,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1381 * Also start the timer that will detect beacon loss. 1399 * Also start the timer that will detect beacon loss.
1382 */ 1400 */
1383 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); 1401 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
1384 mod_beacon_timer(sdata); 1402 ieee80211_sta_reset_beacon_monitor(sdata);
1385 1403
1386 return true; 1404 return true;
1387} 1405}
@@ -1484,7 +1502,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1484 * we have or will be receiving any beacons or data, so let's 1502 * we have or will be receiving any beacons or data, so let's
1485 * schedule the timers again, just in case. 1503 * schedule the timers again, just in case.
1486 */ 1504 */
1487 mod_beacon_timer(sdata); 1505 ieee80211_sta_reset_beacon_monitor(sdata);
1488 1506
1489 mod_timer(&ifmgd->conn_mon_timer, 1507 mod_timer(&ifmgd->conn_mon_timer,
1490 round_jiffies_up(jiffies + 1508 round_jiffies_up(jiffies +
@@ -1610,7 +1628,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1610 * Push the beacon loss detection into the future since 1628 * Push the beacon loss detection into the future since
1611 * we are processing a beacon from the AP just now. 1629 * we are processing a beacon from the AP just now.
1612 */ 1630 */
1613 mod_beacon_timer(sdata); 1631 ieee80211_sta_reset_beacon_monitor(sdata);
1614 1632
1615 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); 1633 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
1616 ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, 1634 ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,