Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Unified Diff: chromeos/compat-wireless/net/mac80211/mlme.c

Issue 5326002: Update compat-wireless to 2.6.36-5-spn (Closed) Base URL: http://git.chromium.org/git/kernel.git@master
Patch Set: Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chromeos/compat-wireless/net/mac80211/mlme.c
diff --git a/chromeos/compat-wireless/net/mac80211/mlme.c b/chromeos/compat-wireless/net/mac80211/mlme.c
index 0c8510c49215263ed061a9e811311d0496fa4b20..873af1d691076661ea06f0da1c2e7a9c26344a59 100644
--- a/chromeos/compat-wireless/net/mac80211/mlme.c
+++ b/chromeos/compat-wireless/net/mac80211/mlme.c
@@ -28,17 +28,19 @@
#include "rate.h"
#include "led.h"
-#define IEEE80211_MAX_PROBE_TRIES 1
+#define IEEE80211_MAX_NULLFUNC_TRIES 2
Sam Leffler 2010/12/01 00:23:44 lost local change
+#define IEEE80211_MAX_PROBE_TRIES 5
/*
- * beacon loss timeout is calculated as N frames times the
+ * Beacon loss timeout is calculated as N frames times the
* advertised beacon interval. This may need to be somewhat
* higher than what hardware might detect to account for
* delays in the host processing frames. But since we also
- * probe on bmiss before declaring the connection lost default
- * to what we want.
+ * probe on beacon miss before declaring the connection lost
+ * default to what we want.
*/
-#define IEEE80211_BEACON_LOSS_COUNT 7
+#define IEEE80211_BEACON_LOSS_COUNT 7
+
/*
* Time the connection can be idle before we probe
* it to see if we can still talk to the AP.
@@ -49,7 +51,7 @@
* a probe request because of beacon loss or for
* checking the connection still works.
*/
-#define IEEE80211_PROBE_WAIT (HZ / 5)
+#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
/*
* Weight given to the latest Beacon frame when calculating average signal
@@ -58,12 +60,6 @@
*/
#define IEEE80211_SIGNAL_AVE_WEIGHT 3
-/*
- * How many Beacon frames need to have been used in average signal strength
- * before starting to indicate signal change events.
- */
-#define IEEE80211_SIGNAL_AVE_MIN_COUNT 4
-
#define TMR_RUNNING_TIMER 0
#define TMR_RUNNING_CHANSW 1
@@ -125,7 +121,7 @@ void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
return;
mod_timer(&sdata->u.mgd.bcn_mon_timer,
- round_jiffies_up(jiffies + sdata->u.mgd.bloss_timeout));
+ round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout));
}
void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
@@ -872,15 +868,15 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
bss_info_changed |= BSS_CHANGED_ASSOC;
/* set timing information */
bss_conf->beacon_int = cbss->beacon_interval;
- /* beacon_int is in TU, convert to jiffies for timer handling */
- sdata->u.mgd.bloss_timeout = usecs_to_jiffies(ieee80211_tu_to_usec(
- IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int));
bss_conf->timestamp = cbss->tsf;
bss_info_changed |= BSS_CHANGED_BEACON_INT;
bss_info_changed |= ieee80211_handle_bss_capability(sdata,
cbss->capability, bss->has_erp_value, bss->erp_value);
+ sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec(
+ IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int));
+
sdata->u.mgd.associated = cbss;
memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
@@ -939,7 +935,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
}
static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
- bool remove_sta, bool tx)
+ bool remove_sta)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_local *local = sdata->local;
@@ -978,7 +974,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
sta = sta_info_get(sdata, bssid);
if (sta) {
set_sta_flags(sta, WLAN_STA_BLOCK_BA);
- ieee80211_sta_tear_down_BA_sessions(sta, tx);
+ ieee80211_sta_tear_down_BA_sessions(sta);
}
mutex_unlock(&local->sta_mtx);
@@ -1039,21 +1035,83 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
ieee80211_sta_reset_conn_monitor(sdata);
}
+static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+ if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
+ IEEE80211_STA_CONNECTION_POLL)))
+ return;
+
+ ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
+ IEEE80211_STA_BEACON_POLL);
+ mutex_lock(&sdata->local->iflist_mtx);
+ ieee80211_recalc_ps(sdata->local, -1);
+ mutex_unlock(&sdata->local->iflist_mtx);
+
+ if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
+ return;
+
+ /*
+ * We've received a probe response, but are not sure whether
+ * we have or will be receiving any beacons or data, so let's
+ * schedule the timers again, just in case.
+ */
+ ieee80211_sta_reset_beacon_monitor(sdata);
+
+ mod_timer(&ifmgd->conn_mon_timer,
+ round_jiffies_up(jiffies +
+ IEEE80211_CONNECTION_IDLE_TIME));
+}
+
+void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_hdr *hdr)
+{
+ if (!ieee80211_is_data(hdr->frame_control) &&
+ !ieee80211_is_nullfunc(hdr->frame_control))
Sam Leffler 2010/12/01 00:23:44 should be able to recognize NullData frame w/ one
+ return;
+
+ ieee80211_sta_reset_conn_monitor(sdata);
+
+ if (ieee80211_is_nullfunc(hdr->frame_control) &&
+ sdata->u.mgd.probe_send_count > 0) {
+ sdata->u.mgd.probe_send_count = 0;
+ ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+ }
+}
+
static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
const u8 *ssid;
u8 *dst = ifmgd->associated->bssid;
+ u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3);
+ /*
+ * Try sending broadcast probe requests for the last three
+ * probe requests after the first ones failed since some
+ * buggy APs only support broadcast probe requests.
+ */
+ if (ifmgd->probe_send_count >= unicast_limit)
+ dst = NULL;
- if ((sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
+ /*
+ * When the hardware reports an accurate Tx ACK status, it's
+ * better to send a nullfunc frame instead of a probe request,
+ * as it will kick us off the AP quickly if we aren't associated
+ * anymore. The timeout will be reset if the frame is ACKed by
+ * the AP.
+ */
+ if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
ieee80211_send_nullfunc(sdata->local, sdata, 0);
- } else {
+ else {
ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
}
ifmgd->probe_send_count++;
+ ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
+ 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
}
static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
@@ -1131,7 +1189,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);
- ieee80211_set_disassoc(sdata, true, true);
+ ieee80211_set_disassoc(sdata, true);
Sam Leffler 2010/12/01 00:23:44 missing local changes
ieee80211_recalc_idle(local);
mutex_unlock(&ifmgd->mtx);
/*
@@ -1209,7 +1267,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
sdata->name, bssid, reason_code);
- ieee80211_set_disassoc(sdata, true, false);
+ ieee80211_set_disassoc(sdata, true);
ieee80211_recalc_idle(sdata->local);
return RX_MGMT_CFG80211_DEAUTH;
@@ -1239,7 +1297,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
sdata->name, mgmt->sa, reason_code);
- ieee80211_set_disassoc(sdata, true, false);
+ ieee80211_set_disassoc(sdata, true);
ieee80211_recalc_idle(sdata->local);
return RX_MGMT_CFG80211_DISASSOC;
}
@@ -1485,29 +1543,8 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
if (ifmgd->associated &&
- memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0 &&
- ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
- IEEE80211_STA_CONNECTION_POLL)) {
- ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
- IEEE80211_STA_BEACON_POLL);
- mutex_lock(&sdata->local->iflist_mtx);
- ieee80211_recalc_ps(sdata->local, -1);
- mutex_unlock(&sdata->local->iflist_mtx);
-
- if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
- return;
-
- /*
- * We've received a probe response, but are not sure whether
- * we have or will be receiving any beacons or data, so let's
- * schedule the timers again, just in case.
- */
- ieee80211_sta_reset_beacon_monitor(sdata);
-
- mod_timer(&ifmgd->conn_mon_timer,
- round_jiffies_up(jiffies +
- IEEE80211_CONNECTION_IDLE_TIME));
- }
+ memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0)
+ ieee80211_reset_ap_probe(sdata);
}
/*
@@ -1579,16 +1616,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
ifmgd->ave_beacon_signal = rx_status->signal * 16;
ifmgd->last_cqm_event_signal = 0;
- ifmgd->count_beacon_signal = 1;
} else {
ifmgd->ave_beacon_signal =
(IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
(16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
ifmgd->ave_beacon_signal) / 16;
- ifmgd->count_beacon_signal++;
}
if (bss_conf->cqm_rssi_thold &&
- ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
int sig = ifmgd->ave_beacon_signal / 16;
int last_event = ifmgd->last_cqm_event_signal;
@@ -1846,84 +1880,66 @@ static void ieee80211_sta_timer(unsigned long data)
void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
{
- /* nothing right now */
-}
-
-static void ieee80211_sta_process_probe_status(struct ieee80211_sub_if_data *sdata)
-{
- struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_local *local = sdata->local;
- u8 bssid[ETH_ALEN];
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ /* then process the rest of the work */
mutex_lock(&ifmgd->mtx);
- if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
- IEEE80211_STA_CONNECTION_POLL)))
- goto done;
- if (!ifmgd->associated) /* XXX can this fail if flags are set? */
- goto done;
- memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
- if (ifmgd->probe_acked) {
- /*
- * Probe frame was ACK'd, just clear polling state.
- */
- ifmgd->flags &= ~(IEEE80211_STA_BEACON_POLL |
- IEEE80211_STA_CONNECTION_POLL);
- ifmgd->probe_send_count = 0;
+ if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
+ IEEE80211_STA_CONNECTION_POLL) &&
+ ifmgd->associated) {
+ u8 bssid[ETH_ALEN];
+ int max_tries;
- /*
- * Re-enable power save
- */
- mutex_lock(&local->iflist_mtx);
- ieee80211_recalc_ps(local, -1);
- mutex_unlock(&local->iflist_mtx);
- } else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "No ACK of probe to AP %pM, try again (%d)\n",
- bssid, ifmgd->probe_send_count);
-#endif
- ieee80211_mgd_probe_ap_send(sdata);
- } else {
- /*
- * We actually lost the connection.
- */
- ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
- IEEE80211_STA_BEACON_POLL);
+ memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
- /* XXX juggle __ieee80211_connection_loss to suit */
- printk(KERN_DEBUG "No response from AP %pM, disconnecting.\n",
- bssid);
+ if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
+ max_tries = IEEE80211_MAX_NULLFUNC_TRIES;
+ else
+ max_tries = IEEE80211_MAX_PROBE_TRIES;
- ieee80211_set_disassoc(sdata, true, true);
- ieee80211_recalc_idle(local);
+ /* ACK received for nullfunc probing frame */
+ if (!ifmgd->probe_send_count)
+ ieee80211_reset_ap_probe(sdata);
- /*
- * NB: must be outside lock due to cfg80211.
- */
- mutex_unlock(&ifmgd->mtx);
- ieee80211_send_deauth_disassoc(sdata, bssid,
- IEEE80211_STYPE_DEAUTH,
- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
- NULL, true);
- return;
- }
-done:
- mutex_unlock(&ifmgd->mtx);
-}
+ else if (time_is_after_jiffies(ifmgd->probe_timeout))
+ run_again(ifmgd, ifmgd->probe_timeout);
-/*
- * Process TX status for probe frame sent to the associated
- * AP on beacon or connection loss.
- */
-static void ieee80211_probe_status_work(struct work_struct *work)
-{
- struct ieee80211_sub_if_data *sdata = container_of(work,
- struct ieee80211_sub_if_data, u.mgd.probe_status_work);
-
- WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION);
+ else if (ifmgd->probe_send_count < max_tries) {
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ printk(KERN_DEBUG "No probe response from AP %pM"
+ " after %dms, try %d\n", bssid,
+ (1000 * IEEE80211_PROBE_WAIT)/HZ,
+ ifmgd->probe_send_count);
+#endif
+ ieee80211_mgd_probe_ap_send(sdata);
+ } else {
+ /*
+ * We actually lost the connection ... or did we?
+ * Let's make sure!
Sam Leffler 2010/12/01 00:23:44 comment is wrong
+ */
+ ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
+ IEEE80211_STA_BEACON_POLL);
+ printk(KERN_DEBUG "No probe response from AP %pM"
+ " after %dms, disconnecting.\n",
+ 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
+ ieee80211_set_disassoc(sdata, true);
+ ieee80211_recalc_idle(local);
+ mutex_unlock(&ifmgd->mtx);
+ /*
+ * must be outside lock due to cfg80211,
+ * but that's not a problem.
+ */
+ ieee80211_send_deauth_disassoc(sdata, bssid,
+ IEEE80211_STYPE_DEAUTH,
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
+ NULL, true);
+ mutex_lock(&ifmgd->mtx);
+ }
+ }
- if (ieee80211_sdata_running(sdata))
- ieee80211_sta_process_probe_status(sdata);
+ mutex_unlock(&ifmgd->mtx);
}
static void ieee80211_sta_bcn_mon_timer(unsigned long data)
@@ -1967,6 +1983,9 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL |
IEEE80211_STA_CONNECTION_POLL);
+ /* let's probe the connection once */
+ ieee80211_queue_work(&sdata->local->hw,
+ &sdata->u.mgd.monitor_work);
/* and do all the other regular work too */
ieee80211_queue_work(&sdata->local->hw, &sdata->work);
}
@@ -2005,9 +2024,8 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
add_timer(&ifmgd->timer);
if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
add_timer(&ifmgd->chswitch_timer);
-
ieee80211_sta_reset_beacon_monitor(sdata);
- ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.monitor_work);
+ 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
}
#endif
@@ -2021,7 +2039,6 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
INIT_WORK(&ifmgd->beacon_connection_loss_work,
ieee80211_beacon_connection_loss_work);
- INIT_WORK(&ifmgd->probe_status_work, ieee80211_probe_status_work);
INIT_WORK(&ifmgd->bitrate_notify_work, ieee80211_rate_notify_work);
setup_timer(&ifmgd->timer, ieee80211_sta_timer,
(unsigned long) sdata);
@@ -2229,7 +2246,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
}
/* Trying to reassociate - clear previous association state */
- ieee80211_set_disassoc(sdata, true, false);
+ ieee80211_set_disassoc(sdata, true);
}
mutex_unlock(&ifmgd->mtx);
@@ -2338,7 +2355,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
memcpy(bssid, req->bss->bssid, ETH_ALEN);
if (ifmgd->associated == req->bss) {
- ieee80211_set_disassoc(sdata, false, true);
+ ieee80211_set_disassoc(sdata, false);
mutex_unlock(&ifmgd->mtx);
assoc_bss = true;
} else {
@@ -2419,7 +2436,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
sdata->name, req->bss->bssid, req->reason_code);
memcpy(bssid, req->bss->bssid, ETH_ALEN);
- ieee80211_set_disassoc(sdata, false, true);
+ ieee80211_set_disassoc(sdata, false);
mutex_unlock(&ifmgd->mtx);

Powered by Google App Engine
This is Rietveld 408576698