Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 203739
b: refs/heads/master
c: 7a17a33
h: refs/heads/master
i:
  203737: 40a5bb2
  203735: c8ac1be
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Jul 21, 2010
1 parent ababd6d commit bdf06ad
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 51 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bc05d19f4b884b1dbbce48912710ae3f972c89d2
refs/heads/master: 7a17a33c0da37f8d24222c967550d19dabf13617
97 changes: 52 additions & 45 deletions trunk/net/mac80211/ibss.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
{
u16 auth_alg, auth_transaction, status_code;

lockdep_assert_held(&sdata->u.ibss.mtx);

if (len < 24 + 6)
return;

Expand Down Expand Up @@ -78,6 +80,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
u32 bss_change;
u8 supp_rates[IEEE80211_MAX_SUPP_RATES];

lockdep_assert_held(&ifibss->mtx);

/* Reset own TSF to allow time synchronization work. */
drv_reset_tsf(local);

Expand Down Expand Up @@ -205,6 +209,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
int i, j;
u16 beacon_int = cbss->beacon_interval;

lockdep_assert_held(&sdata->u.ibss.mtx);

if (beacon_int < 10)
beacon_int = 10;

Expand Down Expand Up @@ -449,6 +455,8 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
int active = 0;
struct sta_info *sta;

lockdep_assert_held(&sdata->u.ibss.mtx);

rcu_read_lock();

list_for_each_entry_rcu(sta, &local->sta_list, list) {
Expand All @@ -473,6 +481,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;

lockdep_assert_held(&ifibss->mtx);

mod_timer(&ifibss->timer,
round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));

Expand Down Expand Up @@ -505,6 +515,8 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
u16 capability;
int i;

lockdep_assert_held(&ifibss->mtx);

if (ifibss->fixed_bssid) {
memcpy(bssid, ifibss->bssid, ETH_ALEN);
} else {
Expand Down Expand Up @@ -549,6 +561,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
int active_ibss;
u16 capability;

lockdep_assert_held(&ifibss->mtx);

active_ibss = ieee80211_sta_active_ibss(sdata);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
Expand Down Expand Up @@ -637,6 +651,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *resp;
u8 *pos, *end;

lockdep_assert_held(&ifibss->mtx);

if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
len < 24 + 2 || !ifibss->presp)
return;
Expand Down Expand Up @@ -740,6 +756,8 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
mgmt = (struct ieee80211_mgmt *) skb->data;
fc = le16_to_cpu(mgmt->frame_control);

mutex_lock(&sdata->u.ibss.mtx);

switch (fc & IEEE80211_FCTL_STYPE) {
case IEEE80211_STYPE_PROBE_REQ:
ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len);
Expand All @@ -756,14 +774,23 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
ieee80211_rx_mgmt_auth_ibss(sdata, mgmt, skb->len);
break;
}

mutex_unlock(&sdata->u.ibss.mtx);
}

void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;

if (!test_and_clear_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request))
return;
mutex_lock(&ifibss->mtx);

/*
* Work could be scheduled after scan or similar
* when we aren't even joined (or trying) with a
* network.
*/
if (!ifibss->ssid_len)
goto out;

switch (ifibss->state) {
case IEEE80211_IBSS_MLME_SEARCH:
Expand All @@ -776,15 +803,9 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
WARN_ON(1);
break;
}
}

static void ieee80211_queue_ibss_work(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local;

set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
ieee80211_queue_work(&local->hw, &sdata->work);
out:
mutex_unlock(&ifibss->mtx);
}

static void ieee80211_ibss_timer(unsigned long data)
Expand All @@ -799,7 +820,7 @@ static void ieee80211_ibss_timer(unsigned long data)
return;
}

ieee80211_queue_ibss_work(sdata);
ieee80211_queue_work(&local->hw, &sdata->work);
}

#ifdef CONFIG_PM
Expand Down Expand Up @@ -828,6 +849,7 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)

setup_timer(&ifibss->timer, ieee80211_ibss_timer,
(unsigned long) sdata);
mutex_init(&ifibss->mtx);
}

/* scan finished notification */
Expand All @@ -841,10 +863,8 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
continue;
if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
continue;
if (!sdata->u.ibss.ssid_len)
continue;
sdata->u.ibss.last_scan_completed = jiffies;
ieee80211_queue_ibss_work(sdata);
ieee80211_queue_work(&local->hw, &sdata->work);
}
mutex_unlock(&local->iflist_mtx);
}
Expand All @@ -854,6 +874,17 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
{
struct sk_buff *skb;

skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
36 /* bitrates */ +
34 /* SSID */ +
3 /* DS params */ +
4 /* IBSS params */ +
params->ie_len);
if (!skb)
return -ENOMEM;

mutex_lock(&sdata->u.ibss.mtx);

if (params->bssid) {
memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
sdata->u.ibss.fixed_bssid = true;
Expand Down Expand Up @@ -882,35 +913,19 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
sdata->u.ibss.ie_len = params->ie_len;
}

skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
36 /* bitrates */ +
34 /* SSID */ +
3 /* DS params */ +
4 /* IBSS params */ +
params->ie_len);
if (!skb)
return -ENOMEM;

sdata->u.ibss.skb = skb;
sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
sdata->u.ibss.ibss_join_req = jiffies;

memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);

/*
* The ssid_len setting below is used to see whether
* we are active, and we need all other settings
* before that may get visible.
*/
mb();

sdata->u.ibss.ssid_len = params->ssid_len;

ieee80211_recalc_idle(sdata->local);

set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
ieee80211_queue_work(&sdata->local->hw, &sdata->work);

mutex_unlock(&sdata->u.ibss.mtx);

return 0;
}

Expand All @@ -921,7 +936,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
struct ieee80211_local *local = sdata->local;
struct cfg80211_bss *cbss;
u16 capability;
int active_ibss = 0;
int active_ibss;

mutex_lock(&sdata->u.ibss.mtx);

active_ibss = ieee80211_sta_active_ibss(sdata);

Expand Down Expand Up @@ -959,19 +976,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
sdata->u.ibss.ssid_len = 0;

/*
* ssid_len indicates active or not, so needs to be visible to
* everybody, especially ieee80211_ibss_notify_scan_completed,
* so it won't restart the timer after we remove it here.
*/
mb();

del_timer_sync(&sdata->u.ibss.timer);
clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
/*
* Since the REQ_RUN bit is clear, the work won't do
* anything if it runs after this.
*/

mutex_unlock(&sdata->u.ibss.mtx);

ieee80211_recalc_idle(sdata->local);

Expand Down
7 changes: 2 additions & 5 deletions trunk/net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,14 +377,11 @@ struct ieee80211_if_managed {
int last_cqm_event_signal;
};

enum ieee80211_ibss_request {
IEEE80211_IBSS_REQ_RUN = 0,
};

struct ieee80211_if_ibss {
struct timer_list timer;

unsigned long request;
struct mutex mtx;

unsigned long last_scan_completed;

u32 basic_rates;
Expand Down

0 comments on commit bdf06ad

Please sign in to comment.