diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 113 |
1 files changed, 61 insertions, 52 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index ee83125ed179..6d5a1ee0445f 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -31,6 +31,7 @@ | |||
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_MAX_PROBE_TRIES 5 | ||
34 | 35 | ||
35 | /* | 36 | /* |
36 | * beacon loss detection timeout | 37 | * beacon loss detection timeout |
@@ -41,13 +42,13 @@ | |||
41 | * Time the connection can be idle before we probe | 42 | * Time the connection can be idle before we probe |
42 | * it to see if we can still talk to the AP. | 43 | * it to see if we can still talk to the AP. |
43 | */ | 44 | */ |
44 | #define IEEE80211_CONNECTION_IDLE_TIME (2 * HZ) | 45 | #define IEEE80211_CONNECTION_IDLE_TIME (30 * HZ) |
45 | /* | 46 | /* |
46 | * Time we wait for a probe response after sending | 47 | * Time we wait for a probe response after sending |
47 | * a probe request because of beacon loss or for | 48 | * a probe request because of beacon loss or for |
48 | * checking the connection still works. | 49 | * checking the connection still works. |
49 | */ | 50 | */ |
50 | #define IEEE80211_PROBE_WAIT (HZ / 5) | 51 | #define IEEE80211_PROBE_WAIT (HZ / 2) |
51 | 52 | ||
52 | #define TMR_RUNNING_TIMER 0 | 53 | #define TMR_RUNNING_TIMER 0 |
53 | #define TMR_RUNNING_CHANSW 1 | 54 | #define TMR_RUNNING_CHANSW 1 |
@@ -565,7 +566,7 @@ static void ieee80211_chswitch_timer(unsigned long data) | |||
565 | return; | 566 | return; |
566 | } | 567 | } |
567 | 568 | ||
568 | queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work); | 569 | ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work); |
569 | } | 570 | } |
570 | 571 | ||
571 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | 572 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, |
@@ -597,7 +598,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
597 | sdata->local->csa_channel = new_ch; | 598 | sdata->local->csa_channel = new_ch; |
598 | 599 | ||
599 | if (sw_elem->count <= 1) { | 600 | if (sw_elem->count <= 1) { |
600 | queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work); | 601 | ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work); |
601 | } else { | 602 | } else { |
602 | ieee80211_stop_queues_by_reason(&sdata->local->hw, | 603 | ieee80211_stop_queues_by_reason(&sdata->local->hw, |
603 | IEEE80211_QUEUE_STOP_REASON_CSA); | 604 | IEEE80211_QUEUE_STOP_REASON_CSA); |
@@ -763,7 +764,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data) | |||
763 | if (local->quiescing || local->suspended) | 764 | if (local->quiescing || local->suspended) |
764 | return; | 765 | return; |
765 | 766 | ||
766 | queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); | 767 | ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work); |
767 | } | 768 | } |
768 | 769 | ||
769 | /* MLME */ | 770 | /* MLME */ |
@@ -916,12 +917,9 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
916 | 917 | ||
917 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); | 918 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); |
918 | 919 | ||
919 | /* will be same as sdata */ | 920 | mutex_lock(&local->iflist_mtx); |
920 | if (local->ps_sdata) { | 921 | ieee80211_recalc_ps(local, -1); |
921 | mutex_lock(&local->iflist_mtx); | 922 | mutex_unlock(&local->iflist_mtx); |
922 | ieee80211_recalc_ps(local, -1); | ||
923 | mutex_unlock(&local->iflist_mtx); | ||
924 | } | ||
925 | 923 | ||
926 | netif_tx_start_all_queues(sdata->dev); | 924 | netif_tx_start_all_queues(sdata->dev); |
927 | netif_carrier_on(sdata->dev); | 925 | netif_carrier_on(sdata->dev); |
@@ -950,7 +948,7 @@ ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | |||
950 | * due to work needing to be done. Hence, queue the STAs work | 948 | * due to work needing to be done. Hence, queue the STAs work |
951 | * again for that. | 949 | * again for that. |
952 | */ | 950 | */ |
953 | queue_work(local->hw.workqueue, &ifmgd->work); | 951 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
954 | return RX_MGMT_CFG80211_AUTH_TO; | 952 | return RX_MGMT_CFG80211_AUTH_TO; |
955 | } | 953 | } |
956 | 954 | ||
@@ -995,7 +993,7 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, | |||
995 | * due to work needing to be done. Hence, queue the STAs work | 993 | * due to work needing to be done. Hence, queue the STAs work |
996 | * again for that. | 994 | * again for that. |
997 | */ | 995 | */ |
998 | queue_work(local->hw.workqueue, &ifmgd->work); | 996 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
999 | return RX_MGMT_CFG80211_AUTH_TO; | 997 | return RX_MGMT_CFG80211_AUTH_TO; |
1000 | } | 998 | } |
1001 | 999 | ||
@@ -1124,7 +1122,7 @@ ieee80211_associate(struct ieee80211_sub_if_data *sdata, | |||
1124 | * due to work needing to be done. Hence, queue the STAs work | 1122 | * due to work needing to be done. Hence, queue the STAs work |
1125 | * again for that. | 1123 | * again for that. |
1126 | */ | 1124 | */ |
1127 | queue_work(local->hw.workqueue, &ifmgd->work); | 1125 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
1128 | return RX_MGMT_CFG80211_ASSOC_TO; | 1126 | return RX_MGMT_CFG80211_ASSOC_TO; |
1129 | } | 1127 | } |
1130 | 1128 | ||
@@ -1156,11 +1154,24 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | |||
1156 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); | 1154 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); |
1157 | } | 1155 | } |
1158 | 1156 | ||
1157 | static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | ||
1158 | { | ||
1159 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
1160 | const u8 *ssid; | ||
1161 | |||
1162 | ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID); | ||
1163 | ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, | ||
1164 | ssid + 2, ssid[1], NULL, 0); | ||
1165 | |||
1166 | ifmgd->probe_send_count++; | ||
1167 | ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; | ||
1168 | run_again(ifmgd, ifmgd->probe_timeout); | ||
1169 | } | ||
1170 | |||
1159 | static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | 1171 | static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, |
1160 | bool beacon) | 1172 | bool beacon) |
1161 | { | 1173 | { |
1162 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1174 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1163 | const u8 *ssid; | ||
1164 | bool already = false; | 1175 | bool already = false; |
1165 | 1176 | ||
1166 | if (!netif_running(sdata->dev)) | 1177 | if (!netif_running(sdata->dev)) |
@@ -1203,18 +1214,12 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
1203 | if (already) | 1214 | if (already) |
1204 | goto out; | 1215 | goto out; |
1205 | 1216 | ||
1206 | ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; | ||
1207 | |||
1208 | mutex_lock(&sdata->local->iflist_mtx); | 1217 | mutex_lock(&sdata->local->iflist_mtx); |
1209 | ieee80211_recalc_ps(sdata->local, -1); | 1218 | ieee80211_recalc_ps(sdata->local, -1); |
1210 | mutex_unlock(&sdata->local->iflist_mtx); | 1219 | mutex_unlock(&sdata->local->iflist_mtx); |
1211 | 1220 | ||
1212 | ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID); | 1221 | ifmgd->probe_send_count = 0; |
1213 | ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, | 1222 | ieee80211_mgd_probe_ap_send(sdata); |
1214 | ssid + 2, ssid[1], NULL, 0); | ||
1215 | |||
1216 | run_again(ifmgd, ifmgd->probe_timeout); | ||
1217 | |||
1218 | out: | 1223 | out: |
1219 | mutex_unlock(&ifmgd->mtx); | 1224 | mutex_unlock(&ifmgd->mtx); |
1220 | } | 1225 | } |
@@ -1232,8 +1237,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif) | |||
1232 | { | 1237 | { |
1233 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 1238 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
1234 | 1239 | ||
1235 | queue_work(sdata->local->hw.workqueue, | 1240 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); |
1236 | &sdata->u.mgd.beacon_loss_work); | ||
1237 | } | 1241 | } |
1238 | EXPORT_SYMBOL(ieee80211_beacon_loss); | 1242 | EXPORT_SYMBOL(ieee80211_beacon_loss); |
1239 | 1243 | ||
@@ -1570,6 +1574,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1570 | wk->bss->cbss.bssid, | 1574 | wk->bss->cbss.bssid, |
1571 | ap_ht_cap_flags); | 1575 | ap_ht_cap_flags); |
1572 | 1576 | ||
1577 | /* delete work item -- must be before set_associated for PS */ | ||
1578 | list_del(&wk->list); | ||
1579 | |||
1573 | /* set AID and assoc capability, | 1580 | /* set AID and assoc capability, |
1574 | * ieee80211_set_associated() will tell the driver */ | 1581 | * ieee80211_set_associated() will tell the driver */ |
1575 | bss_conf->aid = aid; | 1582 | bss_conf->aid = aid; |
@@ -1583,7 +1590,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1583 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); | 1590 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); |
1584 | mod_beacon_timer(sdata); | 1591 | mod_beacon_timer(sdata); |
1585 | 1592 | ||
1586 | list_del(&wk->list); | ||
1587 | kfree(wk); | 1593 | kfree(wk); |
1588 | return RX_MGMT_CFG80211_ASSOC; | 1594 | return RX_MGMT_CFG80211_ASSOC; |
1589 | } | 1595 | } |
@@ -1847,12 +1853,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1847 | bssid, ap_ht_cap_flags); | 1853 | bssid, ap_ht_cap_flags); |
1848 | } | 1854 | } |
1849 | 1855 | ||
1856 | /* Note: country IE parsing is done for us by cfg80211 */ | ||
1850 | if (elems.country_elem) { | 1857 | if (elems.country_elem) { |
1851 | /* Note we are only reviewing this on beacons | ||
1852 | * for the BSSID we are associated to */ | ||
1853 | regulatory_hint_11d(local->hw.wiphy, | ||
1854 | elems.country_elem, elems.country_elem_len); | ||
1855 | |||
1856 | /* TODO: IBSS also needs this */ | 1858 | /* TODO: IBSS also needs this */ |
1857 | if (elems.pwr_constr_elem) | 1859 | if (elems.pwr_constr_elem) |
1858 | ieee80211_handle_pwr_constr(sdata, | 1860 | ieee80211_handle_pwr_constr(sdata, |
@@ -1888,7 +1890,7 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1888 | case IEEE80211_STYPE_DISASSOC: | 1890 | case IEEE80211_STYPE_DISASSOC: |
1889 | case IEEE80211_STYPE_ACTION: | 1891 | case IEEE80211_STYPE_ACTION: |
1890 | skb_queue_tail(&sdata->u.mgd.skb_queue, skb); | 1892 | skb_queue_tail(&sdata->u.mgd.skb_queue, skb); |
1891 | queue_work(local->hw.workqueue, &sdata->u.mgd.work); | 1893 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); |
1892 | return RX_QUEUED; | 1894 | return RX_QUEUED; |
1893 | } | 1895 | } |
1894 | 1896 | ||
@@ -2026,7 +2028,7 @@ static void ieee80211_sta_timer(unsigned long data) | |||
2026 | return; | 2028 | return; |
2027 | } | 2029 | } |
2028 | 2030 | ||
2029 | queue_work(local->hw.workqueue, &ifmgd->work); | 2031 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
2030 | } | 2032 | } |
2031 | 2033 | ||
2032 | static void ieee80211_sta_work(struct work_struct *work) | 2034 | static void ieee80211_sta_work(struct work_struct *work) |
@@ -2051,13 +2053,11 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2051 | return; | 2053 | return; |
2052 | 2054 | ||
2053 | /* | 2055 | /* |
2054 | * Nothing should have been stuffed into the workqueue during | 2056 | * ieee80211_queue_work() should have picked up most cases, |
2055 | * the suspend->resume cycle. If this WARN is seen then there | 2057 | * here we'll pick the the rest. |
2056 | * is a bug with either the driver suspend or something in | ||
2057 | * mac80211 stuffing into the workqueue which we haven't yet | ||
2058 | * cleared during mac80211's suspend cycle. | ||
2059 | */ | 2058 | */ |
2060 | if (WARN_ON(local->suspended)) | 2059 | if (WARN(local->suspended, "STA MLME work scheduled while " |
2060 | "going to suspend\n")) | ||
2061 | return; | 2061 | return; |
2062 | 2062 | ||
2063 | ifmgd = &sdata->u.mgd; | 2063 | ifmgd = &sdata->u.mgd; |
@@ -2072,17 +2072,27 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2072 | if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | 2072 | if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | |
2073 | IEEE80211_STA_CONNECTION_POLL) && | 2073 | IEEE80211_STA_CONNECTION_POLL) && |
2074 | ifmgd->associated) { | 2074 | ifmgd->associated) { |
2075 | u8 bssid[ETH_ALEN]; | ||
2076 | |||
2077 | memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN); | ||
2075 | if (time_is_after_jiffies(ifmgd->probe_timeout)) | 2078 | if (time_is_after_jiffies(ifmgd->probe_timeout)) |
2076 | run_again(ifmgd, ifmgd->probe_timeout); | 2079 | run_again(ifmgd, ifmgd->probe_timeout); |
2077 | else { | 2080 | |
2078 | u8 bssid[ETH_ALEN]; | 2081 | else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { |
2082 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
2083 | printk(KERN_DEBUG "No probe response from AP %pM" | ||
2084 | " after %dms, try %d\n", bssid, | ||
2085 | (1000 * IEEE80211_PROBE_WAIT)/HZ, | ||
2086 | ifmgd->probe_send_count); | ||
2087 | #endif | ||
2088 | ieee80211_mgd_probe_ap_send(sdata); | ||
2089 | } else { | ||
2079 | /* | 2090 | /* |
2080 | * We actually lost the connection ... or did we? | 2091 | * We actually lost the connection ... or did we? |
2081 | * Let's make sure! | 2092 | * Let's make sure! |
2082 | */ | 2093 | */ |
2083 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 2094 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | |
2084 | IEEE80211_STA_BEACON_POLL); | 2095 | IEEE80211_STA_BEACON_POLL); |
2085 | memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN); | ||
2086 | printk(KERN_DEBUG "No probe response from AP %pM" | 2096 | printk(KERN_DEBUG "No probe response from AP %pM" |
2087 | " after %dms, disconnecting.\n", | 2097 | " after %dms, disconnecting.\n", |
2088 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); | 2098 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); |
@@ -2113,9 +2123,9 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2113 | mutex_unlock(&ifmgd->mtx); | 2123 | mutex_unlock(&ifmgd->mtx); |
2114 | 2124 | ||
2115 | if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) | 2125 | if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) |
2116 | queue_delayed_work(local->hw.workqueue, | 2126 | ieee80211_queue_delayed_work(&local->hw, |
2117 | &local->scan_work, | 2127 | &local->scan_work, |
2118 | round_jiffies_relative(0)); | 2128 | round_jiffies_relative(0)); |
2119 | return; | 2129 | return; |
2120 | } | 2130 | } |
2121 | 2131 | ||
@@ -2196,8 +2206,7 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data) | |||
2196 | if (local->quiescing) | 2206 | if (local->quiescing) |
2197 | return; | 2207 | return; |
2198 | 2208 | ||
2199 | queue_work(sdata->local->hw.workqueue, | 2209 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); |
2200 | &sdata->u.mgd.beacon_loss_work); | ||
2201 | } | 2210 | } |
2202 | 2211 | ||
2203 | static void ieee80211_sta_conn_mon_timer(unsigned long data) | 2212 | static void ieee80211_sta_conn_mon_timer(unsigned long data) |
@@ -2210,7 +2219,7 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data) | |||
2210 | if (local->quiescing) | 2219 | if (local->quiescing) |
2211 | return; | 2220 | return; |
2212 | 2221 | ||
2213 | queue_work(local->hw.workqueue, &ifmgd->monitor_work); | 2222 | ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); |
2214 | } | 2223 | } |
2215 | 2224 | ||
2216 | static void ieee80211_sta_monitor_work(struct work_struct *work) | 2225 | static void ieee80211_sta_monitor_work(struct work_struct *work) |
@@ -2229,10 +2238,10 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) | |||
2229 | IEEE80211_STA_CONNECTION_POLL); | 2238 | IEEE80211_STA_CONNECTION_POLL); |
2230 | 2239 | ||
2231 | /* let's probe the connection once */ | 2240 | /* let's probe the connection once */ |
2232 | queue_work(sdata->local->hw.workqueue, | 2241 | ieee80211_queue_work(&sdata->local->hw, |
2233 | &sdata->u.mgd.monitor_work); | 2242 | &sdata->u.mgd.monitor_work); |
2234 | /* and do all the other regular work too */ | 2243 | /* and do all the other regular work too */ |
2235 | queue_work(sdata->local->hw.workqueue, | 2244 | ieee80211_queue_work(&sdata->local->hw, |
2236 | &sdata->u.mgd.work); | 2245 | &sdata->u.mgd.work); |
2237 | } | 2246 | } |
2238 | } | 2247 | } |
@@ -2393,7 +2402,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
2393 | list_add(&wk->list, &sdata->u.mgd.work_list); | 2402 | list_add(&wk->list, &sdata->u.mgd.work_list); |
2394 | mutex_unlock(&ifmgd->mtx); | 2403 | mutex_unlock(&ifmgd->mtx); |
2395 | 2404 | ||
2396 | queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work); | 2405 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work); |
2397 | return 0; | 2406 | return 0; |
2398 | } | 2407 | } |
2399 | 2408 | ||
@@ -2467,7 +2476,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2467 | else | 2476 | else |
2468 | ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; | 2477 | ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; |
2469 | 2478 | ||
2470 | queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work); | 2479 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work); |
2471 | 2480 | ||
2472 | err = 0; | 2481 | err = 0; |
2473 | 2482 | ||