[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20080129212703.GA3180@tuxdriver.com>
Date: Tue, 29 Jan 2008 16:27:03 -0500
From: "John W. Linville" <linville@...driver.com>
To: davem@...emloft.net
Cc: netdev@...r.kernel.org, linux-wireless@...r.kernel.org
Subject: pull request: wireless-2.6 'upstream' 2008-01-29
Dave,
Here are some stragglers for 2.6.25. Most of them are fixes for the
new stuff anyway -- I don't think there is anything convroversial.
Please let me know if there are problems!
Thanks,
John
---
Individual patches are available here:
http://www.kernel.org/pub/linux/kernel/people/linville/wireless-2.6/upstream
---
The following changes since commit 85040bcb4643cba578839e953f25e2d1965d83d0:
YOSHIFUJI Hideaki (1):
[IPV6] ADDRLABEL: Fix double free on label deletion.
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git upstream
Adrian Bassett (1):
rtl8180_dev.c: add support for 1799:700f
Bruno Randolf (1):
ath5k: debug level improvements
Cyrill Gorcunov (1):
wireless: iwlwifi3945/4965 - fix incorrect counting of memory
Eric Sandeen (1):
iwlwifi: correct math in elapsed_jiffies
Gregory Greenman (1):
iwlwifi: Fix uCode error on association
Holger Schurig (1):
libertas: fix interrupt while removing driver
Ihar Hrachyshka (1):
libertas: fix memory alignment problems on the blackfin
Iñaky Pérez-González (1):
rfkill: add the WiMAX radio type
Johannes Berg (1):
mac80211: fix alignment warning
John W. Linville (1):
rt61pci: fix-up merge damage
Joonwoo Park (1):
iwlwifi: do not schedule tasklet when rcv unused irq
Maarten Lankhorst (1):
iwlwifi: Fix an invalid bitmask test in iwl3945 and iwl4965
Marcin Juszkiewicz (1):
Add another Prism2 card to hostap
Michael Buesch (4):
b43: Fix rfkill allocation leakage in error paths
b43legacy: Fix rfkill allocation leakage in error paths
b43: Fix suspend/resume
b43: Drop packets that we are not able to encrypt
Michal Piotrowski (1):
hostap_80211.h: remove duplicate prototype
Reinette Chatre (3):
iwl4965: fix return code indicating one interface is supported
iwlwifi: initialize geo/channel information during probe
iwlwifi: cleanup usage of inline functions
Ron Rindjunsky (1):
mac80211: fixing null qos data frames check for reordering buffer
Stefano Brivio (1):
b43legacy: fix MAC control and microcode init
drivers/net/wireless/ath5k/base.c | 10 +-
drivers/net/wireless/ath5k/debug.c | 124 +++++++++++++++++++++----
drivers/net/wireless/ath5k/debug.h | 18 ++--
drivers/net/wireless/b43/dma.c | 30 +++++-
drivers/net/wireless/b43/main.c | 19 +++-
drivers/net/wireless/b43/xmit.c | 23 +++--
drivers/net/wireless/b43/xmit.h | 10 +-
drivers/net/wireless/b43legacy/b43legacy.h | 31 +++----
drivers/net/wireless/b43legacy/main.c | 133 ++++++++++++++++++---------
drivers/net/wireless/b43legacy/phy.c | 14 ++--
drivers/net/wireless/b43legacy/pio.c | 6 +-
drivers/net/wireless/b43legacy/radio.c | 16 ++--
drivers/net/wireless/hostap/hostap_80211.h | 5 -
drivers/net/wireless/hostap/hostap_cs.c | 3 +
drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-3945.c | 14 ---
drivers/net/wireless/iwlwifi/iwl-3945.h | 2 -
drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-4965.c | 7 --
drivers/net/wireless/iwlwifi/iwl-4965.h | 1 -
drivers/net/wireless/iwlwifi/iwl-helpers.h | 4 +-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 86 +++++++++++++----
drivers/net/wireless/iwlwifi/iwl4965-base.c | 84 ++++++++++++-----
drivers/net/wireless/libertas/assoc.c | 6 +-
drivers/net/wireless/libertas/dev.h | 2 +-
drivers/net/wireless/libertas/if_cs.c | 6 +-
drivers/net/wireless/rt2x00/rt61pci.c | 3 +-
drivers/net/wireless/rtl8180_dev.c | 1 +
include/linux/input.h | 2 +
include/linux/rfkill.h | 2 +
net/mac80211/rx.c | 48 +++++++---
net/rfkill/rfkill-input.c | 9 ++
net/rfkill/rfkill.c | 3 +
33 files changed, 490 insertions(+), 236 deletions(-)
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 72bcf32..d6599d2 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -1980,7 +1980,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
struct ath5k_buf *bf = sc->bbuf;
struct ath5k_hw *ah = sc->ah;
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "in beacon_send\n");
+ ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
if (unlikely(bf->skb == NULL || sc->opmode == IEEE80211_IF_TYPE_STA ||
sc->opmode == IEEE80211_IF_TYPE_MNTR)) {
@@ -1996,10 +1996,10 @@ ath5k_beacon_send(struct ath5k_softc *sc)
*/
if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) {
sc->bmisscount++;
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
+ ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
"missed %u consecutive beacons\n", sc->bmisscount);
if (sc->bmisscount > 3) { /* NB: 3 is a guess */
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
+ ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
"stuck beacon time (%u missed)\n",
sc->bmisscount);
tasklet_schedule(&sc->restq);
@@ -2007,7 +2007,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
return;
}
if (unlikely(sc->bmisscount != 0)) {
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
+ ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
"resume beacon xmit after %u misses\n",
sc->bmisscount);
sc->bmisscount = 0;
@@ -2027,7 +2027,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr);
ath5k_hw_tx_start(ah, sc->bhalq);
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "TXDP[%u] = %llx (%p)\n",
+ ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
sc->bsent++;
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c
index 4ba649e..bb581ef 100644
--- a/drivers/net/wireless/ath5k/debug.c
+++ b/drivers/net/wireless/ath5k/debug.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 Bruno Randolf <bruno@...nktube.com>
+ * Copyright (c) 2007-2008 Bruno Randolf <bruno@...nktube.com>
*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -200,7 +200,7 @@ static ssize_t read_file_tsf(struct file *file, char __user *user_buf,
{
struct ath5k_softc *sc = file->private_data;
char buf[100];
- snprintf(buf, 100, "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah));
+ snprintf(buf, sizeof(buf), "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah));
return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
}
@@ -209,7 +209,12 @@ static ssize_t write_file_tsf(struct file *file,
size_t count, loff_t *ppos)
{
struct ath5k_softc *sc = file->private_data;
- if (strncmp(userbuf, "reset", 5) == 0) {
+ char buf[20];
+
+ if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ return -EFAULT;
+
+ if (strncmp(buf, "reset", 5) == 0) {
ath5k_hw_reset_tsf(sc->ah);
printk(KERN_INFO "debugfs reset TSF\n");
}
@@ -231,8 +236,8 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
{
struct ath5k_softc *sc = file->private_data;
struct ath5k_hw *ah = sc->ah;
- char buf[1000];
- int len = 0;
+ char buf[500];
+ unsigned int len = 0;
unsigned int v;
u64 tsf;
@@ -277,11 +282,15 @@ static ssize_t write_file_beacon(struct file *file,
{
struct ath5k_softc *sc = file->private_data;
struct ath5k_hw *ah = sc->ah;
+ char buf[20];
+
+ if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ return -EFAULT;
- if (strncmp(userbuf, "disable", 7) == 0) {
+ if (strncmp(buf, "disable", 7) == 0) {
AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
printk(KERN_INFO "debugfs disable beacons\n");
- } else if (strncmp(userbuf, "enable", 6) == 0) {
+ } else if (strncmp(buf, "enable", 6) == 0) {
AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
printk(KERN_INFO "debugfs enable beacons\n");
}
@@ -314,6 +323,82 @@ static const struct file_operations fops_reset = {
};
+/* debugfs: debug level */
+
+static struct {
+ enum ath5k_debug_level level;
+ const char *name;
+ const char *desc;
+} dbg_info[] = {
+ { ATH5K_DEBUG_RESET, "reset", "reset and initialization" },
+ { ATH5K_DEBUG_INTR, "intr", "interrupt handling" },
+ { ATH5K_DEBUG_MODE, "mode", "mode init/setup" },
+ { ATH5K_DEBUG_XMIT, "xmit", "basic xmit operation" },
+ { ATH5K_DEBUG_BEACON, "beacon", "beacon handling" },
+ { ATH5K_DEBUG_CALIBRATE, "calib", "periodic calibration" },
+ { ATH5K_DEBUG_TXPOWER, "txpower", "transmit power setting" },
+ { ATH5K_DEBUG_LED, "led", "LED mamagement" },
+ { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" },
+ { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
+ { ATH5K_DEBUG_DUMPMODES, "dumpmodes", "dump modes" },
+ { ATH5K_DEBUG_TRACE, "trace", "trace function calls" },
+ { ATH5K_DEBUG_ANY, "all", "show all debug levels" },
+};
+
+static ssize_t read_file_debug(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath5k_softc *sc = file->private_data;
+ char buf[700];
+ unsigned int len = 0;
+ unsigned int i;
+
+ len += snprintf(buf+len, sizeof(buf)-len,
+ "DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);
+
+ for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
+ len += snprintf(buf+len, sizeof(buf)-len,
+ "%10s %c 0x%08x - %s\n", dbg_info[i].name,
+ sc->debug.level & dbg_info[i].level ? '+' : ' ',
+ dbg_info[i].level, dbg_info[i].desc);
+ }
+ len += snprintf(buf+len, sizeof(buf)-len,
+ "%10s %c 0x%08x - %s\n", dbg_info[i].name,
+ sc->debug.level == dbg_info[i].level ? '+' : ' ',
+ dbg_info[i].level, dbg_info[i].desc);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_debug(struct file *file,
+ const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath5k_softc *sc = file->private_data;
+ unsigned int i;
+ char buf[20];
+
+ if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ return -EFAULT;
+
+ for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
+ if (strncmp(buf, dbg_info[i].name,
+ strlen(dbg_info[i].name)) == 0) {
+ sc->debug.level ^= dbg_info[i].level; /* toggle bit */
+ break;
+ }
+ }
+ return count;
+}
+
+static const struct file_operations fops_debug = {
+ .read = read_file_debug,
+ .write = write_file_debug,
+ .open = ath5k_debugfs_open,
+ .owner = THIS_MODULE,
+};
+
+
/* init */
void
@@ -326,26 +411,24 @@ void
ath5k_debug_init_device(struct ath5k_softc *sc)
{
sc->debug.level = ath5k_debug;
+
sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
- ath5k_global_debugfs);
- sc->debug.debugfs_debug = debugfs_create_u32("debug",
- 0666, sc->debug.debugfs_phydir, &sc->debug.level);
+ ath5k_global_debugfs);
+
+ sc->debug.debugfs_debug = debugfs_create_file("debug", 0666,
+ sc->debug.debugfs_phydir, sc, &fops_debug);
sc->debug.debugfs_registers = debugfs_create_file("registers", 0444,
- sc->debug.debugfs_phydir,
- sc, &fops_registers);
+ sc->debug.debugfs_phydir, sc, &fops_registers);
sc->debug.debugfs_tsf = debugfs_create_file("tsf", 0666,
- sc->debug.debugfs_phydir,
- sc, &fops_tsf);
+ sc->debug.debugfs_phydir, sc, &fops_tsf);
sc->debug.debugfs_beacon = debugfs_create_file("beacon", 0666,
- sc->debug.debugfs_phydir,
- sc, &fops_beacon);
+ sc->debug.debugfs_phydir, sc, &fops_beacon);
sc->debug.debugfs_reset = debugfs_create_file("reset", 0222,
- sc->debug.debugfs_phydir,
- sc, &fops_reset);
+ sc->debug.debugfs_phydir, sc, &fops_reset);
}
void
@@ -415,8 +498,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
struct ath5k_buf *bf;
int status;
- if (likely(!(sc->debug.level &
- (ATH5K_DEBUG_RESET | ATH5K_DEBUG_FATAL))))
+ if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
return;
printk(KERN_DEBUG "rx queue %x, link %p\n",
@@ -426,7 +508,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
list_for_each_entry(bf, &sc->rxbuf, list) {
ds = bf->desc;
status = ah->ah_proc_rx_desc(ah, ds);
- if (!status || (sc->debug.level & ATH5K_DEBUG_FATAL))
+ if (!status)
ath5k_debug_printrxbuf(bf, status == 0);
}
spin_unlock_bh(&sc->rxbuflock);
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h
index 2b491cb..c4fd8c4 100644
--- a/drivers/net/wireless/ath5k/debug.h
+++ b/drivers/net/wireless/ath5k/debug.h
@@ -91,7 +91,6 @@ struct ath5k_dbg_info {
* @ATH5K_DEBUG_MODE: mode init/setup
* @ATH5K_DEBUG_XMIT: basic xmit operation
* @ATH5K_DEBUG_BEACON: beacon handling
- * @ATH5K_DEBUG_BEACON_PROC: beacon ISR proc
* @ATH5K_DEBUG_CALIBRATE: periodic calibration
* @ATH5K_DEBUG_TXPOWER: transmit power setting
* @ATH5K_DEBUG_LED: led management
@@ -99,7 +98,6 @@ struct ath5k_dbg_info {
* @ATH5K_DEBUG_DUMP_TX: print transmit skb content
* @ATH5K_DEBUG_DUMPMODES: dump modes
* @ATH5K_DEBUG_TRACE: trace function calls
- * @ATH5K_DEBUG_FATAL: fatal errors
* @ATH5K_DEBUG_ANY: show at any debug level
*
* The debug level is used to control the amount and type of debugging output
@@ -115,15 +113,13 @@ enum ath5k_debug_level {
ATH5K_DEBUG_MODE = 0x00000004,
ATH5K_DEBUG_XMIT = 0x00000008,
ATH5K_DEBUG_BEACON = 0x00000010,
- ATH5K_DEBUG_BEACON_PROC = 0x00000020,
- ATH5K_DEBUG_CALIBRATE = 0x00000100,
- ATH5K_DEBUG_TXPOWER = 0x00000200,
- ATH5K_DEBUG_LED = 0x00000400,
- ATH5K_DEBUG_DUMP_RX = 0x00001000,
- ATH5K_DEBUG_DUMP_TX = 0x00002000,
- ATH5K_DEBUG_DUMPMODES = 0x00004000,
- ATH5K_DEBUG_TRACE = 0x00010000,
- ATH5K_DEBUG_FATAL = 0x80000000,
+ ATH5K_DEBUG_CALIBRATE = 0x00000020,
+ ATH5K_DEBUG_TXPOWER = 0x00000040,
+ ATH5K_DEBUG_LED = 0x00000080,
+ ATH5K_DEBUG_DUMP_RX = 0x00000100,
+ ATH5K_DEBUG_DUMP_TX = 0x00000200,
+ ATH5K_DEBUG_DUMPMODES = 0x00000400,
+ ATH5K_DEBUG_TRACE = 0x00001000,
ATH5K_DEBUG_ANY = 0xffffffff
};
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 3e73d2a..8a708b7 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1114,7 +1114,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
{
const struct b43_dma_ops *ops = ring->ops;
u8 *header;
- int slot;
+ int slot, old_top_slot, old_used_slots;
int err;
struct b43_dmadesc_generic *desc;
struct b43_dmadesc_meta *meta;
@@ -1126,6 +1126,9 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
#define SLOTS_PER_PACKET 2
B43_WARN_ON(skb_shinfo(skb)->nr_frags);
+ old_top_slot = ring->current_slot;
+ old_used_slots = ring->used_slots;
+
/* Get a slot for the header. */
slot = request_slot(ring);
desc = ops->idx2desc(ring, slot, &meta_hdr);
@@ -1133,13 +1136,21 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
header = &(ring->txhdr_cache[slot * hdrsize]);
cookie = generate_cookie(ring, slot);
- b43_generate_txhdr(ring->dev, header,
- skb->data, skb->len, ctl, cookie);
+ err = b43_generate_txhdr(ring->dev, header,
+ skb->data, skb->len, ctl, cookie);
+ if (unlikely(err)) {
+ ring->current_slot = old_top_slot;
+ ring->used_slots = old_used_slots;
+ return err;
+ }
meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
hdrsize, 1);
- if (dma_mapping_error(meta_hdr->dmaaddr))
+ if (dma_mapping_error(meta_hdr->dmaaddr)) {
+ ring->current_slot = old_top_slot;
+ ring->used_slots = old_used_slots;
return -EIO;
+ }
ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
hdrsize, 1, 0, 0);
@@ -1157,6 +1168,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
if (dma_mapping_error(meta->dmaaddr)) {
bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
if (!bounce_skb) {
+ ring->current_slot = old_top_slot;
+ ring->used_slots = old_used_slots;
err = -ENOMEM;
goto out_unmap_hdr;
}
@@ -1167,6 +1180,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
meta->skb = skb;
meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
if (dma_mapping_error(meta->dmaaddr)) {
+ ring->current_slot = old_top_slot;
+ ring->used_slots = old_used_slots;
err = -EIO;
goto out_free_bounce;
}
@@ -1252,6 +1267,13 @@ int b43_dma_tx(struct b43_wldev *dev,
B43_WARN_ON(ring->stopped);
err = dma_tx_fragment(ring, skb, ctl);
+ if (unlikely(err == -ENOKEY)) {
+ /* Drop this packet, as we don't have the encryption key
+ * anymore and must not transmit it unencrypted. */
+ dev_kfree_skb_any(skb);
+ err = 0;
+ goto out_unlock;
+ }
if (unlikely(err)) {
b43err(dev->wl, "DMA tx mapping failure\n");
goto out_unlock;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 88d2c15..64c154d 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3532,8 +3532,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
b43_bluetooth_coext_enable(dev);
ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
- memset(wl->bssid, 0, ETH_ALEN);
- memset(wl->mac_addr, 0, ETH_ALEN);
b43_upload_card_macaddress(dev);
b43_security_init(dev);
b43_rng_init(wl);
@@ -3630,6 +3628,15 @@ static int b43_op_start(struct ieee80211_hw *hw)
struct b43_wldev *dev = wl->current_dev;
int did_init = 0;
int err = 0;
+ bool do_rfkill_exit = 0;
+
+ /* Kill all old instance specific information to make sure
+ * the card won't use it in the short timeframe between start
+ * and mac80211 reconfiguring it. */
+ memset(wl->bssid, 0, ETH_ALEN);
+ memset(wl->mac_addr, 0, ETH_ALEN);
+ wl->filter_flags = 0;
+ wl->radiotap_enabled = 0;
/* First register RFkill.
* LEDs that are registered later depend on it. */
@@ -3639,8 +3646,10 @@ static int b43_op_start(struct ieee80211_hw *hw)
if (b43_status(dev) < B43_STAT_INITIALIZED) {
err = b43_wireless_core_init(dev);
- if (err)
+ if (err) {
+ do_rfkill_exit = 1;
goto out_mutex_unlock;
+ }
did_init = 1;
}
@@ -3649,6 +3658,7 @@ static int b43_op_start(struct ieee80211_hw *hw)
if (err) {
if (did_init)
b43_wireless_core_exit(dev);
+ do_rfkill_exit = 1;
goto out_mutex_unlock;
}
}
@@ -3656,6 +3666,9 @@ static int b43_op_start(struct ieee80211_hw *hw)
out_mutex_unlock:
mutex_unlock(&wl->mutex);
+ if (do_rfkill_exit)
+ b43_rfkill_exit(dev);
+
return err;
}
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 3fc53e8..7caa26e 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -178,12 +178,12 @@ static u8 b43_calc_fallback_rate(u8 bitrate)
}
/* Generate a TX data header. */
-void b43_generate_txhdr(struct b43_wldev *dev,
- u8 *_txhdr,
- const unsigned char *fragment_data,
- unsigned int fragment_len,
- const struct ieee80211_tx_control *txctl,
- u16 cookie)
+int b43_generate_txhdr(struct b43_wldev *dev,
+ u8 *_txhdr,
+ const unsigned char *fragment_data,
+ unsigned int fragment_len,
+ const struct ieee80211_tx_control *txctl,
+ u16 cookie)
{
struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
const struct b43_phy *phy = &dev->phy;
@@ -237,7 +237,15 @@ void b43_generate_txhdr(struct b43_wldev *dev,
B43_WARN_ON(key_idx >= dev->max_nr_keys);
key = &(dev->key[key_idx]);
- B43_WARN_ON(!key->keyconf);
+
+ if (unlikely(!key->keyconf)) {
+ /* This key is invalid. This might only happen
+ * in a short timeframe after machine resume before
+ * we were able to reconfigure keys.
+ * Drop this packet completely. Do not transmit it
+ * unencrypted to avoid leaking information. */
+ return -ENOKEY;
+ }
/* Hardware appends ICV. */
plcp_fragment_len += txctl->icv_len;
@@ -408,6 +416,7 @@ void b43_generate_txhdr(struct b43_wldev *dev,
txhdr->phy_ctl = cpu_to_le16(phy_ctl);
txhdr->extra_ft = extra_ft;
+ return 0;
}
static s8 b43_rssi_postprocess(struct b43_wldev *dev,
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index ca2a2ab..4176503 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -174,11 +174,11 @@ size_t b43_txhdr_size(struct b43_wldev *dev)
}
-void b43_generate_txhdr(struct b43_wldev *dev,
- u8 * txhdr,
- const unsigned char *fragment_data,
- unsigned int fragment_len,
- const struct ieee80211_tx_control *txctl, u16 cookie);
+int b43_generate_txhdr(struct b43_wldev *dev,
+ u8 * txhdr,
+ const unsigned char *fragment_data,
+ unsigned int fragment_len,
+ const struct ieee80211_tx_control *txctl, u16 cookie);
/* Transmit Status */
struct b43_txstatus {
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index 93419ad..c80edd2 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -23,7 +23,7 @@
#include "phy.h"
-#define B43legacy_IRQWAIT_MAX_RETRIES 100
+#define B43legacy_IRQWAIT_MAX_RETRIES 20
#define B43legacy_RX_MAX_SSI 60 /* best guess at max ssi */
@@ -40,9 +40,8 @@
#define B43legacy_MMIO_DMA4_IRQ_MASK 0x44
#define B43legacy_MMIO_DMA5_REASON 0x48
#define B43legacy_MMIO_DMA5_IRQ_MASK 0x4C
-#define B43legacy_MMIO_MACCTL 0x120
-#define B43legacy_MMIO_STATUS_BITFIELD 0x120
-#define B43legacy_MMIO_STATUS2_BITFIELD 0x124
+#define B43legacy_MMIO_MACCTL 0x120 /* MAC control */
+#define B43legacy_MMIO_MACCMD 0x124 /* MAC command */
#define B43legacy_MMIO_GEN_IRQ_REASON 0x128
#define B43legacy_MMIO_GEN_IRQ_MASK 0x12C
#define B43legacy_MMIO_RAM_CONTROL 0x130
@@ -177,31 +176,25 @@
#define B43legacy_RADIOCTL_ID 0x01
/* MAC Control bitfield */
+#define B43legacy_MACCTL_ENABLED 0x00000001 /* MAC Enabled */
+#define B43legacy_MACCTL_PSM_RUN 0x00000002 /* Run Microcode */
+#define B43legacy_MACCTL_PSM_JMP0 0x00000004 /* Microcode jump to 0 */
+#define B43legacy_MACCTL_SHM_ENABLED 0x00000100 /* SHM Enabled */
#define B43legacy_MACCTL_IHR_ENABLED 0x00000400 /* IHR Region Enabled */
+#define B43legacy_MACCTL_BE 0x00010000 /* Big Endian mode */
#define B43legacy_MACCTL_INFRA 0x00020000 /* Infrastructure mode */
#define B43legacy_MACCTL_AP 0x00040000 /* AccessPoint mode */
+#define B43legacy_MACCTL_RADIOLOCK 0x00080000 /* Radio lock */
#define B43legacy_MACCTL_BEACPROMISC 0x00100000 /* Beacon Promiscuous */
#define B43legacy_MACCTL_KEEP_BADPLCP 0x00200000 /* Keep bad PLCP frames */
#define B43legacy_MACCTL_KEEP_CTL 0x00400000 /* Keep control frames */
#define B43legacy_MACCTL_KEEP_BAD 0x00800000 /* Keep bad frames (FCS) */
#define B43legacy_MACCTL_PROMISC 0x01000000 /* Promiscuous mode */
+#define B43legacy_MACCTL_HWPS 0x02000000 /* Hardware Power Saving */
+#define B43legacy_MACCTL_AWAKE 0x04000000 /* Device is awake */
+#define B43legacy_MACCTL_TBTTHOLD 0x10000000 /* TBTT Hold */
#define B43legacy_MACCTL_GMODE 0x80000000 /* G Mode */
-/* StatusBitField */
-#define B43legacy_SBF_MAC_ENABLED 0x00000001
-#define B43legacy_SBF_CORE_READY 0x00000004
-#define B43legacy_SBF_400 0x00000400 /*FIXME: fix name*/
-#define B43legacy_SBF_XFER_REG_BYTESWAP 0x00010000
-#define B43legacy_SBF_MODE_NOTADHOC 0x00020000
-#define B43legacy_SBF_MODE_AP 0x00040000
-#define B43legacy_SBF_RADIOREG_LOCK 0x00080000
-#define B43legacy_SBF_MODE_MONITOR 0x00400000
-#define B43legacy_SBF_MODE_PROMISC 0x01000000
-#define B43legacy_SBF_PS1 0x02000000
-#define B43legacy_SBF_PS2 0x04000000
-#define B43legacy_SBF_NO_SSID_BCAST 0x08000000
-#define B43legacy_SBF_TIME_UPDATE 0x10000000
-
/* 802.11 core specific TM State Low flags */
#define B43legacy_TMSLOW_GMODE 0x20000000 /* G Mode Enable */
#define B43legacy_TMSLOW_PLLREFSEL 0x00200000 /* PLL Freq Ref Select */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 4ed4243..aa20d5d 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -225,8 +225,8 @@ static void b43legacy_ram_write(struct b43legacy_wldev *dev, u16 offset,
B43legacy_WARN_ON(offset % 4 != 0);
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- if (status & B43legacy_SBF_XFER_REG_BYTESWAP)
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ if (status & B43legacy_MACCTL_BE)
val = swab32(val);
b43legacy_write32(dev, B43legacy_MMIO_RAM_CONTROL, offset);
@@ -434,9 +434,9 @@ static void b43legacy_time_lock(struct b43legacy_wldev *dev)
{
u32 status;
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- status |= B43legacy_SBF_TIME_UPDATE;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ status |= B43legacy_MACCTL_TBTTHOLD;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
mmiowb();
}
@@ -444,9 +444,9 @@ static void b43legacy_time_unlock(struct b43legacy_wldev *dev)
{
u32 status;
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- status &= ~B43legacy_SBF_TIME_UPDATE;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ status &= ~B43legacy_MACCTL_TBTTHOLD;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
}
static void b43legacy_tsf_write_locked(struct b43legacy_wldev *dev, u64 tsf)
@@ -647,7 +647,7 @@ void b43legacy_dummy_transmission(struct b43legacy_wldev *dev)
b43legacy_ram_write(dev, i * 4, buffer[i]);
/* dummy read follows */
- b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
+ b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
b43legacy_write16(dev, 0x0568, 0x0000);
b43legacy_write16(dev, 0x07C0, 0x0000);
@@ -794,9 +794,9 @@ static void b43legacy_jssi_write(struct b43legacy_wldev *dev, u32 jssi)
static void b43legacy_generate_noise_sample(struct b43legacy_wldev *dev)
{
b43legacy_jssi_write(dev, 0x7F7F7F7F);
- b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD,
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
b43legacy_read32(dev,
- B43legacy_MMIO_STATUS2_BITFIELD)
+ B43legacy_MMIO_MACCMD)
| (1 << 4));
B43legacy_WARN_ON(dev->noisecalc.channel_at_start !=
dev->phy.channel);
@@ -895,8 +895,8 @@ static void handle_irq_atim_end(struct b43legacy_wldev *dev)
{
if (!dev->reg124_set_0x4) /*FIXME rename this variable*/
return;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD,
- b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD)
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
+ b43legacy_read32(dev, B43legacy_MMIO_MACCMD)
| 0x4);
}
@@ -1106,9 +1106,9 @@ static void b43legacy_update_templates(struct b43legacy_wldev *dev)
b43legacy_write_probe_resp_template(dev, 0x268, 0x4A,
B43legacy_CCK_RATE_11MB);
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
status |= 0x03;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, status);
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD, status);
}
static void b43legacy_refresh_templates(struct b43legacy_wldev *dev,
@@ -1166,7 +1166,7 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev)
return;
dev->irq_savedstate &= ~B43legacy_IRQ_BEACON;
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
if (!dev->cached_beacon || ((status & 0x1) && (status & 0x2))) {
/* ACK beacon IRQ. */
@@ -1182,14 +1182,14 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev)
b43legacy_write_beacon_template(dev, 0x68, 0x18,
B43legacy_CCK_RATE_1MB);
status |= 0x1;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD,
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
status);
}
if (!(status & 0x2)) {
b43legacy_write_beacon_template(dev, 0x468, 0x1A,
B43legacy_CCK_RATE_1MB);
status |= 0x2;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD,
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
status);
}
}
@@ -1548,9 +1548,20 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
u16 fwpatch;
u16 fwdate;
u16 fwtime;
- u32 tmp;
+ u32 tmp, macctl;
int err = 0;
+ /* Jump the microcode PSM to offset 0 */
+ macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ B43legacy_WARN_ON(macctl & B43legacy_MACCTL_PSM_RUN);
+ macctl |= B43legacy_MACCTL_PSM_JMP0;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
+ /* Zero out all microcode PSM registers and shared memory. */
+ for (i = 0; i < 64; i++)
+ b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, i, 0);
+ for (i = 0; i < 4096; i += 2)
+ b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, i, 0);
+
/* Upload Microcode. */
data = (__be32 *) (dev->fw.ucode->data + hdr_len);
len = (dev->fw.ucode->size - hdr_len) / sizeof(__be32);
@@ -1581,7 +1592,12 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON,
B43legacy_IRQ_ALL);
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 0x00020402);
+
+ /* Start the microcode PSM */
+ macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ macctl &= ~B43legacy_MACCTL_PSM_JMP0;
+ macctl |= B43legacy_MACCTL_PSM_RUN;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
/* Wait for the microcode to load and respond */
i = 0;
@@ -1594,9 +1610,13 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
b43legacyerr(dev->wl, "Microcode not responding\n");
b43legacy_print_fw_helptext(dev->wl);
err = -ENODEV;
- goto out;
+ goto error;
+ }
+ msleep_interruptible(50);
+ if (signal_pending(current)) {
+ err = -EINTR;
+ goto error;
}
- udelay(10);
}
/* dummy read follows */
b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
@@ -1617,9 +1637,8 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
" is supported. You must change your firmware"
" files.\n");
b43legacy_print_fw_helptext(dev->wl);
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 0);
err = -EOPNOTSUPP;
- goto out;
+ goto error;
}
b43legacydbg(dev->wl, "Loading firmware version 0x%X, patch level %u "
"(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch,
@@ -1629,7 +1648,14 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
dev->fw.rev = fwrev;
dev->fw.patch = fwpatch;
-out:
+ return 0;
+
+error:
+ macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ macctl &= ~B43legacy_MACCTL_PSM_RUN;
+ macctl |= B43legacy_MACCTL_PSM_JMP0;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
+
return err;
}
@@ -1736,9 +1762,9 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev)
u32 mask;
u32 set;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
b43legacy_read32(dev,
- B43legacy_MMIO_STATUS_BITFIELD)
+ B43legacy_MMIO_MACCTL)
& 0xFFFF3FFF);
b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK,
@@ -1798,14 +1824,14 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev)
B43legacy_WARN_ON(dev->mac_suspended < 0);
B43legacy_WARN_ON(irqs_disabled());
if (dev->mac_suspended == 0) {
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
b43legacy_read32(dev,
- B43legacy_MMIO_STATUS_BITFIELD)
- | B43legacy_SBF_MAC_ENABLED);
+ B43legacy_MMIO_MACCTL)
+ | B43legacy_MACCTL_ENABLED);
b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON,
B43legacy_IRQ_MAC_SUSPENDED);
/* the next two are dummy reads */
- b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
+ b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
b43legacy_power_saving_ctl_bits(dev, -1, -1);
@@ -1836,10 +1862,10 @@ void b43legacy_mac_suspend(struct b43legacy_wldev *dev)
dev->irq_savedstate = tmp;
b43legacy_power_saving_ctl_bits(dev, -1, 1);
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
b43legacy_read32(dev,
- B43legacy_MMIO_STATUS_BITFIELD)
- & ~B43legacy_SBF_MAC_ENABLED);
+ B43legacy_MMIO_MACCTL)
+ & ~B43legacy_MACCTL_ENABLED);
b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
for (i = 40; i; i--) {
tmp = b43legacy_read32(dev,
@@ -2007,12 +2033,15 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
struct b43legacy_phy *phy = &dev->phy;
int err;
int tmp;
- u32 value32;
+ u32 value32, macctl;
u16 value16;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
- B43legacy_SBF_CORE_READY
- | B43legacy_SBF_400);
+ /* Initialize the MAC control */
+ macctl = B43legacy_MACCTL_IHR_ENABLED | B43legacy_MACCTL_SHM_ENABLED;
+ if (dev->phy.gmode)
+ macctl |= B43legacy_MACCTL_GMODE;
+ macctl |= B43legacy_MACCTL_INFRA;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
err = b43legacy_request_firmware(dev);
if (err)
@@ -2052,12 +2081,12 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
if (dev->dev->id.revision < 5)
b43legacy_write32(dev, 0x010C, 0x01000000);
- value32 = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- value32 &= ~B43legacy_SBF_MODE_NOTADHOC;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value32);
- value32 = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- value32 |= B43legacy_SBF_MODE_NOTADHOC;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value32);
+ value32 = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ value32 &= ~B43legacy_MACCTL_INFRA;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value32);
+ value32 = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ value32 |= B43legacy_MACCTL_INFRA;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value32);
if (b43legacy_using_pio(dev)) {
b43legacy_write32(dev, 0x0210, 0x00000100);
@@ -2951,12 +2980,19 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev)
{
struct b43legacy_wl *wl = dev->wl;
struct b43legacy_phy *phy = &dev->phy;
+ u32 macctl;
B43legacy_WARN_ON(b43legacy_status(dev) > B43legacy_STAT_INITIALIZED);
if (b43legacy_status(dev) != B43legacy_STAT_INITIALIZED)
return;
b43legacy_set_status(dev, B43legacy_STAT_UNINIT);
+ /* Stop the microcode PSM. */
+ macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ macctl &= ~B43legacy_MACCTL_PSM_RUN;
+ macctl |= B43legacy_MACCTL_PSM_JMP0;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
+
mutex_unlock(&wl->mutex);
/* Must unlock as it would otherwise deadlock. No races here.
* Cancel possibly pending workqueues. */
@@ -3221,6 +3257,7 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
struct b43legacy_wldev *dev = wl->current_dev;
int did_init = 0;
int err = 0;
+ bool do_rfkill_exit = 0;
/* First register RFkill.
* LEDs that are registered later depend on it. */
@@ -3230,8 +3267,10 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
err = b43legacy_wireless_core_init(dev);
- if (err)
+ if (err) {
+ do_rfkill_exit = 1;
goto out_mutex_unlock;
+ }
did_init = 1;
}
@@ -3240,6 +3279,7 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
if (err) {
if (did_init)
b43legacy_wireless_core_exit(dev);
+ do_rfkill_exit = 1;
goto out_mutex_unlock;
}
}
@@ -3247,6 +3287,9 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
out_mutex_unlock:
mutex_unlock(&wl->mutex);
+ if (do_rfkill_exit)
+ b43legacy_rfkill_exit(dev);
+
return err;
}
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c
index c16febb..8e5c09b 100644
--- a/drivers/net/wireless/b43legacy/phy.c
+++ b/drivers/net/wireless/b43legacy/phy.c
@@ -140,7 +140,7 @@ void b43legacy_phy_calibrate(struct b43legacy_wldev *dev)
{
struct b43legacy_phy *phy = &dev->phy;
- b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); /* Dummy read. */
+ b43legacy_read32(dev, B43legacy_MMIO_MACCTL); /* Dummy read. */
if (phy->calibrated)
return;
if (phy->type == B43legacy_PHYTYPE_G && phy->rev == 1) {
@@ -2231,16 +2231,16 @@ bit26 = 1;
* or the latest PS-Poll packet sent was successful,
* set bit26 */
}
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
if (bit25)
- status |= B43legacy_SBF_PS1;
+ status |= B43legacy_MACCTL_HWPS;
else
- status &= ~B43legacy_SBF_PS1;
+ status &= ~B43legacy_MACCTL_HWPS;
if (bit26)
- status |= B43legacy_SBF_PS2;
+ status |= B43legacy_MACCTL_AWAKE;
else
- status &= ~B43legacy_SBF_PS2;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+ status &= ~B43legacy_MACCTL_AWAKE;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
if (bit26 && dev->dev->id.revision >= 5) {
for (i = 0; i < 100; i++) {
if (b43legacy_shm_read32(dev, B43legacy_SHM_SHARED,
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index de843ac..e4f4c5c 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -334,9 +334,9 @@ struct b43legacy_pioqueue *b43legacy_setup_pioqueue(struct b43legacy_wldev *dev,
tasklet_init(&queue->txtask, tx_tasklet,
(unsigned long)queue);
- value = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- value &= ~B43legacy_SBF_XFER_REG_BYTESWAP;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value);
+ value = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ value &= ~B43legacy_MACCTL_BE;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value);
qsize = b43legacy_read16(dev, queue->mmio_base
+ B43legacy_PIO_TXQBUFSIZE);
diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c
index 318a270..955832e 100644
--- a/drivers/net/wireless/b43legacy/radio.c
+++ b/drivers/net/wireless/b43legacy/radio.c
@@ -91,10 +91,10 @@ void b43legacy_radio_lock(struct b43legacy_wldev *dev)
{
u32 status;
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- B43legacy_WARN_ON(status & B43legacy_SBF_RADIOREG_LOCK);
- status |= B43legacy_SBF_RADIOREG_LOCK;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ B43legacy_WARN_ON(status & B43legacy_MACCTL_RADIOLOCK);
+ status |= B43legacy_MACCTL_RADIOLOCK;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
mmiowb();
udelay(10);
}
@@ -104,10 +104,10 @@ void b43legacy_radio_unlock(struct b43legacy_wldev *dev)
u32 status;
b43legacy_read16(dev, B43legacy_MMIO_PHY_VER); /* dummy read */
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- B43legacy_WARN_ON(!(status & B43legacy_SBF_RADIOREG_LOCK));
- status &= ~B43legacy_SBF_RADIOREG_LOCK;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ B43legacy_WARN_ON(!(status & B43legacy_MACCTL_RADIOLOCK));
+ status &= ~B43legacy_MACCTL_RADIOLOCK;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
mmiowb();
}
diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h
index d6b9362..3694b1e 100644
--- a/drivers/net/wireless/hostap/hostap_80211.h
+++ b/drivers/net/wireless/hostap/hostap_80211.h
@@ -71,11 +71,6 @@ struct hostap_80211_rx_status {
u16 rate; /* in 100 kbps */
};
-
-void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
- struct hostap_80211_rx_status *rx_stats);
-
-
/* prism2_rx_80211 'type' argument */
enum {
PRISM2_RX_MONITOR, PRISM2_RX_MGMT, PRISM2_RX_NON_ASSOC,
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 0759380..437a9bc 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -891,6 +891,9 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
PCMCIA_DEVICE_PROD_ID123(
"The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P",
0xa5f472c2, 0x9c05598d, 0xc9049a39),
+ PCMCIA_DEVICE_PROD_ID123(
+ "Wireless LAN" , "11Mbps PC Card", "Version 01.02",
+ 0x4b8870ff, 0x70e946d1, 0x4b74baa0),
PCMCIA_DEVICE_NULL
};
MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 6e01873..571815d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -373,7 +373,7 @@ struct iwl3945_eeprom {
#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */
#define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */
#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */
-#define CSR_INT_BIT_MAC_CLK_ACTV (1 << 26) /* NIC controller's clock toggled on/off */
+#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */
#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */
#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */
#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 76c4ed1..4fdeb53 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2369,18 +2369,4 @@ struct pci_device_id iwl3945_hw_card_ids[] = {
{0}
};
-/*
- * Clear the OWNER_MSK, to establish driver (instead of uCode running on
- * embedded controller) as EEPROM reader; each read is a series of pulses
- * to/from the EEPROM chip, not a single event, so even reads could conflict
- * if they weren't arbitrated by some ownership mechanism. Here, the driver
- * simply claims ownership, which should be safe when this function is called
- * (i.e. before loading uCode!).
- */
-inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
-{
- _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
- return 0;
-}
-
MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 20b925f..1da14f9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -671,7 +671,6 @@ extern int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel);
/*
* Forward declare iwl-3945.c functions for iwl-base.c
*/
-extern int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv);
extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv);
extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv);
extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv);
@@ -791,7 +790,6 @@ struct iwl3945_priv {
u16 active_rate_basic;
u8 call_post_assoc_from_beacon;
- u8 assoc_station_added;
/* Rate scaling data */
s8 data_retry_limit;
u8 retry_rate;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index ff71c09..ffe1e9d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -465,7 +465,7 @@ struct iwl4965_eeprom {
#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */
#define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */
#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */
-#define CSR_INT_BIT_MAC_CLK_ACTV (1 << 26) /* NIC controller's clock toggled on/off */
+#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */
#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */
#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */
#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 04db34b..569347f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -4961,11 +4961,4 @@ int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv)
return rc;
}
-inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
-{
- iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-}
-
-
MODULE_DEVICE_TABLE(pci, iwl4965_hw_card_ids);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h
index 78bc148..9cb82be 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.h
@@ -750,7 +750,6 @@ struct iwl4965_priv;
* Forward declare iwl-4965.c functions for iwl-base.c
*/
extern int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv);
-extern void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv);
extern int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv,
struct iwl4965_tx_queue *txq,
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index cd2eb18..cb009f4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -246,10 +246,10 @@ static inline int iwl_check_bits(unsigned long field, unsigned long mask)
static inline unsigned long elapsed_jiffies(unsigned long start,
unsigned long end)
{
- if (end > start)
+ if (end >= start)
return end - start;
- return end + (MAX_JIFFY_OFFSET - start);
+ return end + (MAX_JIFFY_OFFSET - start) + 1;
}
static inline u8 iwl_get_dma_hi_address(dma_addr_t addr)
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 748ac12..33239f1 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1557,6 +1557,20 @@ static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac)
memcpy(mac, priv->eeprom.mac_address, 6);
}
+/*
+ * Clear the OWNER_MSK, to establish driver (instead of uCode running on
+ * embedded controller) as EEPROM reader; each read is a series of pulses
+ * to/from the EEPROM chip, not a single event, so even reads could conflict
+ * if they weren't arbitrated by some ownership mechanism. Here, the driver
+ * simply claims ownership, which should be safe when this function is called
+ * (i.e. before loading uCode!).
+ */
+static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
+{
+ _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
+ return 0;
+}
+
/**
* iwl3945_eeprom_init - read EEPROM contents
*
@@ -2792,7 +2806,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
#endif
/* drop all data frame if we are not associated */
- if (!iwl3945_is_associated(priv) && !priv->assoc_id &&
+ if ((!iwl3945_is_associated(priv) || !priv->assoc_id) &&
((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
goto drop_unlock;
@@ -4745,8 +4759,9 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
#ifdef CONFIG_IWL3945_DEBUG
if (iwl3945_debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
- if (inta & CSR_INT_BIT_MAC_CLK_ACTV)
- IWL_DEBUG_ISR("Microcode started or stopped.\n");
+ if (inta & CSR_INT_BIT_SCD)
+ IWL_DEBUG_ISR("Scheduler finished to transmit "
+ "the frame/frames.\n");
/* Alive notification via Rx interrupt will do the real work */
if (inta & CSR_INT_BIT_ALIVE)
@@ -4754,7 +4769,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
}
#endif
/* Safely ignore these bits for debug checks below */
- inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE);
+ inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
/* HW RF KILL switch toggled (4965 only) */
if (inta & CSR_INT_BIT_RF_KILL) {
@@ -4890,8 +4905,11 @@ static irqreturn_t iwl3945_isr(int irq, void *data)
IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
inta, inta_mask, inta_fh);
+ inta &= ~CSR_INT_BIT_SCD;
+
/* iwl3945_irq_tasklet() will service interrupts and re-enable them */
- tasklet_schedule(&priv->irq_tasklet);
+ if (likely(inta || inta_fh))
+ tasklet_schedule(&priv->irq_tasklet);
unplugged:
spin_unlock(&priv->lock);
@@ -5146,6 +5164,15 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
return 0;
}
+/*
+ * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map
+ */
+static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
+{
+ kfree(priv->channel_info);
+ priv->channel_count = 0;
+}
+
/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
* sending probe req. This should be set long enough to hear probe responses
* from more than one AP. */
@@ -5471,6 +5498,17 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
return 0;
}
+/*
+ * iwl3945_free_geos - undo allocations in iwl3945_init_geos
+ */
+static void iwl3945_free_geos(struct iwl3945_priv *priv)
+{
+ kfree(priv->modes);
+ kfree(priv->ieee_channels);
+ kfree(priv->ieee_rates);
+ clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
+}
+
/******************************************************************************
*
* uCode download functions
@@ -6130,15 +6168,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
/* Clear out the uCode error bit if it is set */
clear_bit(STATUS_FW_ERROR, &priv->status);
- rc = iwl3945_init_channel_map(priv);
- if (rc) {
- IWL_ERROR("initializing regulatory failed: %d\n", rc);
- return;
- }
-
- iwl3945_init_geos(priv);
- iwl3945_reset_channel_flag(priv);
-
if (iwl3945_is_rfkill(priv))
return;
@@ -6599,7 +6628,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
* that based on the direct_mask added to each channel entry */
scan->tx_cmd.len = cpu_to_le16(
iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(scan), 0));
+ IWL_MAX_SCAN_SIZE - sizeof(*scan), 0));
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
@@ -7120,7 +7149,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
{
int rc = 0;
- if (priv->status & STATUS_EXIT_PENDING)
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
/* The following should be done only at AP bring up */
@@ -8614,11 +8643,24 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
+ err = iwl3945_init_channel_map(priv);
+ if (err) {
+ IWL_ERROR("initializing regulatory failed: %d\n", err);
+ goto out_remove_sysfs;
+ }
+
+ err = iwl3945_init_geos(priv);
+ if (err) {
+ IWL_ERROR("initializing geos failed: %d\n", err);
+ goto out_free_channel_map;
+ }
+ iwl3945_reset_channel_flag(priv);
+
iwl3945_rate_control_register(priv->hw);
err = ieee80211_register_hw(priv->hw);
if (err) {
IWL_ERROR("Failed to register network device (error %d)\n", err);
- goto out_remove_sysfs;
+ goto out_free_geos;
}
priv->hw->conf.beacon_int = 100;
@@ -8628,6 +8670,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
return 0;
+ out_free_geos:
+ iwl3945_free_geos(priv);
+ out_free_channel_map:
+ iwl3945_free_channel_map(priv);
out_remove_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
@@ -8702,10 +8748,8 @@ static void iwl3945_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
- kfree(priv->channel_info);
-
- kfree(priv->ieee_channels);
- kfree(priv->ieee_rates);
+ iwl3945_free_channel_map(priv);
+ iwl3945_free_geos(priv);
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index c86da5c..bf3a60c 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1639,6 +1639,12 @@ static void get_eeprom_mac(struct iwl4965_priv *priv, u8 *mac)
memcpy(mac, priv->eeprom.mac_address, 6);
}
+static inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
+{
+ iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+}
+
/**
* iwl4965_eeprom_init - read EEPROM contents
*
@@ -2927,8 +2933,10 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,
#endif
/* drop all data frame if we are not associated */
- if (!iwl4965_is_associated(priv) && !priv->assoc_id &&
- ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
+ if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
+ (!iwl4965_is_associated(priv) ||
+ !priv->assoc_id ||
+ !priv->assoc_station_added)) {
IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n");
goto drop_unlock;
}
@@ -5131,8 +5139,9 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv)
#ifdef CONFIG_IWL4965_DEBUG
if (iwl4965_debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
- if (inta & CSR_INT_BIT_MAC_CLK_ACTV)
- IWL_DEBUG_ISR("Microcode started or stopped.\n");
+ if (inta & CSR_INT_BIT_SCD)
+ IWL_DEBUG_ISR("Scheduler finished to transmit "
+ "the frame/frames.\n");
/* Alive notification via Rx interrupt will do the real work */
if (inta & CSR_INT_BIT_ALIVE)
@@ -5140,7 +5149,7 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv)
}
#endif
/* Safely ignore these bits for debug checks below */
- inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE);
+ inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
/* HW RF KILL switch toggled */
if (inta & CSR_INT_BIT_RF_KILL) {
@@ -5269,8 +5278,11 @@ static irqreturn_t iwl4965_isr(int irq, void *data)
IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
inta, inta_mask, inta_fh);
+ inta &= ~CSR_INT_BIT_SCD;
+
/* iwl4965_irq_tasklet() will service interrupts and re-enable them */
- tasklet_schedule(&priv->irq_tasklet);
+ if (likely(inta || inta_fh))
+ tasklet_schedule(&priv->irq_tasklet);
unplugged:
spin_unlock(&priv->lock);
@@ -5576,6 +5588,15 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv)
return 0;
}
+/*
+ * iwl4965_free_channel_map - undo allocations in iwl4965_init_channel_map
+ */
+static void iwl4965_free_channel_map(struct iwl4965_priv *priv)
+{
+ kfree(priv->channel_info);
+ priv->channel_count = 0;
+}
+
/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
* sending probe req. This should be set long enough to hear probe responses
* from more than one AP. */
@@ -5909,6 +5930,17 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv)
return 0;
}
+/*
+ * iwl4965_free_geos - undo allocations in iwl4965_init_geos
+ */
+static void iwl4965_free_geos(struct iwl4965_priv *priv)
+{
+ kfree(priv->modes);
+ kfree(priv->ieee_channels);
+ kfree(priv->ieee_rates);
+ clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
+}
+
/******************************************************************************
*
* uCode download functions
@@ -6560,15 +6592,6 @@ static void iwl4965_alive_start(struct iwl4965_priv *priv)
/* Clear out the uCode error bit if it is set */
clear_bit(STATUS_FW_ERROR, &priv->status);
- rc = iwl4965_init_channel_map(priv);
- if (rc) {
- IWL_ERROR("initializing regulatory failed: %d\n", rc);
- return;
- }
-
- iwl4965_init_geos(priv);
- iwl4965_reset_channel_flag(priv);
-
if (iwl4965_is_rfkill(priv))
return;
@@ -7023,7 +7046,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
* that based on the direct_mask added to each channel entry */
scan->tx_cmd.len = cpu_to_le16(
iwl4965_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(scan), 0));
+ IWL_MAX_SCAN_SIZE - sizeof(*scan), 0));
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
@@ -7448,7 +7471,7 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,
if (priv->vif) {
IWL_DEBUG_MAC80211("leave - vif != NULL\n");
- return 0;
+ return -EOPNOTSUPP;
}
spin_lock_irqsave(&priv->lock, flags);
@@ -7580,7 +7603,7 @@ static void iwl4965_config_ap(struct iwl4965_priv *priv)
{
int rc = 0;
- if (priv->status & STATUS_EXIT_PENDING)
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
/* The following should be done only at AP bring up */
@@ -9198,11 +9221,24 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
+ err = iwl4965_init_channel_map(priv);
+ if (err) {
+ IWL_ERROR("initializing regulatory failed: %d\n", err);
+ goto out_remove_sysfs;
+ }
+
+ err = iwl4965_init_geos(priv);
+ if (err) {
+ IWL_ERROR("initializing geos failed: %d\n", err);
+ goto out_free_channel_map;
+ }
+ iwl4965_reset_channel_flag(priv);
+
iwl4965_rate_control_register(priv->hw);
err = ieee80211_register_hw(priv->hw);
if (err) {
IWL_ERROR("Failed to register network device (error %d)\n", err);
- goto out_remove_sysfs;
+ goto out_free_geos;
}
priv->hw->conf.beacon_int = 100;
@@ -9212,6 +9248,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
return 0;
+ out_free_geos:
+ iwl4965_free_geos(priv);
+ out_free_channel_map:
+ iwl4965_free_channel_map(priv);
out_remove_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
@@ -9286,10 +9326,8 @@ static void iwl4965_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
- kfree(priv->channel_info);
-
- kfree(priv->ieee_channels);
- kfree(priv->ieee_rates);
+ iwl4965_free_channel_map(priv);
+ iwl4965_free_geos(priv);
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index c622e9b..87e145f 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -12,8 +12,10 @@
#include "cmd.h"
-static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) =
+ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static int assoc_helper_essid(struct lbs_private *priv,
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 58d7ef6..5a69f2b 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -349,7 +349,7 @@ struct assoc_request {
u8 channel;
u8 band;
u8 mode;
- u8 bssid[ETH_ALEN];
+ u8 bssid[ETH_ALEN] __attribute__ ((aligned (2)));
/** WEP keys */
struct enc_key wep_keys[4];
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 4b5ab9a..5a9cadb 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -249,14 +249,14 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
lbs_deb_enter(LBS_DEB_CS);
int_cause = if_cs_read16(card, IF_CS_C_INT_CAUSE);
- if(int_cause == 0x0) {
+ if (int_cause == 0x0) {
/* Not for us */
return IRQ_NONE;
} else if (int_cause == 0xffff) {
/* Read in junk, the card has probably been removed */
card->priv->surpriseremoved = 1;
-
+ return IRQ_HANDLED;
} else {
if (int_cause & IF_CS_H_IC_TX_OVER)
lbs_host_to_card_done(card->priv);
@@ -717,8 +717,8 @@ static void if_cs_release(struct pcmcia_device *p_dev)
lbs_deb_enter(LBS_DEB_CS);
- pcmcia_disable_device(p_dev);
free_irq(p_dev->irq.AssignedIRQ, card);
+ pcmcia_disable_device(p_dev);
if (card->iobase)
ioport_unmap(card->iobase);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index ab52f22..b31f0c2 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1736,7 +1736,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
WARNING(rt2x00dev,
"TX status report missed for entry %p\n",
entry_done);
- rt2x00lib_txdone(entry_done, TX_FAIL_OTHER, 0);
+ rt2x00pci_txdone(rt2x00dev, entry_done, TX_FAIL_OTHER,
+ 0);
entry_done = rt2x00_get_data_entry_done(ring);
}
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index 07f37b0..27ebd68 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -36,6 +36,7 @@ MODULE_LICENSE("GPL");
static struct pci_device_id rtl8180_table[] __devinitdata = {
/* rtl8185 */
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) },
{ PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) },
/* rtl8180 */
diff --git a/include/linux/input.h b/include/linux/input.h
index 2075d6d..056a17a 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -371,6 +371,8 @@ struct input_absinfo {
#define KEY_BRIGHTNESS_ZERO 244 /* brightness off, use ambient */
#define KEY_DISPLAY_OFF 245 /* display device to off state */
+#define KEY_WIMAX 246
+
#define BTN_MISC 0x100
#define BTN_0 0x100
#define BTN_1 0x101
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 0ce5e0b..e3ab21d 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -33,11 +33,13 @@
* RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
* RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
* RFKILL_TYPE_UWB: switch is on a ultra wideband device.
+ * RFKILL_TYPE_WIMAX: switch is on a WiMAX device.
*/
enum rfkill_type {
RFKILL_TYPE_WLAN ,
RFKILL_TYPE_BLUETOOTH,
RFKILL_TYPE_UWB,
+ RFKILL_TYPE_WIMAX,
RFKILL_TYPE_MAX,
};
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 89e1e30..d44c872 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -340,9 +340,42 @@ static u32 ieee80211_rx_load_stats(struct ieee80211_local *local,
return load;
}
+static ieee80211_txrx_result
+ieee80211_rx_h_verify_ip_alignment(struct ieee80211_txrx_data *rx)
+{
+ int hdrlen;
+
+ /*
+ * Drivers are required to align the payload data in a way that
+ * guarantees that the contained IP header is aligned to a four-
+ * byte boundary. In the case of regular frames, this simply means
+ * aligning the payload to a four-byte boundary (because either
+ * the IP header is directly contained, or IV/RFC1042 headers that
+ * have a length divisible by four are in front of it.
+ *
+ * With A-MSDU frames, however, the payload data address must
+ * yield two modulo four because there are 14-byte 802.3 headers
+ * within the A-MSDU frames that push the IP header further back
+ * to a multiple of four again. Thankfully, the specs were sane
+ * enough this time around to require padding each A-MSDU subframe
+ * to a length that is a multiple of four.
+ *
+ * Padding like atheros hardware adds which is inbetween the 802.11
+ * header and the payload is not supported, the driver is required
+ * to move the 802.11 header further back in that case.
+ */
+ hdrlen = ieee80211_get_hdrlen(rx->fc);
+ if (rx->flags & IEEE80211_TXRXD_RX_AMSDU)
+ hdrlen += ETH_HLEN;
+ WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3);
+
+ return TXRX_CONTINUE;
+}
+
ieee80211_rx_handler ieee80211_rx_pre_handlers[] =
{
ieee80211_rx_h_parse_qos,
+ ieee80211_rx_h_verify_ip_alignment,
NULL
};
@@ -1679,7 +1712,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
struct ieee80211_sub_if_data *prev = NULL;
struct sk_buff *skb_new;
u8 *bssid;
- int hdrlen;
hdr = (struct ieee80211_hdr *) skb->data;
memset(&rx, 0, sizeof(rx));
@@ -1691,18 +1723,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
rx.fc = le16_to_cpu(hdr->frame_control);
type = rx.fc & IEEE80211_FCTL_FTYPE;
- /*
- * Drivers are required to align the payload data to a four-byte
- * boundary, so the last two bits of the address where it starts
- * may not be set. The header is required to be directly before
- * the payload data, padding like atheros hardware adds which is
- * inbetween the 802.11 header and the payload is not supported,
- * the driver is required to move the 802.11 header further back
- * in that case.
- */
- hdrlen = ieee80211_get_hdrlen(rx.fc);
- WARN_ON_ONCE(((unsigned long)(skb->data + hdrlen)) & 3);
-
if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT)
local->dot11ReceivedFragmentCount++;
@@ -1952,7 +1972,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
goto end_reorder;
/* null data frames are excluded */
- if (unlikely(fc & IEEE80211_STYPE_QOS_NULLFUNC))
+ if (unlikely(fc & IEEE80211_STYPE_NULLFUNC))
goto end_reorder;
/* new un-ordered ampdu frame - process it */
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index d1e9d68..e4b051d 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -84,6 +84,7 @@ static void rfkill_schedule_toggle(struct rfkill_task *task)
static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN);
static DEFINE_RFKILL_TASK(rfkill_bt, RFKILL_TYPE_BLUETOOTH);
static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
+static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
static void rfkill_event(struct input_handle *handle, unsigned int type,
unsigned int code, int down)
@@ -99,6 +100,9 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
case KEY_UWB:
rfkill_schedule_toggle(&rfkill_uwb);
break;
+ case KEY_WIMAX:
+ rfkill_schedule_toggle(&rfkill_wimax);
+ break;
default:
break;
}
@@ -159,6 +163,11 @@ static const struct input_device_id rfkill_ids[] = {
.evbit = { BIT_MASK(EV_KEY) },
.keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },
},
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+ .evbit = { BIT_MASK(EV_KEY) },
+ .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
+ },
{ }
};
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index d06d338..6562f86 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -126,6 +126,9 @@ static ssize_t rfkill_type_show(struct device *dev,
case RFKILL_TYPE_UWB:
type = "ultrawideband";
break;
+ case RFKILL_TYPE_WIMAX:
+ type = "wimax";
+ break;
default:
BUG();
}
--
John W. Linville
linville@...driver.com
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists