summaryrefslogtreecommitdiff
path: root/net/mac80211
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2008-05-06 16:57:55 +0200
committerJiri Kosina <jkosina@suse.cz>2008-05-06 16:57:55 +0200
commit7022b15e2a9f878fd5184586064c63352c3dd225 (patch)
tree5365c2f5bc82ae1946636ee8d5cd5d3b7e804f1b /net/mac80211
parentaaad2b0c757f3e6e02552cb0bdcd91a5ec0d6305 (diff)
parenta15306365a16380f3bafee9e181ba01231d4acd7 (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/Kconfig4
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/main.c47
-rw-r--r--net/mac80211/mesh.c17
-rw-r--r--net/mac80211/mesh.h3
-rw-r--r--net/mac80211/mesh_hwmp.c1
-rw-r--r--net/mac80211/mlme.c28
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/tkip.c6
-rw-r--r--net/mac80211/wme.c2
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;