Chromium Code Reviews| 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 |