diff options
author | Jiri Kosina <jkosina@suse.cz> | 2008-05-06 16:57:55 +0200 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2008-05-06 16:57:55 +0200 |
commit | 7022b15e2a9f878fd5184586064c63352c3dd225 (patch) | |
tree | 5365c2f5bc82ae1946636ee8d5cd5d3b7e804f1b /net/mac80211 | |
parent | aaad2b0c757f3e6e02552cb0bdcd91a5ec0d6305 (diff) | |
parent | a15306365a16380f3bafee9e181ba01231d4acd7 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/Kconfig | 4 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/main.c | 47 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 17 | ||||
-rw-r--r-- | net/mac80211/mesh.h | 3 | ||||
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 1 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 28 | ||||
-rw-r--r-- | net/mac80211/rx.c | 2 | ||||
-rw-r--r-- | net/mac80211/tkip.c | 6 | ||||
-rw-r--r-- | net/mac80211/wme.c | 2 |
10 files changed, 69 insertions, 43 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 520a5180a4f6..a24b459dd45a 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -73,7 +73,9 @@ config MAC80211_MESH config MAC80211_LEDS bool "Enable LED triggers" - depends on MAC80211 && LEDS_TRIGGERS + depends on MAC80211 + select NEW_LEDS + select LEDS_TRIGGERS ---help--- This option enables a few LED triggers for different packet receive/transmit events. diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8e53ce7ed444..c7314bf4bec2 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -354,7 +354,7 @@ struct ieee80211_if_sta { int preq_queue_len; struct mesh_stats mshstats; struct mesh_config mshcfg; - u8 mesh_seqnum[3]; + u32 mesh_seqnum; bool accepting_plinks; #endif u16 aid; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index e9a978979d38..9ad4e3631b6b 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -255,22 +255,8 @@ static int ieee80211_open(struct net_device *dev) switch (sdata->vif.type) { case IEEE80211_IF_TYPE_WDS: - if (is_zero_ether_addr(sdata->u.wds.remote_addr)) + if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) return -ENOLINK; - - /* Create STA entry for the WDS peer */ - sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, - GFP_KERNEL); - if (!sta) - return -ENOMEM; - - sta->flags |= WLAN_STA_AUTHORIZED; - - res = sta_info_insert(sta); - if (res) { - /* STA has been freed */ - return res; - } break; case IEEE80211_IF_TYPE_VLAN: if (!sdata->u.vlan.ap) @@ -337,10 +323,8 @@ static int ieee80211_open(struct net_device *dev) conf.type = sdata->vif.type; conf.mac_addr = dev->dev_addr; res = local->ops->add_interface(local_to_hw(local), &conf); - if (res && !local->open_count && local->ops->stop) - local->ops->stop(local_to_hw(local)); if (res) - return res; + goto err_stop; ieee80211_if_config(dev); ieee80211_reset_erp_info(dev); @@ -353,9 +337,29 @@ static int ieee80211_open(struct net_device *dev) netif_carrier_on(dev); } + if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) { + /* Create STA entry for the WDS peer */ + sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, + GFP_KERNEL); + if (!sta) { + res = -ENOMEM; + goto err_del_interface; + } + + sta->flags |= WLAN_STA_AUTHORIZED; + + res = sta_info_insert(sta); + if (res) { + /* STA has been freed */ + goto err_del_interface; + } + } + if (local->open_count == 0) { res = dev_open(local->mdev); WARN_ON(res); + if (res) + goto err_del_interface; tasklet_enable(&local->tx_pending_tasklet); tasklet_enable(&local->tasklet); } @@ -390,6 +394,12 @@ static int ieee80211_open(struct net_device *dev) netif_start_queue(dev); return 0; + err_del_interface: + local->ops->remove_interface(local_to_hw(local), &conf); + err_stop: + if (!local->open_count && local->ops->stop) + local->ops->stop(local_to_hw(local)); + return res; } static int ieee80211_stop(struct net_device *dev) @@ -975,6 +985,7 @@ static int __ieee80211_if_config(struct net_device *dev, conf.ssid_len = sdata->u.sta.ssid_len; } else if (ieee80211_vif_is_mesh(&sdata->vif)) { conf.beacon = beacon; + conf.beacon_control = control; ieee80211_start_mesh(dev); } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { conf.ssid = sdata->u.ap.ssid; diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 594a3356a508..f76bc26ae4d2 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include <asm/unaligned.h> #include "ieee80211_i.h" #include "mesh.h" @@ -167,8 +168,8 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, struct rmc_entry *p, *n; /* Don't care about endianness since only match matters */ - memcpy(&seqnum, mesh_hdr->seqnum, sizeof(mesh_hdr->seqnum)); - idx = mesh_hdr->seqnum[0] & rmc->idx_mask; + memcpy(&seqnum, &mesh_hdr->seqnum, sizeof(mesh_hdr->seqnum)); + idx = le32_to_cpu(mesh_hdr->seqnum) & rmc->idx_mask; list_for_each_entry_safe(p, n, &rmc->bucket[idx].list, list) { ++entries; if (time_after(jiffies, p->exp_time) || @@ -393,16 +394,8 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, { meshhdr->flags = 0; meshhdr->ttl = sdata->u.sta.mshcfg.dot11MeshTTL; - - meshhdr->seqnum[0] = sdata->u.sta.mesh_seqnum[0]++; - meshhdr->seqnum[1] = sdata->u.sta.mesh_seqnum[1]; - meshhdr->seqnum[2] = sdata->u.sta.mesh_seqnum[2]; - - if (sdata->u.sta.mesh_seqnum[0] == 0) { - sdata->u.sta.mesh_seqnum[1]++; - if (sdata->u.sta.mesh_seqnum[1] == 0) - sdata->u.sta.mesh_seqnum[2]++; - } + put_unaligned(cpu_to_le32(sdata->u.sta.mesh_seqnum), &meshhdr->seqnum); + sdata->u.sta.mesh_seqnum++; return 5; } diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 742003d3a841..2e161f6d8288 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -13,6 +13,7 @@ #include <linux/types.h> #include <linux/jhash.h> +#include <asm/unaligned.h> #include "ieee80211_i.h" @@ -139,7 +140,7 @@ struct rmc_entry { struct mesh_rmc { struct rmc_entry bucket[RMC_BUCKETS]; - u8 idx_mask; + u32 idx_mask; }; diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 02de8f1522a3..3df809222d1c 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -7,7 +7,6 @@ * published by the Free Software Foundation. */ -#include <asm/unaligned.h> #include "mesh.h" #define TEST_FRAME_LEN 8192 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 6b75cb6c6300..a5e5c31c23ab 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2248,10 +2248,13 @@ static void ieee80211_rx_bss_put(struct net_device *dev, struct ieee80211_sta_bss *bss) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - if (!atomic_dec_and_test(&bss->users)) + + local_bh_disable(); + if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) { + local_bh_enable(); return; + } - spin_lock_bh(&local->sta_bss_lock); __ieee80211_rx_bss_hash_del(dev, bss); list_del(&bss->list); spin_unlock_bh(&local->sta_bss_lock); @@ -2709,7 +2712,26 @@ static void ieee80211_rx_bss_info(struct net_device *dev, bss->wmm_ie_len = elems.wmm_param_len + 2; } else bss->wmm_ie_len = 0; - } else if (!elems.wmm_param && bss->wmm_ie) { + } else if (elems.wmm_info && + (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_info_len || + memcmp(bss->wmm_ie, elems.wmm_info, elems.wmm_info_len))) { + /* As for certain AP's Fifth bit is not set in WMM IE in + * beacon frames.So while parsing the beacon frame the + * wmm_info structure is used instead of wmm_param. + * wmm_info structure was never used to set bss->wmm_ie. + * This code fixes this problem by copying the WME + * information from wmm_info to bss->wmm_ie and enabling + * n-band association. + */ + kfree(bss->wmm_ie); + bss->wmm_ie = kmalloc(elems.wmm_info_len + 2, GFP_ATOMIC); + if (bss->wmm_ie) { + memcpy(bss->wmm_ie, elems.wmm_info - 2, + elems.wmm_info_len + 2); + bss->wmm_ie_len = elems.wmm_info_len + 2; + } else + bss->wmm_ie_len = 0; + } else if (!elems.wmm_param && !elems.wmm_info && bss->wmm_ie) { kfree(bss->wmm_ie); bss->wmm_ie = NULL; bss->wmm_ie_len = 0; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 52e4554fdde7..02f436a86061 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2170,7 +2170,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_supported_band *sband; if (status->band < 0 || - status->band > IEEE80211_NUM_BANDS) { + status->band >= IEEE80211_NUM_BANDS) { WARN_ON(1); return; } diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index dddbfd60f351..09093da24af6 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c @@ -230,10 +230,8 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, iv16 = data[hdr_len] << 8; iv16 += data[hdr_len + 2]; - iv32 = data[hdr_len + 4] + - (data[hdr_len + 5] >> 8) + - (data[hdr_len + 6] >> 16) + - (data[hdr_len + 7] >> 24); + iv32 = data[hdr_len + 4] | (data[hdr_len + 5] << 8) | + (data[hdr_len + 6] << 16) | (data[hdr_len + 7] << 24); #ifdef CONFIG_TKIP_DEBUG printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 4e94e4026e78..64faa3dc488f 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -709,7 +709,7 @@ void ieee80211_requeue(struct ieee80211_local *local, int queue) struct ieee80211_sched_data *q = qdisc_priv(root_qd); struct Qdisc *qdisc = q->queues[queue]; struct sk_buff *skb = NULL; - u32 len = qdisc->q.qlen; + u32 len; if (!qdisc || !qdisc->dequeue) return; |