OLD | NEW |
---|---|
1 /* | 1 /* |
2 * BSS client mode implementation | 2 * BSS client mode implementation |
3 * Copyright 2003-2008, Jouni Malinen <j@w1.fi> | 3 * Copyright 2003-2008, Jouni Malinen <j@w1.fi> |
4 * Copyright 2004, Instant802 Networks, Inc. | 4 * Copyright 2004, Instant802 Networks, Inc. |
5 * Copyright 2005, Devicescape Software, Inc. | 5 * Copyright 2005, Devicescape Software, Inc. |
6 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 6 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
7 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 7 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
8 * | 8 * |
9 * This program is free software; you can redistribute it and/or modify | 9 * This program is free software; you can redistribute it and/or modify |
10 * it under the terms of the GNU General Public License version 2 as | 10 * it under the terms of the GNU General Public License version 2 as |
(...skipping 10 matching lines...) Expand all Loading... | |
21 #include <linux/crc32.h> | 21 #include <linux/crc32.h> |
22 #include <linux/slab.h> | 22 #include <linux/slab.h> |
23 #include <net/mac80211.h> | 23 #include <net/mac80211.h> |
24 #include <asm/unaligned.h> | 24 #include <asm/unaligned.h> |
25 | 25 |
26 #include "ieee80211_i.h" | 26 #include "ieee80211_i.h" |
27 #include "driver-ops.h" | 27 #include "driver-ops.h" |
28 #include "rate.h" | 28 #include "rate.h" |
29 #include "led.h" | 29 #include "led.h" |
30 | 30 |
31 #define IEEE80211_MAX_PROBE_TRIES 1 | 31 #define IEEE80211_MAX_NULLFUNC_TRIES 2 |
Sam Leffler
2010/12/01 00:23:44
lost local change
| |
32 #define IEEE80211_MAX_PROBE_TRIES 5 | |
32 | 33 |
33 /* | 34 /* |
34 * beacon loss timeout is calculated as N frames times the | 35 * Beacon loss timeout is calculated as N frames times the |
35 * advertised beacon interval. This may need to be somewhat | 36 * advertised beacon interval. This may need to be somewhat |
36 * higher than what hardware might detect to account for | 37 * higher than what hardware might detect to account for |
37 * delays in the host processing frames. But since we also | 38 * delays in the host processing frames. But since we also |
38 * probe on bmiss before declaring the connection lost default | 39 * probe on beacon miss before declaring the connection lost |
39 * to what we want. | 40 * default to what we want. |
40 */ | 41 */ |
41 #define»IEEE80211_BEACON_LOSS_COUNT» 7 | 42 #define IEEE80211_BEACON_LOSS_COUNT» 7 |
43 | |
42 /* | 44 /* |
43 * Time the connection can be idle before we probe | 45 * Time the connection can be idle before we probe |
44 * it to see if we can still talk to the AP. | 46 * it to see if we can still talk to the AP. |
45 */ | 47 */ |
46 #define IEEE80211_CONNECTION_IDLE_TIME (30 * HZ) | 48 #define IEEE80211_CONNECTION_IDLE_TIME (30 * HZ) |
47 /* | 49 /* |
48 * Time we wait for a probe response after sending | 50 * Time we wait for a probe response after sending |
49 * a probe request because of beacon loss or for | 51 * a probe request because of beacon loss or for |
50 * checking the connection still works. | 52 * checking the connection still works. |
51 */ | 53 */ |
52 #define IEEE80211_PROBE_WAIT» » (HZ / 5) | 54 #define IEEE80211_PROBE_WAIT» » (HZ / 2) |
Sam Leffler
2010/12/01 00:23:44
lost local change
nbd
2010/12/02 23:06:54
Intentionally dropped. Should be unnecessary with
Sam Leffler
2010/12/08 18:37:56
But you upped the max tries to 2 so there is now a
| |
53 | 55 |
54 /* | 56 /* |
55 * Weight given to the latest Beacon frame when calculating average signal | 57 * Weight given to the latest Beacon frame when calculating average signal |
56 * strength for Beacon frames received in the current BSS. This must be | 58 * strength for Beacon frames received in the current BSS. This must be |
57 * between 1 and 15. | 59 * between 1 and 15. |
58 */ | 60 */ |
59 #define IEEE80211_SIGNAL_AVE_WEIGHT 3 | 61 #define IEEE80211_SIGNAL_AVE_WEIGHT 3 |
60 | 62 |
61 /* | |
62 * How many Beacon frames need to have been used in average signal strength | |
63 * before starting to indicate signal change events. | |
64 */ | |
65 #define IEEE80211_SIGNAL_AVE_MIN_COUNT 4 | |
66 | |
67 #define TMR_RUNNING_TIMER 0 | 63 #define TMR_RUNNING_TIMER 0 |
68 #define TMR_RUNNING_CHANSW 1 | 64 #define TMR_RUNNING_CHANSW 1 |
69 | 65 |
70 /* | 66 /* |
71 * All cfg80211 functions have to be called outside a locked | 67 * All cfg80211 functions have to be called outside a locked |
72 * section so that they can acquire a lock themselves... This | 68 * section so that they can acquire a lock themselves... This |
73 * is much simpler than queuing up things in cfg80211, but we | 69 * is much simpler than queuing up things in cfg80211, but we |
74 * do need some indirection for that here. | 70 * do need some indirection for that here. |
75 */ | 71 */ |
76 enum rx_mgmt_action { | 72 enum rx_mgmt_action { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 time_before(timeout, ifmgd->timer.expires)) | 114 time_before(timeout, ifmgd->timer.expires)) |
119 mod_timer(&ifmgd->timer, timeout); | 115 mod_timer(&ifmgd->timer, timeout); |
120 } | 116 } |
121 | 117 |
122 void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) | 118 void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) |
123 { | 119 { |
124 if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER) | 120 if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER) |
125 return; | 121 return; |
126 | 122 |
127 mod_timer(&sdata->u.mgd.bcn_mon_timer, | 123 mod_timer(&sdata->u.mgd.bcn_mon_timer, |
128 » » round_jiffies_up(jiffies + sdata->u.mgd.bloss_timeout)); | 124 » » round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout)); |
129 } | 125 } |
130 | 126 |
131 void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata) | 127 void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata) |
132 { | 128 { |
133 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 129 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
134 | 130 |
135 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | 131 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) |
136 return; | 132 return; |
137 | 133 |
138 mod_timer(&sdata->u.mgd.conn_mon_timer, | 134 mod_timer(&sdata->u.mgd.conn_mon_timer, |
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
865 struct cfg80211_bss *cbss, | 861 struct cfg80211_bss *cbss, |
866 u32 bss_info_changed) | 862 u32 bss_info_changed) |
867 { | 863 { |
868 struct ieee80211_bss *bss = (void *)cbss->priv; | 864 struct ieee80211_bss *bss = (void *)cbss->priv; |
869 struct ieee80211_local *local = sdata->local; | 865 struct ieee80211_local *local = sdata->local; |
870 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; | 866 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
871 | 867 |
872 bss_info_changed |= BSS_CHANGED_ASSOC; | 868 bss_info_changed |= BSS_CHANGED_ASSOC; |
873 /* set timing information */ | 869 /* set timing information */ |
874 bss_conf->beacon_int = cbss->beacon_interval; | 870 bss_conf->beacon_int = cbss->beacon_interval; |
875 /* beacon_int is in TU, convert to jiffies for timer handling */ | |
876 sdata->u.mgd.bloss_timeout = usecs_to_jiffies(ieee80211_tu_to_usec( | |
877 IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int)); | |
878 bss_conf->timestamp = cbss->tsf; | 871 bss_conf->timestamp = cbss->tsf; |
879 | 872 |
880 bss_info_changed |= BSS_CHANGED_BEACON_INT; | 873 bss_info_changed |= BSS_CHANGED_BEACON_INT; |
881 bss_info_changed |= ieee80211_handle_bss_capability(sdata, | 874 bss_info_changed |= ieee80211_handle_bss_capability(sdata, |
882 cbss->capability, bss->has_erp_value, bss->erp_value); | 875 cbss->capability, bss->has_erp_value, bss->erp_value); |
883 | 876 |
877 sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec( | |
878 IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int)); | |
879 | |
884 sdata->u.mgd.associated = cbss; | 880 sdata->u.mgd.associated = cbss; |
885 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN); | 881 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN); |
886 | 882 |
887 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; | 883 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; |
888 | 884 |
889 /* just to be sure */ | 885 /* just to be sure */ |
890 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 886 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | |
891 IEEE80211_STA_BEACON_POLL); | 887 IEEE80211_STA_BEACON_POLL); |
892 | 888 |
893 /* | 889 /* |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
932 mutex_lock(&local->iflist_mtx); | 928 mutex_lock(&local->iflist_mtx); |
933 ieee80211_recalc_ps(local, -1); | 929 ieee80211_recalc_ps(local, -1); |
934 ieee80211_recalc_smps(local, sdata); | 930 ieee80211_recalc_smps(local, sdata); |
935 mutex_unlock(&local->iflist_mtx); | 931 mutex_unlock(&local->iflist_mtx); |
936 | 932 |
937 netif_tx_start_all_queues(sdata->dev); | 933 netif_tx_start_all_queues(sdata->dev); |
938 netif_carrier_on(sdata->dev); | 934 netif_carrier_on(sdata->dev); |
939 } | 935 } |
940 | 936 |
941 static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | 937 static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, |
942 » » » » bool remove_sta, bool tx) | 938 » » » » bool remove_sta) |
943 { | 939 { |
944 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 940 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
945 struct ieee80211_local *local = sdata->local; | 941 struct ieee80211_local *local = sdata->local; |
946 struct sta_info *sta; | 942 struct sta_info *sta; |
947 u32 changed = 0, config_changed = 0; | 943 u32 changed = 0, config_changed = 0; |
948 u8 bssid[ETH_ALEN]; | 944 u8 bssid[ETH_ALEN]; |
949 | 945 |
950 ASSERT_MGD_MTX(ifmgd); | 946 ASSERT_MGD_MTX(ifmgd); |
951 | 947 |
952 if (WARN_ON(!ifmgd->associated)) | 948 if (WARN_ON(!ifmgd->associated)) |
(...skipping 18 matching lines...) Expand all Loading... | |
971 * time -- we don't want the scan code to enable queues. | 967 * time -- we don't want the scan code to enable queues. |
972 */ | 968 */ |
973 | 969 |
974 netif_tx_stop_all_queues(sdata->dev); | 970 netif_tx_stop_all_queues(sdata->dev); |
975 netif_carrier_off(sdata->dev); | 971 netif_carrier_off(sdata->dev); |
976 | 972 |
977 mutex_lock(&local->sta_mtx); | 973 mutex_lock(&local->sta_mtx); |
978 sta = sta_info_get(sdata, bssid); | 974 sta = sta_info_get(sdata, bssid); |
979 if (sta) { | 975 if (sta) { |
980 set_sta_flags(sta, WLAN_STA_BLOCK_BA); | 976 set_sta_flags(sta, WLAN_STA_BLOCK_BA); |
981 » » ieee80211_sta_tear_down_BA_sessions(sta, tx); | 977 » » ieee80211_sta_tear_down_BA_sessions(sta); |
982 } | 978 } |
983 mutex_unlock(&local->sta_mtx); | 979 mutex_unlock(&local->sta_mtx); |
984 | 980 |
985 changed |= ieee80211_reset_erp_info(sdata); | 981 changed |= ieee80211_reset_erp_info(sdata); |
986 | 982 |
987 ieee80211_led_assoc(local, 0); | 983 ieee80211_led_assoc(local, 0); |
988 changed |= BSS_CHANGED_ASSOC; | 984 changed |= BSS_CHANGED_ASSOC; |
989 sdata->vif.bss_conf.assoc = false; | 985 sdata->vif.bss_conf.assoc = false; |
990 | 986 |
991 ieee80211_set_wmm_default(sdata); | 987 ieee80211_set_wmm_default(sdata); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1032 * be ignored here, because we need to trigger the timer during | 1028 * be ignored here, because we need to trigger the timer during |
1033 * data idle periods for sending the periodic probe request to the | 1029 * data idle periods for sending the periodic probe request to the |
1034 * AP we're connected to. | 1030 * AP we're connected to. |
1035 */ | 1031 */ |
1036 if (is_multicast_ether_addr(hdr->addr1)) | 1032 if (is_multicast_ether_addr(hdr->addr1)) |
1037 return; | 1033 return; |
1038 | 1034 |
1039 ieee80211_sta_reset_conn_monitor(sdata); | 1035 ieee80211_sta_reset_conn_monitor(sdata); |
1040 } | 1036 } |
1041 | 1037 |
1038 static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) | |
1039 { | |
1040 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | |
1041 | |
1042 if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | |
1043 IEEE80211_STA_CONNECTION_POLL))) | |
1044 return; | |
1045 | |
1046 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | |
1047 IEEE80211_STA_BEACON_POLL); | |
1048 mutex_lock(&sdata->local->iflist_mtx); | |
1049 ieee80211_recalc_ps(sdata->local, -1); | |
1050 mutex_unlock(&sdata->local->iflist_mtx); | |
1051 | |
1052 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | |
1053 return; | |
1054 | |
1055 /* | |
1056 * We've received a probe response, but are not sure whether | |
1057 * we have or will be receiving any beacons or data, so let's | |
1058 * schedule the timers again, just in case. | |
1059 */ | |
1060 ieee80211_sta_reset_beacon_monitor(sdata); | |
1061 | |
1062 mod_timer(&ifmgd->conn_mon_timer, | |
1063 round_jiffies_up(jiffies + | |
1064 IEEE80211_CONNECTION_IDLE_TIME)); | |
1065 } | |
1066 | |
1067 void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, | |
1068 struct ieee80211_hdr *hdr) | |
1069 { | |
1070 if (!ieee80211_is_data(hdr->frame_control) && | |
1071 !ieee80211_is_nullfunc(hdr->frame_control)) | |
Sam Leffler
2010/12/01 00:23:44
should be able to recognize NullData frame w/ one
| |
1072 return; | |
1073 | |
1074 ieee80211_sta_reset_conn_monitor(sdata); | |
1075 | |
1076 if (ieee80211_is_nullfunc(hdr->frame_control) && | |
1077 sdata->u.mgd.probe_send_count > 0) { | |
1078 sdata->u.mgd.probe_send_count = 0; | |
1079 ieee80211_queue_work(&sdata->local->hw, &sdata->work); | |
1080 } | |
1081 } | |
1082 | |
1042 static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | 1083 static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) |
1043 { | 1084 { |
1044 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1085 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1045 const u8 *ssid; | 1086 const u8 *ssid; |
1046 u8 *dst = ifmgd->associated->bssid; | 1087 u8 *dst = ifmgd->associated->bssid; |
1088 u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3); | |
1047 | 1089 |
1090 /* | |
1091 * Try sending broadcast probe requests for the last three | |
1092 * probe requests after the first ones failed since some | |
1093 * buggy APs only support broadcast probe requests. | |
1094 */ | |
1095 if (ifmgd->probe_send_count >= unicast_limit) | |
1096 dst = NULL; | |
1048 | 1097 |
1049 » if ((sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { | 1098 » /* |
1099 » * When the hardware reports an accurate Tx ACK status, it's | |
1100 » * better to send a nullfunc frame instead of a probe request, | |
1101 » * as it will kick us off the AP quickly if we aren't associated | |
1102 » * anymore. The timeout will be reset if the frame is ACKed by | |
1103 » * the AP. | |
1104 » */ | |
1105 » if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | |
1050 ieee80211_send_nullfunc(sdata->local, sdata, 0); | 1106 ieee80211_send_nullfunc(sdata->local, sdata, 0); |
1051 » } else { | 1107 » else { |
1052 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); | 1108 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); |
1053 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0) ; | 1109 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0) ; |
1054 } | 1110 } |
1055 | 1111 |
1056 ifmgd->probe_send_count++; | 1112 ifmgd->probe_send_count++; |
1113 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; | |
1114 run_again(ifmgd, ifmgd->probe_timeout); | |
Sam Leffler
2010/12/01 00:23:44
this should not run for the send_nullfunc case as
nbd
2010/12/02 23:06:54
I think we should run this one even for the nullfu
Sam Leffler
2010/12/08 18:37:56
I don't understand how interference relates to sta
| |
1057 } | 1115 } |
1058 | 1116 |
1059 static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | 1117 static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, |
1060 bool beacon) | 1118 bool beacon) |
1061 { | 1119 { |
1062 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1120 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1063 bool already = false; | 1121 bool already = false; |
1064 | 1122 |
1065 if (!ieee80211_sdata_running(sdata)) | 1123 if (!ieee80211_sdata_running(sdata)) |
1066 return; | 1124 return; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1124 mutex_lock(&ifmgd->mtx); | 1182 mutex_lock(&ifmgd->mtx); |
1125 if (!ifmgd->associated) { | 1183 if (!ifmgd->associated) { |
1126 mutex_unlock(&ifmgd->mtx); | 1184 mutex_unlock(&ifmgd->mtx); |
1127 return; | 1185 return; |
1128 } | 1186 } |
1129 | 1187 |
1130 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | 1188 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); |
1131 | 1189 |
1132 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); | 1190 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); |
1133 | 1191 |
1134 » ieee80211_set_disassoc(sdata, true, true); | 1192 » ieee80211_set_disassoc(sdata, true); |
Sam Leffler
2010/12/01 00:23:44
missing local changes
| |
1135 ieee80211_recalc_idle(local); | 1193 ieee80211_recalc_idle(local); |
1136 mutex_unlock(&ifmgd->mtx); | 1194 mutex_unlock(&ifmgd->mtx); |
1137 /* | 1195 /* |
1138 * must be outside lock due to cfg80211, | 1196 * must be outside lock due to cfg80211, |
1139 * but that's not a problem. | 1197 * but that's not a problem. |
1140 */ | 1198 */ |
1141 ieee80211_send_deauth_disassoc(sdata, bssid, | 1199 ieee80211_send_deauth_disassoc(sdata, bssid, |
1142 IEEE80211_STYPE_DEAUTH, | 1200 IEEE80211_STYPE_DEAUTH, |
1143 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | 1201 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, |
1144 NULL, true); | 1202 NULL, true); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1202 | 1260 |
1203 ASSERT_MGD_MTX(ifmgd); | 1261 ASSERT_MGD_MTX(ifmgd); |
1204 | 1262 |
1205 bssid = ifmgd->associated->bssid; | 1263 bssid = ifmgd->associated->bssid; |
1206 | 1264 |
1207 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | 1265 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); |
1208 | 1266 |
1209 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", | 1267 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", |
1210 sdata->name, bssid, reason_code); | 1268 sdata->name, bssid, reason_code); |
1211 | 1269 |
1212 » ieee80211_set_disassoc(sdata, true, false); | 1270 » ieee80211_set_disassoc(sdata, true); |
1213 ieee80211_recalc_idle(sdata->local); | 1271 ieee80211_recalc_idle(sdata->local); |
1214 | 1272 |
1215 return RX_MGMT_CFG80211_DEAUTH; | 1273 return RX_MGMT_CFG80211_DEAUTH; |
1216 } | 1274 } |
1217 | 1275 |
1218 | 1276 |
1219 static enum rx_mgmt_action __must_check | 1277 static enum rx_mgmt_action __must_check |
1220 ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | 1278 ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, |
1221 struct ieee80211_mgmt *mgmt, size_t len) | 1279 struct ieee80211_mgmt *mgmt, size_t len) |
1222 { | 1280 { |
1223 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1281 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1224 u16 reason_code; | 1282 u16 reason_code; |
1225 | 1283 |
1226 if (len < 24 + 2) | 1284 if (len < 24 + 2) |
1227 return RX_MGMT_NONE; | 1285 return RX_MGMT_NONE; |
1228 | 1286 |
1229 ASSERT_MGD_MTX(ifmgd); | 1287 ASSERT_MGD_MTX(ifmgd); |
1230 | 1288 |
1231 if (WARN_ON(!ifmgd->associated)) | 1289 if (WARN_ON(!ifmgd->associated)) |
1232 return RX_MGMT_NONE; | 1290 return RX_MGMT_NONE; |
1233 | 1291 |
1234 if (WARN_ON(memcmp(ifmgd->associated->bssid, mgmt->sa, ETH_ALEN))) | 1292 if (WARN_ON(memcmp(ifmgd->associated->bssid, mgmt->sa, ETH_ALEN))) |
1235 return RX_MGMT_NONE; | 1293 return RX_MGMT_NONE; |
1236 | 1294 |
1237 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 1295 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
1238 | 1296 |
1239 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", | 1297 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", |
1240 sdata->name, mgmt->sa, reason_code); | 1298 sdata->name, mgmt->sa, reason_code); |
1241 | 1299 |
1242 » ieee80211_set_disassoc(sdata, true, false); | 1300 » ieee80211_set_disassoc(sdata, true); |
1243 ieee80211_recalc_idle(sdata->local); | 1301 ieee80211_recalc_idle(sdata->local); |
1244 return RX_MGMT_CFG80211_DISASSOC; | 1302 return RX_MGMT_CFG80211_DISASSOC; |
1245 } | 1303 } |
1246 | 1304 |
1247 | 1305 |
1248 static bool ieee80211_assoc_success(struct ieee80211_work *wk, | 1306 static bool ieee80211_assoc_success(struct ieee80211_work *wk, |
1249 struct ieee80211_mgmt *mgmt, size_t len) | 1307 struct ieee80211_mgmt *mgmt, size_t len) |
1250 { | 1308 { |
1251 struct ieee80211_sub_if_data *sdata = wk->sdata; | 1309 struct ieee80211_sub_if_data *sdata = wk->sdata; |
1252 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1310 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1478 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; | 1536 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; |
1479 if (baselen > len) | 1537 if (baselen > len) |
1480 return; | 1538 return; |
1481 | 1539 |
1482 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | 1540 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, |
1483 &elems); | 1541 &elems); |
1484 | 1542 |
1485 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); | 1543 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); |
1486 | 1544 |
1487 if (ifmgd->associated && | 1545 if (ifmgd->associated && |
1488 » memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0 && | 1546 » memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0) |
1489 » ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | 1547 » » ieee80211_reset_ap_probe(sdata); |
1490 » » » IEEE80211_STA_CONNECTION_POLL)) { | |
1491 » » ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | |
1492 » » » » IEEE80211_STA_BEACON_POLL); | |
1493 » » mutex_lock(&sdata->local->iflist_mtx); | |
1494 » » ieee80211_recalc_ps(sdata->local, -1); | |
1495 » » mutex_unlock(&sdata->local->iflist_mtx); | |
1496 | |
1497 » » if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | |
1498 » » » return; | |
1499 | |
1500 » » /* | |
1501 » » * We've received a probe response, but are not sure whether | |
1502 » » * we have or will be receiving any beacons or data, so let's | |
1503 » » * schedule the timers again, just in case. | |
1504 » » */ | |
1505 » » ieee80211_sta_reset_beacon_monitor(sdata); | |
1506 | |
1507 » » mod_timer(&ifmgd->conn_mon_timer, | |
1508 » » » round_jiffies_up(jiffies + | |
1509 » » » » » IEEE80211_CONNECTION_IDLE_TIME)); | |
1510 » } | |
1511 } | 1548 } |
1512 | 1549 |
1513 /* | 1550 /* |
1514 * This is the canonical list of information elements we care about, | 1551 * This is the canonical list of information elements we care about, |
1515 * the filter code also gives us all changes to the Microsoft OUI | 1552 * the filter code also gives us all changes to the Microsoft OUI |
1516 * (00:50:F2) vendor IE which is used for WMM which we need to track. | 1553 * (00:50:F2) vendor IE which is used for WMM which we need to track. |
1517 * | 1554 * |
1518 * We implement beacon filtering in software since that means we can | 1555 * We implement beacon filtering in software since that means we can |
1519 * avoid processing the frame here and in cfg80211, and userspace | 1556 * avoid processing the frame here and in cfg80211, and userspace |
1520 * will not be able to tell whether the hardware supports it or not. | 1557 * will not be able to tell whether the hardware supports it or not. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1572 */ | 1609 */ |
1573 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0) | 1610 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0) |
1574 return; | 1611 return; |
1575 | 1612 |
1576 /* Track average RSSI from the Beacon frames of the current AP */ | 1613 /* Track average RSSI from the Beacon frames of the current AP */ |
1577 ifmgd->last_beacon_signal = rx_status->signal; | 1614 ifmgd->last_beacon_signal = rx_status->signal; |
1578 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { | 1615 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { |
1579 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; | 1616 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; |
1580 ifmgd->ave_beacon_signal = rx_status->signal * 16; | 1617 ifmgd->ave_beacon_signal = rx_status->signal * 16; |
1581 ifmgd->last_cqm_event_signal = 0; | 1618 ifmgd->last_cqm_event_signal = 0; |
1582 ifmgd->count_beacon_signal = 1; | |
1583 } else { | 1619 } else { |
1584 ifmgd->ave_beacon_signal = | 1620 ifmgd->ave_beacon_signal = |
1585 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 + | 1621 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 + |
1586 (16 - IEEE80211_SIGNAL_AVE_WEIGHT) * | 1622 (16 - IEEE80211_SIGNAL_AVE_WEIGHT) * |
1587 ifmgd->ave_beacon_signal) / 16; | 1623 ifmgd->ave_beacon_signal) / 16; |
1588 ifmgd->count_beacon_signal++; | |
1589 } | 1624 } |
1590 if (bss_conf->cqm_rssi_thold && | 1625 if (bss_conf->cqm_rssi_thold && |
1591 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT && | |
1592 !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { | 1626 !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { |
1593 int sig = ifmgd->ave_beacon_signal / 16; | 1627 int sig = ifmgd->ave_beacon_signal / 16; |
1594 int last_event = ifmgd->last_cqm_event_signal; | 1628 int last_event = ifmgd->last_cqm_event_signal; |
1595 int thold = bss_conf->cqm_rssi_thold; | 1629 int thold = bss_conf->cqm_rssi_thold; |
1596 int hyst = bss_conf->cqm_rssi_hyst; | 1630 int hyst = bss_conf->cqm_rssi_hyst; |
1597 if (sig < thold && | 1631 if (sig < thold && |
1598 (last_event == 0 || sig < last_event - hyst)) { | 1632 (last_event == 0 || sig < last_event - hyst)) { |
1599 ifmgd->last_cqm_event_signal = sig; | 1633 ifmgd->last_cqm_event_signal = sig; |
1600 ieee80211_cqm_rssi_notify( | 1634 ieee80211_cqm_rssi_notify( |
1601 &sdata->vif, | 1635 &sdata->vif, |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1839 if (local->quiescing) { | 1873 if (local->quiescing) { |
1840 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); | 1874 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); |
1841 return; | 1875 return; |
1842 } | 1876 } |
1843 | 1877 |
1844 ieee80211_queue_work(&local->hw, &sdata->work); | 1878 ieee80211_queue_work(&local->hw, &sdata->work); |
1845 } | 1879 } |
1846 | 1880 |
1847 void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | 1881 void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) |
1848 { | 1882 { |
1849 » /* nothing right now */ | 1883 » struct ieee80211_local *local = sdata->local; |
1850 } | 1884 » struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1851 | 1885 |
1852 static void ieee80211_sta_process_probe_status(struct ieee80211_sub_if_data *sda ta) | 1886 » /* then process the rest of the work */ |
1853 { | |
1854 » struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | |
1855 » struct ieee80211_local *local = sdata->local; | |
1856 » u8 bssid[ETH_ALEN]; | |
1857 | |
1858 mutex_lock(&ifmgd->mtx); | 1887 mutex_lock(&ifmgd->mtx); |
1859 | 1888 |
1860 » if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | 1889 » if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | |
1861 » » » IEEE80211_STA_CONNECTION_POLL))) | 1890 » » » IEEE80211_STA_CONNECTION_POLL) && |
1862 » » goto done; | 1891 » ifmgd->associated) { |
1863 » if (!ifmgd->associated)»/* XXX can this fail if flags are set? */ | 1892 » » u8 bssid[ETH_ALEN]; |
1864 » » goto done; | 1893 » » int max_tries; |
1865 » memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | |
1866 » if (ifmgd->probe_acked) { | |
1867 » » /* | |
1868 » » * Probe frame was ACK'd, just clear polling state. | |
1869 » » */ | |
1870 » » ifmgd->flags &= ~(IEEE80211_STA_BEACON_POLL | | |
1871 » » » » IEEE80211_STA_CONNECTION_POLL); | |
1872 » » ifmgd->probe_send_count = 0; | |
1873 | 1894 |
1874 » » /* | 1895 » » memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); |
1875 » » * Re-enable power save | 1896 |
1876 » » */ | 1897 » » if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) |
1877 » » mutex_lock(&local->iflist_mtx); | 1898 » » » max_tries = IEEE80211_MAX_NULLFUNC_TRIES; |
1878 » » ieee80211_recalc_ps(local, -1); | 1899 » » else |
1879 » » mutex_unlock(&local->iflist_mtx); | 1900 » » » max_tries = IEEE80211_MAX_PROBE_TRIES; |
1880 » } else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { | 1901 |
1902 » » /* ACK received for nullfunc probing frame */ | |
1903 » » if (!ifmgd->probe_send_count) | |
1904 » » » ieee80211_reset_ap_probe(sdata); | |
1905 | |
1906 » » else if (time_is_after_jiffies(ifmgd->probe_timeout)) | |
1907 » » » run_again(ifmgd, ifmgd->probe_timeout); | |
1908 | |
1909 » » else if (ifmgd->probe_send_count < max_tries) { | |
1881 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1910 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1882 » » printk(KERN_DEBUG "No ACK of probe to AP %pM, try again (%d)\n", | 1911 » » » printk(KERN_DEBUG "No probe response from AP %pM" |
1883 » » » bssid, ifmgd->probe_send_count); | 1912 » » » » " after %dms, try %d\n", bssid, |
1913 » » » » (1000 * IEEE80211_PROBE_WAIT)/HZ, | |
1914 » » » » ifmgd->probe_send_count); | |
1884 #endif | 1915 #endif |
1885 » » ieee80211_mgd_probe_ap_send(sdata); | 1916 » » » ieee80211_mgd_probe_ap_send(sdata); |
1886 » } else { | 1917 » » } else { |
1887 » » /* | 1918 » » » /* |
1888 » » * We actually lost the connection. | 1919 » » » * We actually lost the connection ... or did we? |
1889 » » */ | 1920 » » » * Let's make sure! |
Sam Leffler
2010/12/01 00:23:44
comment is wrong
| |
1890 » » ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 1921 » » » */ |
1891 » » » » IEEE80211_STA_BEACON_POLL); | 1922 » » » ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | |
1923 » » » » » IEEE80211_STA_BEACON_POLL); | |
1924 » » » printk(KERN_DEBUG "No probe response from AP %pM" | |
1925 » » » » " after %dms, disconnecting.\n", | |
1926 » » » » bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); | |
Sam Leffler
2010/12/01 00:23:44
this msg is wrong for the nulldata case which is w
| |
1927 » » » ieee80211_set_disassoc(sdata, true); | |
1928 » » » ieee80211_recalc_idle(local); | |
1929 » » » mutex_unlock(&ifmgd->mtx); | |
1930 » » » /* | |
1931 » » » * must be outside lock due to cfg80211, | |
1932 » » » * but that's not a problem. | |
1933 » » » */ | |
1934 » » » ieee80211_send_deauth_disassoc(sdata, bssid, | |
1935 » » » » » IEEE80211_STYPE_DEAUTH, | |
1936 » » » » » WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | |
1937 » » » » » NULL, true); | |
1938 » » » mutex_lock(&ifmgd->mtx); | |
1939 » » } | |
1940 » } | |
1892 | 1941 |
1893 /* XXX juggle __ieee80211_connection_loss to suit */ | |
1894 printk(KERN_DEBUG "No response from AP %pM, disconnecting.\n", | |
1895 bssid); | |
1896 | |
1897 ieee80211_set_disassoc(sdata, true, true); | |
1898 ieee80211_recalc_idle(local); | |
1899 | |
1900 /* | |
1901 * NB: must be outside lock due to cfg80211. | |
1902 */ | |
1903 mutex_unlock(&ifmgd->mtx); | |
1904 ieee80211_send_deauth_disassoc(sdata, bssid, | |
1905 IEEE80211_STYPE_DEAUTH, | |
1906 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | |
1907 NULL, true); | |
1908 return; | |
1909 } | |
1910 done: | |
1911 mutex_unlock(&ifmgd->mtx); | 1942 mutex_unlock(&ifmgd->mtx); |
1912 } | 1943 } |
1913 | 1944 |
1914 /* | |
1915 * Process TX status for probe frame sent to the associated | |
1916 * AP on beacon or connection loss. | |
1917 */ | |
1918 static void ieee80211_probe_status_work(struct work_struct *work) | |
1919 { | |
1920 struct ieee80211_sub_if_data *sdata = container_of(work, | |
1921 struct ieee80211_sub_if_data, u.mgd.probe_status_work); | |
1922 | |
1923 WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION); | |
1924 | |
1925 if (ieee80211_sdata_running(sdata)) | |
1926 ieee80211_sta_process_probe_status(sdata); | |
1927 } | |
1928 | |
1929 static void ieee80211_sta_bcn_mon_timer(unsigned long data) | 1945 static void ieee80211_sta_bcn_mon_timer(unsigned long data) |
1930 { | 1946 { |
1931 struct ieee80211_sub_if_data *sdata = | 1947 struct ieee80211_sub_if_data *sdata = |
1932 (struct ieee80211_sub_if_data *) data; | 1948 (struct ieee80211_sub_if_data *) data; |
1933 struct ieee80211_local *local = sdata->local; | 1949 struct ieee80211_local *local = sdata->local; |
1934 | 1950 |
1935 if (local->quiescing) | 1951 if (local->quiescing) |
1936 return; | 1952 return; |
1937 | 1953 |
1938 ieee80211_queue_work(&sdata->local->hw, | 1954 ieee80211_queue_work(&sdata->local->hw, |
(...skipping 21 matching lines...) Expand all Loading... | |
1960 | 1976 |
1961 ieee80211_mgd_probe_ap(sdata, false); | 1977 ieee80211_mgd_probe_ap(sdata, false); |
1962 } | 1978 } |
1963 | 1979 |
1964 static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) | 1980 static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) |
1965 { | 1981 { |
1966 if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 1982 if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
1967 sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL | | 1983 sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL | |
1968 IEEE80211_STA_CONNECTION_POLL); | 1984 IEEE80211_STA_CONNECTION_POLL); |
1969 | 1985 |
1986 /* let's probe the connection once */ | |
1987 ieee80211_queue_work(&sdata->local->hw, | |
1988 &sdata->u.mgd.monitor_work); | |
1970 /* and do all the other regular work too */ | 1989 /* and do all the other regular work too */ |
1971 ieee80211_queue_work(&sdata->local->hw, &sdata->work); | 1990 ieee80211_queue_work(&sdata->local->hw, &sdata->work); |
1972 } | 1991 } |
1973 } | 1992 } |
1974 | 1993 |
1975 #ifdef CONFIG_PM | 1994 #ifdef CONFIG_PM |
1976 void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | 1995 void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) |
1977 { | 1996 { |
1978 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1997 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1979 | 1998 |
(...skipping 18 matching lines...) Expand all Loading... | |
1998 } | 2017 } |
1999 | 2018 |
2000 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | 2019 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) |
2001 { | 2020 { |
2002 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2021 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2003 | 2022 |
2004 if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running)) | 2023 if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running)) |
2005 add_timer(&ifmgd->timer); | 2024 add_timer(&ifmgd->timer); |
2006 if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) | 2025 if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) |
2007 add_timer(&ifmgd->chswitch_timer); | 2026 add_timer(&ifmgd->chswitch_timer); |
2008 | |
2009 ieee80211_sta_reset_beacon_monitor(sdata); | 2027 ieee80211_sta_reset_beacon_monitor(sdata); |
2010 » ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.monitor_work); | 2028 » ieee80211_restart_sta_timer(sdata); |
Sam Leffler
2010/12/01 00:23:44
this restarts more than just the connection monito
nbd
2010/12/02 23:06:54
The interface may have collected some unprocessed
| |
2011 } | 2029 } |
2012 #endif | 2030 #endif |
2013 | 2031 |
2014 /* interface setup */ | 2032 /* interface setup */ |
2015 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | 2033 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) |
2016 { | 2034 { |
2017 struct ieee80211_if_managed *ifmgd; | 2035 struct ieee80211_if_managed *ifmgd; |
2018 | 2036 |
2019 ifmgd = &sdata->u.mgd; | 2037 ifmgd = &sdata->u.mgd; |
2020 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); | 2038 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); |
2021 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); | 2039 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); |
2022 INIT_WORK(&ifmgd->beacon_connection_loss_work, | 2040 INIT_WORK(&ifmgd->beacon_connection_loss_work, |
2023 ieee80211_beacon_connection_loss_work); | 2041 ieee80211_beacon_connection_loss_work); |
2024 INIT_WORK(&ifmgd->probe_status_work, ieee80211_probe_status_work); | |
2025 INIT_WORK(&ifmgd->bitrate_notify_work, ieee80211_rate_notify_work); | 2042 INIT_WORK(&ifmgd->bitrate_notify_work, ieee80211_rate_notify_work); |
2026 setup_timer(&ifmgd->timer, ieee80211_sta_timer, | 2043 setup_timer(&ifmgd->timer, ieee80211_sta_timer, |
2027 (unsigned long) sdata); | 2044 (unsigned long) sdata); |
2028 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, | 2045 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, |
2029 (unsigned long) sdata); | 2046 (unsigned long) sdata); |
2030 setup_timer(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, | 2047 setup_timer(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, |
2031 (unsigned long) sdata); | 2048 (unsigned long) sdata); |
2032 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, | 2049 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, |
2033 (unsigned long) sdata); | 2050 (unsigned long) sdata); |
2034 | 2051 |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2222 /* | 2239 /* |
2223 * We are already associated and the request was not a | 2240 * We are already associated and the request was not a |
2224 * reassociation request from the current BSS, so | 2241 * reassociation request from the current BSS, so |
2225 * reject it. | 2242 * reject it. |
2226 */ | 2243 */ |
2227 mutex_unlock(&ifmgd->mtx); | 2244 mutex_unlock(&ifmgd->mtx); |
2228 return -EALREADY; | 2245 return -EALREADY; |
2229 } | 2246 } |
2230 | 2247 |
2231 /* Trying to reassociate - clear previous association state */ | 2248 /* Trying to reassociate - clear previous association state */ |
2232 » » ieee80211_set_disassoc(sdata, true, false); | 2249 » » ieee80211_set_disassoc(sdata, true); |
2233 } | 2250 } |
2234 mutex_unlock(&ifmgd->mtx); | 2251 mutex_unlock(&ifmgd->mtx); |
2235 | 2252 |
2236 wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL); | 2253 wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL); |
2237 if (!wk) | 2254 if (!wk) |
2238 return -ENOMEM; | 2255 return -ENOMEM; |
2239 | 2256 |
2240 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; | 2257 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; |
2241 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; | 2258 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; |
2242 | 2259 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2331 struct ieee80211_local *local = sdata->local; | 2348 struct ieee80211_local *local = sdata->local; |
2332 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2349 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2333 struct ieee80211_work *wk; | 2350 struct ieee80211_work *wk; |
2334 u8 bssid[ETH_ALEN]; | 2351 u8 bssid[ETH_ALEN]; |
2335 bool assoc_bss = false; | 2352 bool assoc_bss = false; |
2336 | 2353 |
2337 mutex_lock(&ifmgd->mtx); | 2354 mutex_lock(&ifmgd->mtx); |
2338 | 2355 |
2339 memcpy(bssid, req->bss->bssid, ETH_ALEN); | 2356 memcpy(bssid, req->bss->bssid, ETH_ALEN); |
2340 if (ifmgd->associated == req->bss) { | 2357 if (ifmgd->associated == req->bss) { |
2341 » » ieee80211_set_disassoc(sdata, false, true); | 2358 » » ieee80211_set_disassoc(sdata, false); |
2342 mutex_unlock(&ifmgd->mtx); | 2359 mutex_unlock(&ifmgd->mtx); |
2343 assoc_bss = true; | 2360 assoc_bss = true; |
2344 } else { | 2361 } else { |
2345 bool not_auth_yet = false; | 2362 bool not_auth_yet = false; |
2346 | 2363 |
2347 mutex_unlock(&ifmgd->mtx); | 2364 mutex_unlock(&ifmgd->mtx); |
2348 | 2365 |
2349 mutex_lock(&local->work_mtx); | 2366 mutex_lock(&local->work_mtx); |
2350 list_for_each_entry(wk, &local->work_list, list) { | 2367 list_for_each_entry(wk, &local->work_list, list) { |
2351 if (wk->sdata != sdata) | 2368 if (wk->sdata != sdata) |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2412 */ | 2429 */ |
2413 if (ifmgd->associated != req->bss) { | 2430 if (ifmgd->associated != req->bss) { |
2414 mutex_unlock(&ifmgd->mtx); | 2431 mutex_unlock(&ifmgd->mtx); |
2415 return -ENOLINK; | 2432 return -ENOLINK; |
2416 } | 2433 } |
2417 | 2434 |
2418 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=% d)\n", | 2435 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=% d)\n", |
2419 sdata->name, req->bss->bssid, req->reason_code); | 2436 sdata->name, req->bss->bssid, req->reason_code); |
2420 | 2437 |
2421 memcpy(bssid, req->bss->bssid, ETH_ALEN); | 2438 memcpy(bssid, req->bss->bssid, ETH_ALEN); |
2422 » ieee80211_set_disassoc(sdata, false, true); | 2439 » ieee80211_set_disassoc(sdata, false); |
2423 | 2440 |
2424 mutex_unlock(&ifmgd->mtx); | 2441 mutex_unlock(&ifmgd->mtx); |
2425 | 2442 |
2426 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, | 2443 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, |
2427 IEEE80211_STYPE_DISASSOC, req->reason_code, | 2444 IEEE80211_STYPE_DISASSOC, req->reason_code, |
2428 cookie, !req->local_state_change); | 2445 cookie, !req->local_state_change); |
2429 sta_info_destroy_addr(sdata, bssid); | 2446 sta_info_destroy_addr(sdata, bssid); |
2430 | 2447 |
2431 ieee80211_recalc_idle(sdata->local); | 2448 ieee80211_recalc_idle(sdata->local); |
2432 | 2449 |
2433 return 0; | 2450 return 0; |
2434 } | 2451 } |
2435 | 2452 |
2436 void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, | 2453 void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, |
2437 enum nl80211_cqm_rssi_threshold_event rssi_event, | 2454 enum nl80211_cqm_rssi_threshold_event rssi_event, |
2438 gfp_t gfp) | 2455 gfp_t gfp) |
2439 { | 2456 { |
2440 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 2457 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
2441 | 2458 |
2442 trace_api_cqm_rssi_notify(sdata, rssi_event); | 2459 trace_api_cqm_rssi_notify(sdata, rssi_event); |
2443 | 2460 |
2444 cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); | 2461 cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); |
2445 } | 2462 } |
2446 EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); | 2463 EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); |
OLD | NEW |