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/08 18:37:56
until we can override upstream defaults w/o modify
| |
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) |
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 138 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, bool ack) | |
1069 { | |
1070 if (!ieee80211_is_data(hdr->frame_control)) | |
Sam Leffler
2010/12/08 18:37:56
this should check is_nullfunc instead and remove t
| |
1071 return; | |
1072 | |
1073 if (ack) | |
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 if (ack) | |
1079 sdata->u.mgd.probe_send_count = 0; | |
1080 else | |
1081 sdata->u.mgd.nullfunc_failed = true; | |
1082 ieee80211_queue_work(&sdata->local->hw, &sdata->work); | |
Sam Leffler
2010/12/08 18:37:56
this code is confusing because there are no commen
| |
1083 } | |
1084 } | |
1085 | |
1042 static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | 1086 static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) |
1043 { | 1087 { |
1044 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1088 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1045 const u8 *ssid; | 1089 const u8 *ssid; |
1046 u8 *dst = ifmgd->associated->bssid; | 1090 u8 *dst = ifmgd->associated->bssid; |
1091 u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3); | |
1047 | 1092 |
1093 /* | |
1094 * Try sending broadcast probe requests for the last three | |
1095 * probe requests after the first ones failed since some | |
1096 * buggy APs only support broadcast probe requests. | |
1097 */ | |
1098 if (ifmgd->probe_send_count >= unicast_limit) | |
1099 dst = NULL; | |
1048 | 1100 |
1049 » if ((sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { | 1101 » /* |
1102 » * When the hardware reports an accurate Tx ACK status, it's | |
1103 » * better to send a nullfunc frame instead of a probe request, | |
1104 » * as it will kick us off the AP quickly if we aren't associated | |
1105 » * anymore. The timeout will be reset if the frame is ACKed by | |
1106 » * the AP. | |
1107 » */ | |
1108 » if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { | |
1109 » » ifmgd->nullfunc_failed = false; | |
Sam Leffler
2010/12/08 18:37:56
it appears you are setting this here because the w
| |
1050 ieee80211_send_nullfunc(sdata->local, sdata, 0); | 1110 ieee80211_send_nullfunc(sdata->local, sdata, 0); |
1051 } else { | 1111 } else { |
1052 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); | 1112 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); |
1053 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0) ; | 1113 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0) ; |
1054 } | 1114 } |
1055 | 1115 |
1056 ifmgd->probe_send_count++; | 1116 ifmgd->probe_send_count++; |
1117 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; | |
1118 run_again(ifmgd, ifmgd->probe_timeout); | |
1057 } | 1119 } |
1058 | 1120 |
1059 static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | 1121 static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, |
1060 bool beacon) | 1122 bool beacon) |
1061 { | 1123 { |
1062 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1124 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1063 bool already = false; | 1125 bool already = false; |
1064 | 1126 |
1065 if (!ieee80211_sdata_running(sdata)) | 1127 if (!ieee80211_sdata_running(sdata)) |
1066 return; | 1128 return; |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1478 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; | 1540 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; |
1479 if (baselen > len) | 1541 if (baselen > len) |
1480 return; | 1542 return; |
1481 | 1543 |
1482 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | 1544 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, |
1483 &elems); | 1545 &elems); |
1484 | 1546 |
1485 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); | 1547 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); |
1486 | 1548 |
1487 if (ifmgd->associated && | 1549 if (ifmgd->associated && |
1488 » memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0 && | 1550 » memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0) |
1489 » ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | 1551 » » 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 } | 1552 } |
1512 | 1553 |
1513 /* | 1554 /* |
1514 * This is the canonical list of information elements we care about, | 1555 * This is the canonical list of information elements we care about, |
1515 * the filter code also gives us all changes to the Microsoft OUI | 1556 * 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. | 1557 * (00:50:F2) vendor IE which is used for WMM which we need to track. |
1517 * | 1558 * |
1518 * We implement beacon filtering in software since that means we can | 1559 * We implement beacon filtering in software since that means we can |
1519 * avoid processing the frame here and in cfg80211, and userspace | 1560 * avoid processing the frame here and in cfg80211, and userspace |
1520 * will not be able to tell whether the hardware supports it or not. | 1561 * 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 */ | 1613 */ |
1573 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0) | 1614 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0) |
1574 return; | 1615 return; |
1575 | 1616 |
1576 /* Track average RSSI from the Beacon frames of the current AP */ | 1617 /* Track average RSSI from the Beacon frames of the current AP */ |
1577 ifmgd->last_beacon_signal = rx_status->signal; | 1618 ifmgd->last_beacon_signal = rx_status->signal; |
1578 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { | 1619 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { |
1579 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; | 1620 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; |
1580 ifmgd->ave_beacon_signal = rx_status->signal * 16; | 1621 ifmgd->ave_beacon_signal = rx_status->signal * 16; |
1581 ifmgd->last_cqm_event_signal = 0; | 1622 ifmgd->last_cqm_event_signal = 0; |
1582 ifmgd->count_beacon_signal = 1; | |
1583 } else { | 1623 } else { |
1584 ifmgd->ave_beacon_signal = | 1624 ifmgd->ave_beacon_signal = |
1585 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 + | 1625 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 + |
1586 (16 - IEEE80211_SIGNAL_AVE_WEIGHT) * | 1626 (16 - IEEE80211_SIGNAL_AVE_WEIGHT) * |
1587 ifmgd->ave_beacon_signal) / 16; | 1627 ifmgd->ave_beacon_signal) / 16; |
1588 ifmgd->count_beacon_signal++; | |
1589 } | 1628 } |
1590 if (bss_conf->cqm_rssi_thold && | 1629 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)) { | 1630 !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { |
1593 int sig = ifmgd->ave_beacon_signal / 16; | 1631 int sig = ifmgd->ave_beacon_signal / 16; |
1594 int last_event = ifmgd->last_cqm_event_signal; | 1632 int last_event = ifmgd->last_cqm_event_signal; |
1595 int thold = bss_conf->cqm_rssi_thold; | 1633 int thold = bss_conf->cqm_rssi_thold; |
1596 int hyst = bss_conf->cqm_rssi_hyst; | 1634 int hyst = bss_conf->cqm_rssi_hyst; |
1597 if (sig < thold && | 1635 if (sig < thold && |
1598 (last_event == 0 || sig < last_event - hyst)) { | 1636 (last_event == 0 || sig < last_event - hyst)) { |
1599 ifmgd->last_cqm_event_signal = sig; | 1637 ifmgd->last_cqm_event_signal = sig; |
1600 ieee80211_cqm_rssi_notify( | 1638 ieee80211_cqm_rssi_notify( |
1601 &sdata->vif, | 1639 &sdata->vif, |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1837 struct ieee80211_local *local = sdata->local; | 1875 struct ieee80211_local *local = sdata->local; |
1838 | 1876 |
1839 if (local->quiescing) { | 1877 if (local->quiescing) { |
1840 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); | 1878 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); |
1841 return; | 1879 return; |
1842 } | 1880 } |
1843 | 1881 |
1844 ieee80211_queue_work(&local->hw, &sdata->work); | 1882 ieee80211_queue_work(&local->hw, &sdata->work); |
1845 } | 1883 } |
1846 | 1884 |
1885 static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | |
1886 u8 *bssid) | |
1887 { | |
1888 struct ieee80211_local *local = sdata->local; | |
1889 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | |
1890 | |
1891 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | |
1892 IEEE80211_STA_BEACON_POLL); | |
1893 | |
1894 ieee80211_set_disassoc(sdata, true, true); | |
1895 ieee80211_recalc_idle(local); | |
1896 mutex_unlock(&ifmgd->mtx); | |
1897 /* | |
1898 * must be outside lock due to cfg80211, | |
1899 * but that's not a problem. | |
1900 */ | |
1901 ieee80211_send_deauth_disassoc(sdata, bssid, | |
1902 IEEE80211_STYPE_DEAUTH, | |
1903 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | |
1904 NULL, true); | |
1905 mutex_lock(&ifmgd->mtx); | |
1906 } | |
1907 | |
1847 void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | 1908 void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) |
1848 { | 1909 { |
1849 » /* nothing right now */ | 1910 » struct ieee80211_local *local = sdata->local; |
1850 } | 1911 » struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1851 | 1912 |
1852 static void ieee80211_sta_process_probe_status(struct ieee80211_sub_if_data *sda ta) | 1913 » /* 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); | 1914 mutex_lock(&ifmgd->mtx); |
1859 | 1915 |
1860 » if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | 1916 » if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | |
1861 » » » IEEE80211_STA_CONNECTION_POLL))) | 1917 » » » IEEE80211_STA_CONNECTION_POLL) && |
1862 » » goto done; | 1918 » ifmgd->associated) { |
1863 » if (!ifmgd->associated)»/* XXX can this fail if flags are set? */ | 1919 » » u8 bssid[ETH_ALEN]; |
1864 » » goto done; | 1920 » » 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 | 1921 |
1874 » » /* | 1922 » » memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); |
1875 » » * Re-enable power save | 1923 |
1876 » » */ | 1924 » » if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) |
1877 » » mutex_lock(&local->iflist_mtx); | 1925 » » » max_tries = IEEE80211_MAX_NULLFUNC_TRIES; |
1878 » » ieee80211_recalc_ps(local, -1); | 1926 » » else |
1879 » » mutex_unlock(&local->iflist_mtx); | 1927 » » » max_tries = IEEE80211_MAX_PROBE_TRIES; |
Sam Leffler
2010/12/08 18:37:56
I find this combined code too complicated; I think
| |
1880 » } else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { | 1928 |
1929 » » /* ACK received for nullfunc probing frame */ | |
1930 » » if (!ifmgd->probe_send_count) | |
1931 » » » ieee80211_reset_ap_probe(sdata); | |
1932 » » else if (ifmgd->nullfunc_failed) { | |
1933 » » » if (ifmgd->probe_send_count < max_tries) { | |
1881 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1934 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1882 » » printk(KERN_DEBUG "No ACK of probe to AP %pM, try again (%d)\n", | 1935 » » » » wiphy_debug(local->hw.wiphy, |
1883 » » » bssid, ifmgd->probe_send_count); | 1936 » » » » » "%s: No ack for nullfunc frame to" |
1937 » » » » » " AP %pM, try %d\n", | |
1938 » » » » » sdata->name, bssid, | |
1939 » » » » » ifmgd->probe_send_count); | |
1884 #endif | 1940 #endif |
1885 » » ieee80211_mgd_probe_ap_send(sdata); | 1941 » » » » ieee80211_mgd_probe_ap_send(sdata); |
1886 » } else { | 1942 » » » } else { |
1887 » » /* | 1943 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1888 » » * We actually lost the connection. | 1944 » » » » wiphy_debug(local->hw.wiphy, |
1889 » » */ | 1945 » » » » » "%s: No ack for nullfunc frame to" |
1890 » » ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 1946 » » » » » " AP %pM, disconnecting.\n", |
1891 » » » » IEEE80211_STA_BEACON_POLL); | 1947 » » » » » sdata->name, bssid, |
1948 » » » » » ifmgd->probe_send_count); | |
1949 #endif | |
1950 » » » » ieee80211_sta_connection_lost(sdata, bssid); | |
1951 » » » } | |
1952 » » } else if (time_is_after_jiffies(ifmgd->probe_timeout)) | |
1953 » » » run_again(ifmgd, ifmgd->probe_timeout); | |
1954 » » else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { | |
Sam Leffler
2010/12/08 18:37:56
how do we get to this case? If we have TX status
| |
1955 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | |
1956 » » » wiphy_debug(local->hw.wiphy, | |
1957 » » » » "%s: Failed to send nullfunc to AP %pM" | |
1958 » » » » " after %dms, disconnecting.\n", | |
1959 » » » » sdata->name, | |
1960 » » » » bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); | |
1961 #endif | |
1962 » » » ieee80211_sta_connection_lost(sdata, bssid); | |
1963 » » } else if (ifmgd->probe_send_count < max_tries) { | |
1964 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | |
1965 » » » printk(KERN_DEBUG "No probe response from AP %pM" | |
1966 » » » » " after %dms, try %d\n", bssid, | |
1967 » » » » (1000 * IEEE80211_PROBE_WAIT)/HZ, | |
1968 » » » » ifmgd->probe_send_count); | |
1969 #endif | |
1970 » » » ieee80211_mgd_probe_ap_send(sdata); | |
1971 » » } else { | |
1972 » » » /* | |
1973 » » » * We actually lost the connection ... or did we? | |
1974 » » » * Let's make sure! | |
1975 » » » */ | |
1976 » » » printk(KERN_DEBUG "No probe response from AP %pM" | |
1977 » » » » " after %dms, disconnecting.\n", | |
1978 » » » » bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); | |
1892 | 1979 |
1893 » » /* XXX juggle __ieee80211_connection_loss to suit */ | 1980 » » » ieee80211_sta_connection_lost(sdata, bssid); |
1894 » » printk(KERN_DEBUG "No response from AP %pM, disconnecting.\n", | 1981 » » } |
1895 » » bssid); | 1982 » } |
1896 | 1983 |
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); | 1984 mutex_unlock(&ifmgd->mtx); |
1912 } | 1985 } |
1913 | 1986 |
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) | 1987 static void ieee80211_sta_bcn_mon_timer(unsigned long data) |
1930 { | 1988 { |
1931 struct ieee80211_sub_if_data *sdata = | 1989 struct ieee80211_sub_if_data *sdata = |
1932 (struct ieee80211_sub_if_data *) data; | 1990 (struct ieee80211_sub_if_data *) data; |
1933 struct ieee80211_local *local = sdata->local; | 1991 struct ieee80211_local *local = sdata->local; |
1934 | 1992 |
1935 if (local->quiescing) | 1993 if (local->quiescing) |
1936 return; | 1994 return; |
1937 | 1995 |
1938 ieee80211_queue_work(&sdata->local->hw, | 1996 ieee80211_queue_work(&sdata->local->hw, |
(...skipping 21 matching lines...) Expand all Loading... | |
1960 | 2018 |
1961 ieee80211_mgd_probe_ap(sdata, false); | 2019 ieee80211_mgd_probe_ap(sdata, false); |
1962 } | 2020 } |
1963 | 2021 |
1964 static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) | 2022 static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) |
1965 { | 2023 { |
1966 if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 2024 if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
1967 sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL | | 2025 sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL | |
1968 IEEE80211_STA_CONNECTION_POLL); | 2026 IEEE80211_STA_CONNECTION_POLL); |
1969 | 2027 |
2028 /* let's probe the connection once */ | |
2029 ieee80211_queue_work(&sdata->local->hw, | |
2030 &sdata->u.mgd.monitor_work); | |
1970 /* and do all the other regular work too */ | 2031 /* and do all the other regular work too */ |
1971 ieee80211_queue_work(&sdata->local->hw, &sdata->work); | 2032 ieee80211_queue_work(&sdata->local->hw, &sdata->work); |
1972 } | 2033 } |
1973 } | 2034 } |
1974 | 2035 |
1975 #ifdef CONFIG_PM | 2036 #ifdef CONFIG_PM |
1976 void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | 2037 void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) |
1977 { | 2038 { |
1978 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2039 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1979 | 2040 |
(...skipping 18 matching lines...) Expand all Loading... | |
1998 } | 2059 } |
1999 | 2060 |
2000 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | 2061 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) |
2001 { | 2062 { |
2002 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2063 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2003 | 2064 |
2004 if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running)) | 2065 if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running)) |
2005 add_timer(&ifmgd->timer); | 2066 add_timer(&ifmgd->timer); |
2006 if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) | 2067 if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) |
2007 add_timer(&ifmgd->chswitch_timer); | 2068 add_timer(&ifmgd->chswitch_timer); |
2008 | |
2009 ieee80211_sta_reset_beacon_monitor(sdata); | 2069 ieee80211_sta_reset_beacon_monitor(sdata); |
2010 » ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.monitor_work); | 2070 » ieee80211_restart_sta_timer(sdata); |
2011 } | 2071 } |
2012 #endif | 2072 #endif |
2013 | 2073 |
2014 /* interface setup */ | 2074 /* interface setup */ |
2015 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | 2075 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) |
2016 { | 2076 { |
2017 struct ieee80211_if_managed *ifmgd; | 2077 struct ieee80211_if_managed *ifmgd; |
2018 | 2078 |
2019 ifmgd = &sdata->u.mgd; | 2079 ifmgd = &sdata->u.mgd; |
2020 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); | 2080 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); |
2021 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); | 2081 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); |
2022 INIT_WORK(&ifmgd->beacon_connection_loss_work, | 2082 INIT_WORK(&ifmgd->beacon_connection_loss_work, |
2023 ieee80211_beacon_connection_loss_work); | 2083 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); | 2084 INIT_WORK(&ifmgd->bitrate_notify_work, ieee80211_rate_notify_work); |
2026 setup_timer(&ifmgd->timer, ieee80211_sta_timer, | 2085 setup_timer(&ifmgd->timer, ieee80211_sta_timer, |
2027 (unsigned long) sdata); | 2086 (unsigned long) sdata); |
2028 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, | 2087 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, |
2029 (unsigned long) sdata); | 2088 (unsigned long) sdata); |
2030 setup_timer(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, | 2089 setup_timer(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, |
2031 (unsigned long) sdata); | 2090 (unsigned long) sdata); |
2032 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, | 2091 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, |
2033 (unsigned long) sdata); | 2092 (unsigned long) sdata); |
2034 | 2093 |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2437 enum nl80211_cqm_rssi_threshold_event rssi_event, | 2496 enum nl80211_cqm_rssi_threshold_event rssi_event, |
2438 gfp_t gfp) | 2497 gfp_t gfp) |
2439 { | 2498 { |
2440 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 2499 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
2441 | 2500 |
2442 trace_api_cqm_rssi_notify(sdata, rssi_event); | 2501 trace_api_cqm_rssi_notify(sdata, rssi_event); |
2443 | 2502 |
2444 cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); | 2503 cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); |
2445 } | 2504 } |
2446 EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); | 2505 EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); |
OLD | NEW |