Skip to content

Commit

Permalink
mac80211: track beacons separately from the rx path activity
Browse files Browse the repository at this point in the history
Separate beacon and rx path tracking in preparation for the beacon filtering
support. At the same time change ieee80211_associated() to look a bit simpler.

Probe requests are now sent only after IEEE80211_PROBE_IDLE_TIME, which
is now set to 60 seconds.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Kalle Valo authored and John W. Linville committed Mar 28, 2009
1 parent 3cf335d commit 15b7b06
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 32 deletions.
1 change: 1 addition & 0 deletions net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ struct ieee80211_if_managed {
unsigned long request;

unsigned long last_probe;
unsigned long last_beacon;

unsigned int flags;

Expand Down
77 changes: 46 additions & 31 deletions net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
#define IEEE80211_ASSOC_MAX_TRIES 3
#define IEEE80211_MONITORING_INTERVAL (2 * HZ)
#define IEEE80211_PROBE_INTERVAL (60 * HZ)
#define IEEE80211_PROBE_IDLE_TIME (60 * HZ)
#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ)

/* utils */
Expand Down Expand Up @@ -930,7 +930,7 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
int disassoc;
bool disassoc = false;

/* TODO: start monitoring current AP signal quality and number of
* missed beacons. Scan other channels every now and then and search
Expand All @@ -945,36 +945,39 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
if (!sta) {
printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n",
sdata->dev->name, ifmgd->bssid);
disassoc = 1;
} else {
disassoc = 0;
if (time_after(jiffies,
sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) {
printk(KERN_DEBUG "%s: No ProbeResp from "
"current AP %pM - assume out of "
"range\n",
sdata->dev->name, ifmgd->bssid);
disassoc = 1;
} else
ieee80211_send_probe_req(sdata, ifmgd->bssid,
ifmgd->ssid,
ifmgd->ssid_len,
NULL, 0);
ifmgd->flags ^= IEEE80211_STA_PROBEREQ_POLL;
} else {
ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
if (time_after(jiffies, ifmgd->last_probe +
IEEE80211_PROBE_INTERVAL)) {
ifmgd->last_probe = jiffies;
ieee80211_send_probe_req(sdata, ifmgd->bssid,
ifmgd->ssid,
ifmgd->ssid_len,
NULL, 0);
}
}
disassoc = true;
goto unlock;
}

if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) &&
time_after(jiffies, sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
printk(KERN_DEBUG "%s: no probe response from AP %pM "
"- disassociating\n",
sdata->dev->name, ifmgd->bssid);
disassoc = true;
ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
goto unlock;
}

if (time_after(jiffies,
ifmgd->last_beacon + IEEE80211_MONITORING_INTERVAL)) {
printk(KERN_DEBUG "%s: beacon loss from AP %pM "
"- sending probe request\n",
sdata->dev->name, ifmgd->bssid);
ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
ifmgd->ssid_len, NULL, 0);
goto unlock;

}

if (time_after(jiffies, sta->last_rx + IEEE80211_PROBE_IDLE_TIME)) {
ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
ifmgd->ssid_len, NULL, 0);
}

unlock:
rcu_read_unlock();

if (disassoc)
Expand Down Expand Up @@ -1374,6 +1377,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
bss_conf->assoc_capability = capab_info;
ieee80211_set_associated(sdata, changed);

/*
* initialise the time of last beacon to be the association time,
* otherwise beacon loss check will trigger immediately
*/
ifmgd->last_beacon = jiffies;

ieee80211_associated(sdata);
cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len);
}
Expand Down Expand Up @@ -1422,9 +1431,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
size_t len,
struct ieee80211_rx_status *rx_status)
{
struct ieee80211_if_managed *ifmgd;
size_t baselen;
struct ieee802_11_elems elems;

ifmgd = &sdata->u.mgd;

if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
return; /* ignore ProbeResp to foreign address */

Expand All @@ -1439,11 +1451,14 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,

/* direct probe may be part of the association flow */
if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE,
&sdata->u.mgd.request)) {
&ifmgd->request)) {
printk(KERN_DEBUG "%s direct probe responded\n",
sdata->dev->name);
ieee80211_authenticate(sdata);
}

if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL)
ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
}

static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
Expand Down
6 changes: 5 additions & 1 deletion net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,11 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
* Mesh beacons will update last_rx when if they are found to
* match the current local configuration when processed.
*/
sta->last_rx = jiffies;
if (rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
ieee80211_is_beacon(hdr->frame_control)) {
rx->sdata->u.mgd.last_beacon = jiffies;
} else
sta->last_rx = jiffies;
}

if (!(rx->flags & IEEE80211_RX_RA_MATCH))
Expand Down

0 comments on commit 15b7b06

Please sign in to comment.