diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 42 |
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 */ |
93 | static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd) | 93 | static 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 | ||
118 | static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata) | 118 | void 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 | ||
127 | void 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 | |||
127 | static int ecw2cw(int ecw) | 140 | static 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 | ||
1028 | static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | 1037 | static 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, |