Search Linux Wireless

Please pull latest bcm43xx-mac80211 + ssb

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The following changes since commit 78d7c152a3a8880b7daab8a1be1f24199f9d80b9:
  John W. Linville:
        Merge branch 'upstream' of git://git.kernel.org/.../ivd/rt2x00

are found in the git repository at:

  http://bu3sch.de/git/wireless-dev.git/ for-linville

Larry Finger:
      bcm43xx-mac80211: Fix deviations from OFDM table specs

Michael Buesch:
      bcm43xx-mac80211: Fix build for PCI-less systems.
      bcm43xx-mac80211: Use round_jiffies() to round pwork interval.
      ssb: Zero out invariants before pulling them.
      ssb: Rename nr_buses variable to next_busnumber
      bcm43xx-mac80211: Add optional verbose DMA debugging.
      bcm43xx-mac80211: Use ieee80211_generic_frame_duration() to calculate durations.
      bcm43xx-mac80211: Add sanity checks for the packet length in the RX handler.
      bcm43xx-mac80211: Rewrite and simplify handling of the initialization status.
      bcm43xx-mac80211: Rewrite message logging to associate logmessages to the wiphy.
      bcm43xx-mac80211: Get rid of all stupid bitfields and use bool.
      bcm43xx-mac80211: Fix nondebug build.
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-dev
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-dev
      ssb: Fix typo in EXTIF_BASE define.
      ssb: Address Andrew Morton's comments.
      bcm43xx-mac80211: Always run promisc on old devices with broken MAC addr filter.
      ssb: Remove ifdef __KERNEL__
      ssb: A few fixes
      ssb: Cleanup Makefile and Kconfig.
      ssb: Add more comments.
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-dev
      bcm43xx-mac80211: Fix compilation, pass if_id to ieee80211_generic_frame_duration()

 drivers/net/wireless/bcm43xx-mac80211/bcm43xx.h    |  113 +++---
 .../wireless/bcm43xx-mac80211/bcm43xx_debugfs.c    |   83 +----
 .../wireless/bcm43xx-mac80211/bcm43xx_debugfs.h    |   43 --
 .../net/wireless/bcm43xx-mac80211/bcm43xx_dma.c    |  108 ++++--
 .../net/wireless/bcm43xx-mac80211/bcm43xx_dma.h    |    8 
 drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.c |   27 +
 drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.h |    4 
 .../net/wireless/bcm43xx-mac80211/bcm43xx_main.c   |  400 +++++++++++++----------
 .../net/wireless/bcm43xx-mac80211/bcm43xx_phy.c    |   64 ++--
 .../net/wireless/bcm43xx-mac80211/bcm43xx_phy.h    |    4 
 .../net/wireless/bcm43xx-mac80211/bcm43xx_pio.c    |   18 +
 .../net/wireless/bcm43xx-mac80211/bcm43xx_pio.h    |    6 
 .../net/wireless/bcm43xx-mac80211/bcm43xx_sysfs.c  |    4 
 .../net/wireless/bcm43xx-mac80211/bcm43xx_xmit.c   |   23 +
 drivers/ssb/Kconfig                                |    1 
 drivers/ssb/Makefile                               |   18 +
 drivers/ssb/driver_chipcommon.c                    |   28 +
 drivers/ssb/driver_mipscore.c                      |   38 +-
 drivers/ssb/driver_pcicore.c                       |   30 +-
 drivers/ssb/main.c                                 |   90 ++---
 drivers/ssb/pci.c                                  |    4 
 drivers/ssb/pcmcia.c                               |   11 -
 drivers/ssb/scan.c                                 |   20 +
 drivers/ssb/ssb_private.h                          |   26 -
 include/linux/ssb/ssb.h                            |   29 +
 include/linux/ssb/ssb_driver_chipcommon.h          |    2 
 include/linux/ssb/ssb_driver_extif.h               |    3 
 include/linux/ssb/ssb_driver_mips.h                |    3 
 include/linux/ssb/ssb_driver_pci.h                 |    2 
 include/linux/ssb/ssb_regs.h                       |   12 -
 30 files changed, 593 insertions(+), 629 deletions(-)


diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx.h b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx.h
index 2802fc0..49b471a 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx.h
@@ -23,8 +23,6 @@ #include "bcm43xx_lo.h"
 #include "bcm43xx_phy.h"
 
 
-#define PFX				KBUILD_MODNAME ": "
-
 #define BCM43xx_IRQWAIT_MAX_RETRIES	50
 
 #define BCM43xx_IO_SIZE			8192
@@ -441,11 +439,12 @@ # undef assert
 #endif
 #ifdef CONFIG_BCM43XX_MAC80211_DEBUG
 # define assert(expr) \
-	do {									\
-		if (unlikely(!(expr))) {					\
-		printk(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n",	\
-			#expr, __FILE__, __LINE__, __FUNCTION__);		\
-		}								\
+	do {								\
+		if (unlikely(!(expr))) {				\
+		printk(KERN_ERR KBUILD_MODNAME ": "			\
+		       "ASSERTION FAILED (%s) at: %s:%d:%s()\n",	\
+			#expr, __FILE__, __LINE__, __FUNCTION__);	\
+		}							\
 	} while (0)
 # define BCM43xx_DEBUG	1
 #else
@@ -453,31 +452,6 @@ # define assert(expr)	do { /* nothing */
 # define BCM43xx_DEBUG	0
 #endif
 
-/* rate limited printk(). */
-#ifdef printkl
-# undef printkl
-#endif
-#define printkl(f, x...)  do { if (printk_ratelimit()) printk(f ,##x); } while (0)
-/* rate limited printk() for debugging */
-#ifdef dprintkl
-# undef dprintkl
-#endif
-#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
-# define dprintkl		printkl
-#else
-# define dprintkl(f, x...)	do { /* nothing */ } while (0)
-#endif
-
-/* debugging printk() */
-#ifdef dprintk
-# undef dprintk
-#endif
-#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
-# define dprintk(f, x...)  do { printk(f ,##x); } while (0)
-#else
-# define dprintk(f, x...)  do { /* nothing */ } while (0)
-#endif
-
 
 struct net_device;
 struct pci_dev;
@@ -499,7 +473,7 @@ struct bcm43xx_phy {
 	/* Possible PHYMODEs on this PHY */
 	u8 possible_phymodes;
 	/* GMODE bit enabled? */
-	u8 gmode;
+	bool gmode;
 	/* Possible ieee80211 subsystem hwmodes for this PHY.
 	 * Which mode is selected, depends on thr GMODE enabled bit */
 #define BCM43xx_MAX_PHYHWMODES	2
@@ -517,14 +491,14 @@ #define BCM43xx_MAX_PHYHWMODES	2
 	u16 radio_ver;		/* Radio version */
 	u8 radio_rev;		/* Radio revision */
 
-	u8 radio_on:1;		/* Radio switched on/off */
-	u8 locked:1;		/* Only used in bcm43xx_phy_{un}lock() */
-	u8 dyn_tssi_tbl:1;	/* tssi2dbm is kmalloc()ed. */
+	bool radio_on;		/* Radio switched on/off */
+	bool locked;		/* Only used in bcm43xx_phy_{un}lock() */
+	bool dyn_tssi_tbl;	/* tssi2dbm is kmalloc()ed. */
 
 	/* ACI (adjacent channel interference) flags. */
-	u8 aci_enable:1;
-	u8 aci_wlan_automatic:1;
-	u8 aci_hw_rssi:1;
+	bool aci_enable;
+	bool aci_wlan_automatic;
+	bool aci_hw_rssi;
 
 	u16 minlowsig[2];
 	u16 minlowsigpos[2];
@@ -561,7 +535,7 @@ #define BCM43xx_MAX_PHYHWMODES	2
 	struct bcm43xx_rfatt rfatt;
 	u8 tx_control; /* BCM43xx_TXCTL_XXX */
 #ifdef CONFIG_BCM43XX_MAC80211_DEBUG
-	u8 manual_txpower_control; /* Manual TX-power control enabled? */
+	bool manual_txpower_control; /* Manual TX-power control enabled? */
 #endif
 
 	/* Current Interference Mitigation mode */
@@ -614,7 +588,7 @@ struct bcm43xx_pio {
 /* Context information for a noise calculation (Link Quality). */
 struct bcm43xx_noise_calculation {
 	u8 channel_at_start;
-	u8 calculation_running:1;
+	bool calculation_running;
 	u8 nr_samples;
 	s8 samples[8][4];
 };
@@ -627,7 +601,7 @@ struct bcm43xx_stats {
 };
 
 struct bcm43xx_key {
-	u8 enabled;
+	bool enabled;
 	u8 algorithm;
 	u8 address[6];
 };
@@ -663,11 +637,11 @@ struct bcm43xx_wl {
 	/* Counter of active monitor interfaces. */
 	int monitor;
 	/* Is the card operating in AP, STA or IBSS mode? */
-	unsigned int operating:1;
+	bool operating;
 	/* Promisc mode active?
 	 * Note that (monitor != 0) implies promisc.
 	 */
-	unsigned int promisc:1;
+	bool promisc;
 	/* Stats about the wireless interface */
 	struct ieee80211_low_level_stats ieee_stats;
 
@@ -698,13 +672,13 @@ struct bcm43xx_firmware {
 
 /* Device (802.11 core) initialization status. */
 enum {
-	BCM43xx_STAT_UNINIT,		/* Uninitialized. */
-	BCM43xx_STAT_INITIALIZING,	/* bcm43xx_wireless_core_init() in progress. */
-	BCM43xx_STAT_INITIALIZED,	/* Initialized. Note that this doesn't mean it's started. */
+	BCM43xx_STAT_UNINIT		= 0, /* Uninitialized. */
+	BCM43xx_STAT_INITIALIZED	= 1, /* Initialized, but not started, yet. */
+	BCM43xx_STAT_STARTED		= 2, /* Up and running. */
 };
-#define bcm43xx_status(bcm)		atomic_read(&(bcm)->init_status)
-#define bcm43xx_set_status(bcm, stat)	do {			\
-		atomic_set(&(bcm)->init_status, (stat));	\
+#define bcm43xx_status(wldev)		atomic_read(&(wldev)->__init_status)
+#define bcm43xx_set_status(wldev, stat)	do {			\
+		atomic_set(&(wldev)->__init_status, (stat));	\
 		smp_wmb();					\
 					} while (0)
 
@@ -721,19 +695,18 @@ struct bcm43xx_wldev {
 	struct ssb_device *dev;
 	struct bcm43xx_wl *wl;
 
-	/* Driver initialization status BCM43xx_STAT_*** */
-	atomic_t init_status;
-	/* Interface started? (bcm43xx_wireless_core_start()) */
-	u8 started;
+	/* The device initialization status.
+	 * Use bcm43xx_status() to query. */
+	atomic_t __init_status;
+	/* Saved init status for handling suspend. */
+	int suspend_init_status;
 
-	u16 was_initialized:1,		/* for suspend/resume. */
-	    was_started:1,		/* for suspend/resume. */
-	    __using_pio:1,		/* Internal, use bcm43xx_using_pio(). */
-	    bad_frames_preempt:1,	/* Use "Bad Frames Preemption" (default off) */
-	    reg124_set_0x4:1,		/* Some variable to keep track of IRQ stuff. */
-	    short_preamble:1,		/* TRUE, if short preamble is enabled. */
-	    short_slot:1,		/* TRUE, if short slot timing is enabled. */
-	    radio_hw_enable:1;          /* saved state of radio hardware enabled state */
+	bool __using_pio;		/* Internal, use bcm43xx_using_pio(). */
+	bool bad_frames_preempt;	/* Use "Bad Frames Preemption" (default off) */
+	bool reg124_set_0x4;		/* Some variable to keep track of IRQ stuff. */
+	bool short_preamble;		/* TRUE, if short preamble is enabled. */
+	bool short_slot;		/* TRUE, if short slot timing is enabled. */
+	bool radio_hw_enable;		/* saved state of radio hardware enabled state */
 
 	/* PHY/Radio device. */
 	struct bcm43xx_phy phy;
@@ -863,6 +836,22 @@ void bcm43xx_write32(struct bcm43xx_wlde
 	ssb_write32(dev->dev, offset, value);
 }
 
+
+/* Message printing */
+void bcminfo(struct bcm43xx_wl *wl, const char *fmt, ...)
+		__attribute__((format(printf, 2, 3)));
+void bcmerr(struct bcm43xx_wl *wl, const char *fmt, ...)
+		__attribute__((format(printf, 2, 3)));
+void bcmwarn(struct bcm43xx_wl *wl, const char *fmt, ...)
+		__attribute__((format(printf, 2, 3)));
+#if BCM43xx_DEBUG
+void bcmdbg(struct bcm43xx_wl *wl, const char *fmt, ...)
+		__attribute__((format(printf, 2, 3)));
+#else /* DEBUG */
+# define bcmdbg(wl, fmt...) do { /* nothing */ } while (0)
+#endif /* DEBUG */
+
+
 /** Limit a value between two limits */
 #ifdef limit_value
 # undef limit_value
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.c
index 3ea9d08..9ca4625 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.c
@@ -92,7 +92,7 @@ static ssize_t tsf_read_file(struct file
 	mutex_lock(&big_buffer_mutex);
 	mutex_lock(&dev->wl->mutex);
 	spin_lock_irqsave(&dev->wl->irq_lock, flags);
-	if (bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED) {
+	if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED) {
 		fappend("Board not initialized.\n");
 		goto out;
 	}
@@ -128,13 +128,13 @@ static ssize_t tsf_write_file(struct fil
 	}
 	mutex_lock(&dev->wl->mutex);
 	spin_lock_irqsave(&dev->wl->irq_lock, flags);
-	if (bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED) {
-		printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
+	if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED) {
+		bcmerr(dev->wl, "debugfs: Board not initialized.\n");
 		res = -EFAULT;
 		goto out_unlock;
 	}
 	if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1) {
-		printk(KERN_INFO PFX "debugfs: invalid values for \"tsf\"\n");
+		bcmerr(dev->wl, "debugfs: invalid values for \"tsf\"\n");
 		res = -EINVAL;
 		goto out_unlock;
 	}
@@ -234,8 +234,8 @@ static ssize_t restart_write_file(struct
 	}
 	mutex_lock(&dev->wl->mutex);
 	spin_lock_irqsave(&dev->wl->irq_lock, flags);
-	if (bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED) {
-		printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
+	if (bcm43xx_status(dev) < BCM43xx_STAT_INITIALIZED) {
+		bcmerr(dev->wl, "debugfs: Board not initialized.\n");
 		res = -EFAULT;
 		goto out_unlock;
 	}
@@ -267,8 +267,7 @@ static ssize_t txpower_g_read_file(struc
 	mutex_lock(&big_buffer_mutex);
 	mutex_lock(&dev->wl->mutex);
 	spin_lock_irqsave(&dev->wl->irq_lock, flags);
-	if ((bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED) ||
-	    !dev->started) {
+	if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED) {
 		fappend("Not initialized\n");
 		goto out;
 	}
@@ -322,14 +321,13 @@ static ssize_t txpower_g_write_file(stru
 	}
 	mutex_lock(&dev->wl->mutex);
 	spin_lock_irqsave(&dev->wl->irq_lock, flags);
-	if ((bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED) ||
-	    !dev->started) {
-		printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
+	if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED) {
+		bcmerr(dev->wl, "debugfs: Board not initialized.\n");
 		res = -ENODEV;
 		goto out_unlock;
 	}
 	if (dev->phy.type != BCM43xx_PHYTYPE_G) {
-		printk(KERN_ERR PFX "debugfs: Device is not a G-PHY\n");
+		bcmerr(dev->wl, "debugfs: Device is not a G-PHY\n");
 		res = -ENODEV;
 		goto out_unlock;
 	}
@@ -342,7 +340,7 @@ static ssize_t txpower_g_write_file(stru
 		/* Manual control */
 		if (sscanf(buf, "%d %d %d %d %d", &bbatt, &rfatt,
 			   &txmix, &pa2db, &pa3db) != 5) {
-			printk(KERN_INFO PFX "debugfs: invalid value for \"tx_power_g\"\n");
+			bcmerr(dev->wl, "debugfs: invalid value for \"tx_power_g\"\n");
 			res = -EINVAL;
 			goto out_unlock;
 		}
@@ -437,6 +435,7 @@ #define add_dyn_dbg(name, id, initstate)
 
 	add_dyn_dbg("debug_xmitpower", BCM43xx_DBG_XMITPOWER, 0);
 	add_dyn_dbg("debug_dmaoverflow", BCM43xx_DBG_DMAOVERFLOW, 0);
+	add_dyn_dbg("debug_dmaverbose", BCM43xx_DBG_DMAVERBOSE, 0);
 	add_dyn_dbg("debug_pwork_fast", BCM43xx_DBG_PWORK_FAST, 0);
 	add_dyn_dbg("debug_pwork_stop", BCM43xx_DBG_PWORK_STOP, 0);
 
@@ -452,7 +451,7 @@ void bcm43xx_debugfs_add_device(struct b
 	assert(dev);
 	e = kzalloc(sizeof(*e), GFP_KERNEL);
 	if (!e) {
-		printk(KERN_ERR PFX "debugfs: add device OOM\n");
+		bcmerr(dev->wl, "debugfs: add device OOM\n");
 		return;
 	}
 	e->dev = dev;
@@ -461,7 +460,7 @@ void bcm43xx_debugfs_add_device(struct b
 			   sizeof(struct bcm43xx_txstatus),
 			   GFP_KERNEL);
 	if (!log->log) {
-		printk(KERN_ERR PFX "debugfs: add device txstatus OOM\n");
+		bcmerr(dev->wl, "debugfs: add device txstatus OOM\n");
 		kfree(e);
 		return;
 	}
@@ -557,57 +556,3 @@ void bcm43xx_debugfs_exit(void)
 	debugfs_remove(fs.dentry_driverinfo);
 	debugfs_remove(fs.root);
 }
-
-void bcm43xx_printk_dump(const char *data,
-			 size_t size,
-			 const char *description)
-{
-	unsigned int i;
-	char c;
-
-	printk(KERN_INFO PFX "Data dump (%s, %lu bytes):",
-	       description, (unsigned long)size);
-	for (i = 0; i < size; i++) {
-		c = data[i];
-		if (i % 8 == 0)
-			printk("\n" KERN_INFO PFX "0x%08x:  0x%02x, ", i, c & 0xff);
-		else
-			printk("0x%02x, ", c & 0xff);
-	}
-	printk("\n");
-}
-
-void bcm43xx_printk_bitdump(const unsigned char *data,
-			    size_t bytes, int msb_to_lsb,
-			    const char *description)
-{
-	unsigned int i;
-	int j;
-	const unsigned char *d;
-
-	printk(KERN_INFO PFX "*** Bitdump (%s, %lu bytes, %s) ***",
-	       description, (unsigned long)bytes,
-	       msb_to_lsb ? "MSB to LSB" : "LSB to MSB");
-	for (i = 0; i < bytes; i++) {
-		d = data + i;
-		if (i % 8 == 0)
-			printk("\n" KERN_INFO PFX "0x%08x:  ", i);
-		if (msb_to_lsb) {
-			for (j = 7; j >= 0; j--) {
-				if (*d & (1 << j))
-					printk("1");
-				else
-					printk("0");
-			}
-		} else {
-			for (j = 0; j < 8; j++) {
-				if (*d & (1 << j))
-					printk("1");
-				else
-					printk("0");
-			}
-		}
-		printk(" ");
-	}
-	printk("\n");
-}
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.h b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.h
index 892299d..65f6b1f 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.h
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.h
@@ -7,6 +7,7 @@ struct bcm43xx_txstatus;
 enum bcm43xx_dyndbg { /* Dynamic debugging features */
 	BCM43xx_DBG_XMITPOWER,
 	BCM43xx_DBG_DMAOVERFLOW,
+	BCM43xx_DBG_DMAVERBOSE,
 	BCM43xx_DBG_PWORK_FAST,
 	BCM43xx_DBG_PWORK_STOP,
 	__BCM43xx_NR_DYNDBG,
@@ -59,22 +60,6 @@ void bcm43xx_debugfs_remove_device(struc
 void bcm43xx_debugfs_log_txstat(struct bcm43xx_wldev *dev,
 				const struct bcm43xx_txstatus *status);
 
-/* Debug helper: Dump binary data through printk. */
-void bcm43xx_printk_dump(const char *data,
-			 size_t size,
-			 const char *description);
-/* Debug helper: Dump bitwise binary data through printk. */
-void bcm43xx_printk_bitdump(const unsigned char *data,
-			    size_t bytes, int msb_to_lsb,
-			    const char *description);
-#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) \
-	do {									\
-		bcm43xx_printk_bitdump((const unsigned char *)(pointer),	\
-				       sizeof(*(pointer)),			\
-				       (msb_to_lsb),				\
-				       (description));				\
-	} while (0)
-
 #else /* CONFIG_BCM43XX_MAC80211_DEBUG*/
 
 static inline
@@ -95,20 +80,6 @@ static inline
 void bcm43xx_debugfs_log_txstat(struct bcm43xx_wldev *dev,
 				const struct bcm43xx_txstatus *status) { }
 
-static inline
-void bcm43xx_printk_dump(const char *data,
-			 size_t size,
-			 const char *description)
-{
-}
-static inline
-void bcm43xx_printk_bitdump(const unsigned char *data,
-			    size_t bytes, int msb_to_lsb,
-			    const char *description)
-{
-}
-#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description)  do { /* nothing */ } while (0)
-
 #endif /* CONFIG_BCM43XX_MAC80211_DEBUG*/
 
 /* Ugly helper macros to make incomplete code more verbose on runtime */
@@ -116,18 +87,18 @@ #ifdef TODO
 # undef TODO
 #endif
 #define TODO()  \
-	do {										\
-		printk(KERN_INFO PFX "TODO: Incomplete code in %s() at %s:%d\n",	\
-		       __FUNCTION__, __FILE__, __LINE__);				\
+	do {									\
+		bcminfo(NULL, "TODO: Incomplete code in %s() at %s:%d\n",	\
+			__FUNCTION__, __FILE__, __LINE__);			\
 	} while (0)
 
 #ifdef FIXME
 # undef FIXME
 #endif
 #define FIXME()  \
-	do {										\
-		printk(KERN_INFO PFX "FIXME: Possibly broken code in %s() at %s:%d\n",	\
-		       __FUNCTION__, __FILE__, __LINE__);				\
+	do {									\
+		bcminfo(NULL, "FIXME: Possibly broken code in %s() at %s:%d\n",	\
+			__FUNCTION__, __FILE__, __LINE__);			\
 	} while (0)
 
 #endif /* BCM43xx_DEBUGFS_H_ */
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.c
index c8b5cdd..5476250 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.c
@@ -259,6 +259,28 @@ static inline int prev_slot(struct bcm43
 	return slot - 1;
 }
 
+#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
+static void update_max_used_slots(struct bcm43xx_dmaring *ring,
+				  int current_used_slots)
+{
+	if (current_used_slots <= ring->max_used_slots)
+		return;
+	ring->max_used_slots = current_used_slots;
+	if (bcm43xx_debug(ring->dev, BCM43xx_DBG_DMAVERBOSE)) {
+		bcmdbg(ring->dev->wl,
+		       "max_used_slots increased to %d on %s ring %d\n",
+		       ring->max_used_slots,
+		       ring->tx ? "TX" : "RX",
+		       ring->index);
+	}
+}
+#else
+static inline
+void update_max_used_slots(struct bcm43xx_dmaring *ring,
+			   int current_used_slots)
+{ }
+#endif /* DEBUG */
+
 /* Request a slot for usage. */
 static inline
 int request_slot(struct bcm43xx_dmaring *ring)
@@ -273,23 +295,11 @@ int request_slot(struct bcm43xx_dmaring 
 	ring->current_slot = slot;
 	ring->used_slots++;
 
-#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
-	if (ring->used_slots > ring->max_used_slots)
-		ring->max_used_slots = ring->used_slots;
-#endif /* CONFIG_BCM43XX_MAC80211_DEBUG*/
+	update_max_used_slots(ring, ring->used_slots);
 
 	return slot;
 }
 
-/* Return a slot to the free slots. */
-static inline
-void return_slot(struct bcm43xx_dmaring *ring, int slot)
-{
-	assert(ring->tx);
-
-	ring->used_slots--;
-}
-
 /* Mac80211-queue to bcm43xx-ring mapping */
 static struct bcm43xx_dmaring * priority_to_txring(struct bcm43xx_wldev *dev,
 						   int queue_priority)
@@ -450,7 +460,7 @@ static int alloc_ringmemory(struct bcm43
 	ring->descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
 					    &(ring->dmabase), GFP_KERNEL);
 	if (!ring->descbase) {
-		printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
+		bcmerr(ring->dev->wl, "DMA ringmemory allocation failed\n");
 		return -ENOMEM;
 	}
 	memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);
@@ -497,7 +507,7 @@ int bcm43xx_dmacontroller_rx_reset(struc
 		msleep(1);
 	}
 	if (i != -1) {
-		printk(KERN_ERR PFX "ERROR: DMA RX reset timed out\n");
+		bcmerr(dev->wl, "DMA RX reset timed out\n");
 		return -ENODEV;
 	}
 
@@ -553,7 +563,7 @@ int bcm43xx_dmacontroller_tx_reset(struc
 		msleep(1);
 	}
 	if (i != -1) {
-		printk(KERN_ERR PFX "ERROR: DMA TX reset timed out\n");
+		bcmerr(dev->wl, "DMA TX reset timed out\n");
 		return -ENODEV;
 	}
 	/* ensure the reset is completed. */
@@ -624,7 +634,8 @@ static int alloc_initial_descbuffers(str
 
 		err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
 		if (err) {
-			printk(KERN_ERR PFX "Failed to allocate initial descbuffers\n");
+			bcmerr(ring->dev->wl,
+			       "Failed to allocate initial descbuffers\n");
 			goto err_unwind;
 		}
 	}
@@ -903,11 +914,11 @@ static void bcm43xx_destroy_dmaring(stru
 	if (!ring)
 		return;
 
-	dprintk(KERN_INFO PFX "DMA-%s 0x%04X (%s) max used slots: %d/%d\n",
-		(ring->dma64) ? "64" : "32",
-		ring->mmio_base,
-		(ring->tx) ? "TX" : "RX",
-		ring->max_used_slots, ring->nr_slots);
+	bcmdbg(ring->dev->wl, "DMA-%s 0x%04X (%s) max used slots: %d/%d\n",
+	       (ring->dma64) ? "64" : "32",
+	       ring->mmio_base,
+	       (ring->tx) ? "TX" : "RX",
+	       ring->max_used_slots, ring->nr_slots);
 	/* Device IRQs are disabled prior entering this function,
 	 * so no need to take care of concurrency with rx handler stuff.
 	 */
@@ -962,13 +973,13 @@ int bcm43xx_dma_init(struct bcm43xx_wlde
 	err = ssb_dma_set_mask(dev->dev, dmamask);
 	if (err) {
 #ifdef BCM43XX_MAC80211_PIO
-		printk(KERN_WARNING PFX "DMA for this device not supported. "
-					"Falling back to PIO\n");
+		bcmwarn(dev->wl, "DMA for this device not supported. "
+			"Falling back to PIO\n");
 		dev->__using_pio = 1;
 		return -EAGAIN;
 #else
-		printk(KERN_ERR PFX "DMA for this device not supported and "
-				    "no PIO support compiled in\n");
+		bcmerr(dev->wl, "DMA for this device not supported and "
+		       "no PIO support compiled in\n");
 		return -EOPNOTSUPP;
 #endif
 	}
@@ -1018,9 +1029,9 @@ #endif
 		dma->rx_ring3 = ring;
 	}
 
-	dprintk(KERN_INFO PFX "%d-bit DMA initialized\n",
-		(dmamask == DMA_64BIT_MASK) ? 64 :
-		(dmamask == DMA_32BIT_MASK) ? 32 : 30);
+	bcmdbg(dev->wl, "%d-bit DMA initialized\n",
+	       (dmamask == DMA_64BIT_MASK) ? 64 :
+	       (dmamask == DMA_32BIT_MASK) ? 32 : 30);
 	err = 0;
 out:
 	return err;
@@ -1213,8 +1224,9 @@ #ifdef CONFIG_BCM43XX_MAC80211_DEBUG
 		next_overflow = ring->last_injected_overflow + HZ;
 		if (time_after(jiffies, next_overflow)) {
 			ring->last_injected_overflow = jiffies;
-			dprintk(KERN_DEBUG PFX "Injecting TX ring overflow on "
-				"DMA controller %d\n", ring->index);
+			bcmdbg(ring->dev->wl,
+			       "Injecting TX ring overflow on "
+			       "DMA controller %d\n", ring->index);
 			return 1;
 		}
 	}
@@ -1234,7 +1246,7 @@ int bcm43xx_dma_tx(struct bcm43xx_wldev 
 	spin_lock_irqsave(&ring->lock, flags);
 	assert(ring->tx);
 	if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
-		printkl(KERN_ERR PFX "DMA queue overflow\n");
+		bcmwarn(dev->wl, "DMA queue overflow\n");
 		err = -ENOSPC;
 		goto out_unlock;
 	}
@@ -1245,7 +1257,7 @@ int bcm43xx_dma_tx(struct bcm43xx_wldev 
 
 	err = dma_tx_fragment(ring, skb, ctl);
 	if (unlikely(err)) {
-		printkl(KERN_ERR PFX "DMA tx mapping failure\n");
+		bcmerr(dev->wl, "DMA tx mapping failure\n");
 		goto out_unlock;
 	}
 	ring->nr_tx_packets++;
@@ -1254,6 +1266,10 @@ int bcm43xx_dma_tx(struct bcm43xx_wldev 
 		/* This TX ring is full. */
 		ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring));
 		ring->stopped = 1;
+		if (bcm43xx_debug(dev, BCM43xx_DBG_DMAVERBOSE)) {
+			bcmdbg(dev->wl, "Stopped TX ring %d\n",
+			       ring->index);
+		}
 	}
 out_unlock:
 	spin_unlock_irqrestore(&ring->lock, flags);
@@ -1305,10 +1321,9 @@ void bcm43xx_dma_handle_txstatus(struct 
 			 */
 			assert(meta->skb == NULL);
 		}
-		/* Everything belonging to the slot is unmapped
-		 * and freed, so we can return it.
-		 */
-		return_slot(ring, slot);
+
+		/* Everything unmapped and free'd. So it's not used anymore. */
+		ring->used_slots--;
 
 		if (meta->is_last_fragment)
 			break;
@@ -1319,6 +1334,10 @@ void bcm43xx_dma_handle_txstatus(struct 
 		assert(free_slots(ring) >= SLOTS_PER_PACKET);
 		ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring));
 		ring->stopped = 0;
+		if (bcm43xx_debug(dev, BCM43xx_DBG_DMAVERBOSE)) {
+			bcmdbg(dev->wl, "Woke up TX ring %d\n",
+			       ring->index);
+		}
 	}
 
 	spin_unlock(&ring->lock);
@@ -1417,16 +1436,16 @@ static void dma_rx(struct bcm43xx_dmarin
 			if (tmp <= 0)
 				break;
 		}
-		printkl(KERN_ERR PFX "DMA RX buffer too small "
-			"(len: %u, buffer: %u, nr-dropped: %d)\n",
-			len, ring->rx_buffersize, cnt);
+		bcmerr(ring->dev->wl, "DMA RX buffer too small "
+		       "(len: %u, buffer: %u, nr-dropped: %d)\n",
+		       len, ring->rx_buffersize, cnt);
 		goto drop;
 	}
 
 	dmaaddr = meta->dmaaddr;
 	err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC);
 	if (unlikely(err)) {
-		dprintkl(KERN_ERR PFX "DMA RX: setup_rx_descbuffer() failed\n");
+		bcmdbg(ring->dev->wl, "DMA RX: setup_rx_descbuffer() failed\n");
 		sync_descbuffer_for_device(ring, dmaaddr,
 					   ring->rx_buffersize);
 		goto drop;
@@ -1445,9 +1464,7 @@ void bcm43xx_dma_rx(struct bcm43xx_dmari
 {
 	const struct bcm43xx_dma_ops *ops = ring->ops;
 	int slot, current_slot;
-#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
 	int used_slots = 0;
-#endif
 
 	assert(!ring->tx);
 	current_slot = ops->get_current_rxslot(ring);
@@ -1456,10 +1473,7 @@ #endif
 	slot = ring->current_slot;
 	for ( ; slot != current_slot; slot = next_slot(ring, slot)) {
 		dma_rx(ring, &slot);
-#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
-		if (++used_slots > ring->max_used_slots)
-			ring->max_used_slots = used_slots;
-#endif
+		update_max_used_slots(ring, ++used_slots);
 	}
 	ops->set_current_rxslot(ring, slot);
 	ring->current_slot = slot;
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.h
index 3d109b1..baabeed 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.h
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.h
@@ -194,7 +194,7 @@ struct bcm43xx_dmadesc_meta {
 	/* DMA base bus-address of the descriptor buffer. */
 	dma_addr_t dmaaddr;
 	/* ieee80211 TX status. Only used once per 802.11 frag. */
-	u8 is_last_fragment;
+	bool is_last_fragment;
 	struct ieee80211_tx_status txstat;
 };
 
@@ -247,11 +247,11 @@ struct bcm43xx_dmaring {
 	/* DMA controller index number (0-5). */
 	int index;
 	/* Boolean. Is this a TX ring? */
-	u8 tx;
+	bool tx;
 	/* Boolean. 64bit DMA if true, 32bit DMA otherwise. */
-	u8 dma64;
+	bool dma64;
 	/* Boolean. Is this ring stopped at ieee80211 level? */
-	u8 stopped;
+	bool stopped;
 	/* Lock, only used for TX. */
 	spinlock_t lock;
 	struct bcm43xx_wldev *dev;
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.c
index aa1a298..b405779 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.c
@@ -47,8 +47,8 @@ static void bcm43xx_lo_write(struct bcm4
 	if (BCM43xx_DEBUG) {
 		if (unlikely(abs(control->i) > 16 ||
 			     abs(control->q) > 16)) {
-			printk(KERN_ERR PFX "ERROR: Invalid LO control pair "
-					    "(I: %d, Q: %d)\n",
+			bcmdbg(dev->wl, "Invalid LO control pair "
+			       "(I: %d, Q: %d)\n",
 			       control->i, control->q);
 			dump_stack();
 			return;
@@ -64,22 +64,21 @@ static void bcm43xx_lo_write(struct bcm4
 
 static inline
 int assert_rfatt_and_bbatt(const struct bcm43xx_rfatt *rfatt,
-			   const struct bcm43xx_bbatt *bbatt)
+			   const struct bcm43xx_bbatt *bbatt,
+			   struct bcm43xx_wldev *dev)
 {
 	int err = 0;
 
 	/* Check the attenuation values against the LO control array sizes. */
 #if BCM43xx_DEBUG
 	if (rfatt->att >= BCM43xx_NR_RF) {
-		dprintk(KERN_ERR PFX
-			"ERROR: rfatt(%u) >= size of LO array\n",
-			rfatt->att);
+		bcmdbg(dev->wl, "rfatt(%u) >= size of LO array\n",
+		       rfatt->att);
 		err = -EINVAL;
 	}
 	if (bbatt->att >= BCM43xx_NR_BB) {
-		dprintk(KERN_ERR PFX
-			"ERROR: bbatt(%u) >= size of LO array\n",
-			bbatt->att);
+		bcmdbg(dev->wl, "bbatt(%u) >= size of LO array\n",
+		       bbatt->att);
 		err = -EINVAL;
 	}
 	if (err)
@@ -97,7 +96,7 @@ struct bcm43xx_loctl * bcm43xx_get_lo_g_
 	struct bcm43xx_phy *phy = &dev->phy;
 	struct bcm43xx_txpower_lo_control *lo = phy->lo_control;
 
-	if (assert_rfatt_and_bbatt(rfatt, bbatt))
+	if (assert_rfatt_and_bbatt(rfatt, bbatt, dev))
 		return &(lo->no_padmix[0][0]); /* Just prevent a crash */
 	return &(lo->no_padmix[bbatt->att][rfatt->att]);
 }
@@ -109,7 +108,7 @@ struct bcm43xx_loctl * bcm43xx_get_lo_g_
 	struct bcm43xx_phy *phy = &dev->phy;
 	struct bcm43xx_txpower_lo_control *lo = phy->lo_control;
 
-	if (assert_rfatt_and_bbatt(rfatt, bbatt))
+	if (assert_rfatt_and_bbatt(rfatt, bbatt, dev))
 		return &(lo->no_padmix[0][0]); /* Just prevent a crash */
 	if (rfatt->with_padmix)
 		return &(lo->with_padmix[bbatt->att][rfatt->att]);
@@ -1013,13 +1012,13 @@ #if BCM43xx_DEBUG
 static void do_validate_loctl(struct bcm43xx_wldev *dev,
 			      struct bcm43xx_loctl *control)
 {
-	const int is_initializing = (bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZING);
+	const int is_initializing = (bcm43xx_status(dev) == BCM43xx_STAT_UNINIT);
 
 	if (unlikely(abs(control->i) > 16 ||
 		     abs(control->q) > 16 ||
 		     (is_initializing && control->used))) {
-		printk(KERN_ERR PFX "ERROR: LO control pair validation failed "
-				    "(first: %d, second: %d, used %u)\n",
+		bcmdbg(dev->wl, "ERROR: LO control pair validation failed "
+		       "(first: %d, second: %d, used %u)\n",
 		       control->i, control->q, control->used);
 	}
 }
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.h b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.h
index 71fbe3e..377bda4 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.h
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.h
@@ -35,7 +35,7 @@ #define BCM43xx_NR_RF	16
 
 	/* Flag to indicate a complete rebuild of the two tables above
 	 * to the LO measuring code. */
-	u8 rebuild;
+	bool rebuild;
 
 	/* Lists of valid RF and BB attenuation values for this device. */
 	struct bcm43xx_rfatt_list rfatt_list;
@@ -47,7 +47,7 @@ #define BCM43xx_NR_RF	16
 	u8 tx_magn;
 
 	/* GPHY LO is measured. */
-	u8 lo_measured;
+	bool lo_measured;
 
 	/* Saved device PowerVector */
 	u64 power_vector;
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_main.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_main.c
index eefc536..7a9dd02 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_main.c
@@ -194,6 +194,69 @@ static void bcm43xx_wireless_core_stop(s
 static int bcm43xx_wireless_core_start(struct bcm43xx_wldev *dev);
 
 
+static int bcm43xx_ratelimit(struct bcm43xx_wl *wl)
+{
+	if (!wl || !wl->current_dev)
+		return 1;
+	if (bcm43xx_status(wl->current_dev) < BCM43xx_STAT_STARTED)
+		return 1;
+	/* We are up and running.
+	 * Ratelimit the messages to avoid DoS over the net. */
+	return net_ratelimit();
+}
+
+void bcminfo(struct bcm43xx_wl *wl, const char *fmt, ...)
+{
+	va_list args;
+
+	if (!bcm43xx_ratelimit(wl))
+		return;
+	va_start(args, fmt);
+	printk(KERN_INFO "bcm43xx-%s: ",
+	       (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
+	vprintk(fmt, args);
+	va_end(args);
+}
+
+void bcmerr(struct bcm43xx_wl *wl, const char *fmt, ...)
+{
+	va_list args;
+
+	if (!bcm43xx_ratelimit(wl))
+		return;
+	va_start(args, fmt);
+	printk(KERN_ERR "bcm43xx-%s ERROR: ",
+	       (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
+	vprintk(fmt, args);
+	va_end(args);
+}
+
+void bcmwarn(struct bcm43xx_wl *wl, const char *fmt, ...)
+{
+	va_list args;
+
+	if (!bcm43xx_ratelimit(wl))
+		return;
+	va_start(args, fmt);
+	printk(KERN_WARNING "bcm43xx-%s warning: ",
+	       (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
+	vprintk(fmt, args);
+	va_end(args);
+}
+
+#if BCM43xx_DEBUG
+void bcmdbg(struct bcm43xx_wl *wl, const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	printk(KERN_DEBUG "bcm43xx-%s debug: ",
+	       (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
+	vprintk(fmt, args);
+	va_end(args);
+}
+#endif /* DEBUG */
+
 static void bcm43xx_ram_write(struct bcm43xx_wldev *dev, u16 offset, u32 val)
 {
 	u32 status;
@@ -772,7 +835,7 @@ static int bcm43xx_key_write(struct bcm4
 			}
 		}
 		if (index < 0) {
-			dprintk(KERN_ERR PFX "Out of hw key memory\n");
+			bcmerr(dev->wl, "Out of hardware key memory\n");
 			return -ENOBUFS;
 		}
 	} else
@@ -1080,21 +1143,13 @@ static void bcm43xx_write_probe_resp_plc
 {
 	struct bcm43xx_plcp_hdr4 plcp;
 	u32 tmp;
-	u16 packet_time;
+	__le16 dur;
 
 	plcp.data = 0;
 	bcm43xx_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
-	/*
-	 * 144 + 48 + 10 = preamble + PLCP + SIFS,
-	 * taken from mac80211 timings calculation.
-	 *
-	 * FIXME: long preamble assumed!
-	 *
-	 */
-	packet_time = 202 + (size + FCS_LEN) * 16 / rate;
-	if ((size + FCS_LEN) * 16 % rate >= rate / 2)
-		++packet_time;
-
+	dur = ieee80211_generic_frame_duration(dev->wl->hw,
+					       dev->wl->if_id, size,
+					       BCM43xx_RATE_TO_BASE100KBPS(rate));
 	/* Write PLCP in two parts and timing for packet transfer */
 	tmp = le32_to_cpu(plcp.data);
 	bcm43xx_shm_write16(dev, BCM43xx_SHM_SHARED, shm_offset,
@@ -1102,7 +1157,7 @@ static void bcm43xx_write_probe_resp_plc
 	bcm43xx_shm_write16(dev, BCM43xx_SHM_SHARED, shm_offset + 2,
 			    tmp >> 16);
 	bcm43xx_shm_write16(dev, BCM43xx_SHM_SHARED, shm_offset + 6,
-			    packet_time);
+			    le16_to_cpu(dur));
 }
 
 /* Instead of using custom probe response template, this function
@@ -1116,15 +1171,17 @@ static u8 * bcm43xx_generate_probe_resp(
 {
 	const u8 *src_data;
 	u8 *dest_data;
-	u16 src_size, elem_size, src_pos, dest_pos, tmp;
+	u16 src_size, elem_size, src_pos, dest_pos;
+	__le16 dur;
+	struct ieee80211_hdr *hdr;
 
 	assert(dev->cached_beacon);
 	src_size = dev->cached_beacon->len;
 	src_data = (const u8*)dev->cached_beacon->data;
 
 	if (unlikely(src_size < 0x24)) {
-		dprintk(KERN_ERR PFX "bcm43xx_generate_probe_resp: "
-				     "invalid beacon\n");
+		bcmdbg(dev->wl, "bcm43xx_generate_probe_resp: "
+		       "invalid beacon\n");
 		return NULL;
 	}
 
@@ -1146,26 +1203,15 @@ static u8 * bcm43xx_generate_probe_resp(
 		}
 	}
 	*dest_size = dest_pos;
+	hdr = (struct ieee80211_hdr *)dest_data;
 
 	/* Set the frame control. */
-	dest_data[0] = (IEEE80211_FTYPE_MGMT |
-			IEEE80211_STYPE_PROBE_RESP);
-	dest_data[1] = 0;
-
-	/* Set the duration field.
-	 *
-	 * 144 + 48 + 10 = preamble + PLCP + SIFS,
-	 * taken from mac80211 timings calculation.
-	 *
-	 * FIXME: long preamble assumed!
-	 *
-	 */
-	tmp = 202 + (14 + FCS_LEN) * 16 / rate;
-	if ((14 + FCS_LEN) * 16 % rate >= rate / 2)
-		++tmp;
-
-	dest_data[2] = tmp & 0xFF;
-	dest_data[3] = (tmp >> 8) & 0xFF;
+	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+					 IEEE80211_STYPE_PROBE_RESP);
+	dur = ieee80211_generic_frame_duration(dev->wl->hw,
+					       dev->wl->if_id, *dest_size,
+					       BCM43xx_RATE_TO_BASE100KBPS(rate));
+	hdr->duration_id = dur;
 
 	return dest_data;
 }
@@ -1328,8 +1374,7 @@ static void bcm43xx_interrupt_tasklet(st
 
 	spin_lock_irqsave(&dev->wl->irq_lock, flags);
 
-	assert(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED);
-	assert(dev->started);
+	assert(bcm43xx_status(dev) == BCM43xx_STAT_STARTED);
 
 	reason = dev->irq_reason;
 	for (i = 0; i < ARRAY_SIZE(dma_reason); i++) {
@@ -1338,32 +1383,32 @@ static void bcm43xx_interrupt_tasklet(st
 	}
 
 	if (unlikely(reason & BCM43xx_IRQ_MAC_TXERR))
-		printkl(KERN_ERR PFX "MAC transmission error\n");
+		bcmerr(dev->wl, "MAC transmission error\n");
 
 	if (unlikely(reason & BCM43xx_IRQ_PHY_TXERR))
-		printkl(KERN_ERR PFX "PHY transmission error\n");
+		bcmerr(dev->wl, "PHY transmission error\n");
 
 	if (unlikely(merged_dma_reason & (BCM43xx_DMAIRQ_FATALMASK |
 					  BCM43xx_DMAIRQ_NONFATALMASK))) {
 		if (merged_dma_reason & BCM43xx_DMAIRQ_FATALMASK) {
-			printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
-					     "0x%08X, 0x%08X, 0x%08X, "
-					     "0x%08X, 0x%08X, 0x%08X\n",
-			        dma_reason[0], dma_reason[1],
-				dma_reason[2], dma_reason[3],
-				dma_reason[4], dma_reason[5]);
+			bcmerr(dev->wl, "Fatal DMA error: "
+			       "0x%08X, 0x%08X, 0x%08X, "
+			       "0x%08X, 0x%08X, 0x%08X\n",
+			       dma_reason[0], dma_reason[1],
+			       dma_reason[2], dma_reason[3],
+			       dma_reason[4], dma_reason[5]);
 			bcm43xx_controller_restart(dev, "DMA error");
 			mmiowb();
 			spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
 			return;
 		}
 		if (merged_dma_reason & BCM43xx_DMAIRQ_NONFATALMASK) {
-			printkl(KERN_ERR PFX "DMA error: "
-					     "0x%08X, 0x%08X, 0x%08X, "
-					     "0x%08X, 0x%08X, 0x%08X\n",
-			        dma_reason[0], dma_reason[1],
-				dma_reason[2], dma_reason[3],
-				dma_reason[4], dma_reason[5]);
+			bcmerr(dev->wl, "DMA error: "
+			       "0x%08X, 0x%08X, 0x%08X, "
+			       "0x%08X, 0x%08X, 0x%08X\n",
+			       dma_reason[0], dma_reason[1],
+			       dma_reason[2], dma_reason[3],
+			       dma_reason[4], dma_reason[5]);
 		}
 	}
 
@@ -1458,7 +1503,7 @@ static void bcm43xx_interrupt_ack(struct
 /* Interrupt handler top-half */
 static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id)
 {
-	irqreturn_t ret = IRQ_HANDLED;
+	irqreturn_t ret = IRQ_NONE;
 	struct bcm43xx_wldev *dev = dev_id;
 	u32 reason;
 
@@ -1467,18 +1512,17 @@ static irqreturn_t bcm43xx_interrupt_han
 
 	spin_lock(&dev->wl->irq_lock);
 
+	if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED)
+		goto out;
 	reason = bcm43xx_read32(dev, BCM43xx_MMIO_GEN_IRQ_REASON);
-	if (reason == 0xffffffff) {
-		/* irq not for us (shared irq) */
-		ret = IRQ_NONE;
+	if (reason == 0xffffffff) /* shared IRQ */
 		goto out;
-	}
+	ret = IRQ_HANDLED;
 	reason &= bcm43xx_read32(dev, BCM43xx_MMIO_GEN_IRQ_MASK);
 	if (!reason)
 		goto out;
 
-	assert(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED);
-	assert(dev->started);
+	assert(bcm43xx_status(dev) == BCM43xx_STAT_STARTED);
 
 	dev->dma_reason[0] = bcm43xx_read32(dev, BCM43xx_MMIO_DMA0_REASON)
 			     & 0x0001DC00;
@@ -1531,9 +1575,8 @@ static int bcm43xx_request_firmware(stru
 			 modparam_fwpostfix);
 		err = request_firmware(&dev->fw.ucode, buf, dev->dev->dev);
 		if (err) {
-			printk(KERN_ERR PFX
-			       "Error: Microcode \"%s\" not available or load failed.\n",
-			        buf);
+			bcmerr(dev->wl, "Microcode \"%s\" not "
+			       "available or load failed.\n", buf);
 			goto error;
 		}
 	}
@@ -1545,9 +1588,8 @@ static int bcm43xx_request_firmware(stru
 			 modparam_fwpostfix);
 		err = request_firmware(&dev->fw.pcm, buf, dev->dev->dev);
 		if (err) {
-			printk(KERN_ERR PFX
-			       "Error: PCM \"%s\" not available or load failed.\n",
-			       buf);
+			bcmerr(dev->wl, "PCM \"%s\" not available "
+			       "or load failed.\n", buf);
 			goto error;
 		}
 	}
@@ -1585,13 +1627,12 @@ static int bcm43xx_request_firmware(stru
 
 		err = request_firmware(&dev->fw.initvals0, buf, dev->dev->dev);
 		if (err) {
-			printk(KERN_ERR PFX
-			       "Error: InitVals \"%s\" not available or load failed.\n",
-			        buf);
+			bcmerr(dev->wl, "InitVals \"%s\" not available "
+			       "or load failed.\n", buf);
 			goto error;
 		}
 		if (dev->fw.initvals0->size % sizeof(struct bcm43xx_initval)) {
-			printk(KERN_ERR PFX "InitVals fileformat error.\n");
+			bcmerr(dev->wl, "InitVals fileformat error.\n");
 			goto error;
 		}
 	}
@@ -1620,13 +1661,12 @@ static int bcm43xx_request_firmware(stru
 
 			err = request_firmware(&dev->fw.initvals1, buf, dev->dev->dev);
 			if (err) {
-				printk(KERN_ERR PFX
-				       "Error: InitVals \"%s\" not available or load failed.\n",
-					buf);
+				bcmerr(dev->wl, "InitVals \"%s\" not available "
+				       "or load failed.\n", buf);
 				goto error;
 			}
 			if (dev->fw.initvals1->size % sizeof(struct bcm43xx_initval)) {
-				printk(KERN_ERR PFX "InitVals fileformat error.\n");
+				bcmerr(dev->wl, "InitVals fileformat error.\n");
 				goto error;
 			}
 		}
@@ -1638,7 +1678,7 @@ error:
 	bcm43xx_release_firmware(dev);
 	goto out;
 err_noinitval:
-	printk(KERN_ERR PFX "Error: No InitVals available!\n");
+	bcmerr(dev->wl, "No InitVals available\n");
 	err = -ENOENT;
 	goto error;
 }
@@ -1687,7 +1727,7 @@ static int bcm43xx_upload_microcode(stru
 			break;
 		i++;
 		if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
-			printk(KERN_ERR PFX "Microcode not responding\n");
+			bcmerr(dev->wl, "Microcode not responding\n");
 			err = -ENODEV;
 			goto out;
 		}
@@ -1706,15 +1746,15 @@ static int bcm43xx_upload_microcode(stru
 				    BCM43xx_SHM_SH_UCODETIME);
 
 	if (fwrev <= 0x128) {
-		printk(KERN_ERR PFX "YOUR FIRMWARE IS TOO OLD. Firmware from "
+		bcmerr(dev->wl, "YOUR FIRMWARE IS TOO OLD. Firmware from "
 		       "binary drivers older than version 4.x is unsupported. "
 		       "You must upgrade your firmware files.\n");
 		bcm43xx_write32(dev, BCM43xx_MMIO_STATUS_BITFIELD, 0);
 		err = -EOPNOTSUPP;
 		goto out;
 	}
-	printk(KERN_DEBUG PFX "Loading firmware version %u.%u "
-			      "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
+	bcmdbg(dev->wl, "Loading firmware version %u.%u "
+	       "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
 	       fwrev, fwpatch,
 	       (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
 	       (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F);
@@ -1754,8 +1794,8 @@ static int bcm43xx_write_initvals(struct
 	return 0;
 
 err_format:
-	printk(KERN_ERR PFX "InitVals (bcm43xx_initvalXX.fw) file-format error. "
-			    "Please fix your bcm43xx firmware files.\n");
+	bcmerr(dev->wl, "InitVals (bcm43xx_initvalXX.fw) file-format error. "
+	       "Please fix your bcm43xx firmware files.\n");
 	return -EPROTO;
 }
 
@@ -1882,7 +1922,7 @@ void bcm43xx_mac_suspend(struct bcm43xx_
 				goto out;
 			udelay(1);
 		}
-		printkl(KERN_ERR PFX "MAC suspend failed\n");
+		bcmerr(dev->wl, "MAC suspend failed\n");
 	}
 out:
 	dev->mac_suspended++;
@@ -1928,6 +1968,11 @@ static void bcm43xx_adjust_opmode(struct
 	}
 	if (wl->promisc)
 		ctl |= BCM43xx_MACCTL_PROMISC;
+	/* Workaround: On old hardware the HW-MAC-address-filter
+	 * doesn't work properly, so always run promisc in filter
+	 * it in software. */
+	if (dev->dev->id.revision <= 4)
+		ctl |= BCM43xx_MACCTL_PROMISC;
 
 	bcm43xx_write32(dev, BCM43xx_MMIO_MACCTL, ctl);
 
@@ -2068,8 +2113,8 @@ static int bcm43xx_chip_init(struct bcm4
 		goto err_gpio_cleanup;
 	bcm43xx_radio_turn_on(dev);
 	dev->radio_hw_enable = bcm43xx_is_hw_radio_enabled(dev);
-	dprintk(KERN_INFO PFX "Radio %s by hardware\n",
-		(dev->radio_hw_enable == 0) ? "disabled" : "enabled");
+	bcmdbg(dev->wl, "Radio %s by hardware\n",
+	       (dev->radio_hw_enable == 0) ? "disabled" : "enabled");
 
 	bcm43xx_write16(dev, 0x03E6, 0x0000);
 	err = bcm43xx_phy_init(dev);
@@ -2144,7 +2189,7 @@ static int bcm43xx_chip_init(struct bcm4
 			dev->dev->bus->chipco.fast_pwrup_delay);
 
 	assert(err == 0);
-	dprintk(KERN_INFO PFX "Chip initialized\n");
+	bcmdbg(dev->wl, "Chip initialized\n");
 out:
 	return err;
 
@@ -2222,8 +2267,8 @@ static void bcm43xx_periodic_every1sec(s
 	radio_hw_enable = bcm43xx_is_hw_radio_enabled(dev);
 	if (unlikely(dev->radio_hw_enable != radio_hw_enable)) {
 		dev->radio_hw_enable = radio_hw_enable;
-		dprintk(KERN_INFO PFX "Radio hardware status changed to %s\n",
-			(radio_hw_enable == 0) ? "disabled" : "enabled");
+		bcmdbg(dev->wl, "Radio hardware status changed to %s\n",
+		       (radio_hw_enable == 0) ? "disabled" : "enabled");
 		bcm43xx_leds_update(dev, 0);
 	}
 }
@@ -2275,9 +2320,7 @@ static void bcm43xx_periodic_work_handle
 
 	mutex_lock(&dev->wl->mutex);
 
-	if (unlikely(bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED))
-		goto out;
-	if (unlikely(!dev->started))
+	if (unlikely(bcm43xx_status(dev) != BCM43xx_STAT_STARTED))
 		goto out;
 	if (bcm43xx_debug(dev, BCM43xx_DBG_PWORK_STOP))
 		goto out_requeue;
@@ -2312,9 +2355,10 @@ static void bcm43xx_periodic_work_handle
 	}
 	dev->periodic_state++;
 out_requeue:
-	delay = HZ;
 	if (bcm43xx_debug(dev, BCM43xx_DBG_PWORK_FAST))
 		delay = msecs_to_jiffies(50);
+	else
+		delay = round_jiffies(HZ);
 	queue_delayed_work(dev->wl->hw->workqueue,
 			   &dev->periodic_work, delay);
 out:
@@ -2330,7 +2374,6 @@ static void bcm43xx_periodic_tasks_setup
 {
 	struct delayed_work *work = &dev->periodic_work;
 
-	assert(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED);
 	dev->periodic_state = 0;
 	INIT_DELAYED_WORK(work, bcm43xx_periodic_work_handler);
 	queue_delayed_work(dev->wl->hw->workqueue, work, 0);
@@ -2362,7 +2405,7 @@ static int bcm43xx_validate_chipaccess(s
 
 	return 0;
 error:
-	printk(KERN_ERR PFX "Failed to validate the chipaccess\n");
+	bcmerr(dev->wl, "Failed to validate the chipaccess\n");
 	return -ENODEV;
 }
 
@@ -2419,7 +2462,7 @@ static int bcm43xx_rng_init(struct bcm43
 	err = hwrng_register(&wl->rng);
 	if (err) {
 		wl->rng_initialized = 0;
-		printk(KERN_ERR PFX "Failed to register the random "
+		bcmerr(wl, "Failed to register the random "
 		       "number generator (%d)\n", err);
 	}
 
@@ -2435,11 +2478,11 @@ static int bcm43xx_tx(struct ieee80211_h
 	int err = -ENODEV;
 	unsigned long flags;
 
-	/* DMA-TX is done without a global lock. */
 	if (unlikely(!dev))
 		goto out;
-	assert(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED);
-	assert(dev->started);
+	if (unlikely(bcm43xx_status(dev) < BCM43xx_STAT_STARTED))
+		goto out;
+	/* DMA-TX is done without a global lock. */
 	if (bcm43xx_using_pio(dev)) {
 		spin_lock_irqsave(&wl->irq_lock, flags);
 		err = bcm43xx_pio_tx(dev, skb, ctl);
@@ -2470,7 +2513,7 @@ static int bcm43xx_get_tx_stats(struct i
 	if (!dev)
 		goto out;
 	spin_lock_irqsave(&wl->irq_lock, flags);
-	if (likely(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED)) {
+	if (likely(bcm43xx_status(dev) >= BCM43xx_STAT_STARTED)) {
 		if (bcm43xx_using_pio(dev))
 			bcm43xx_pio_get_tx_stats(dev, stats);
 		else
@@ -2528,7 +2571,7 @@ static const char * phymode_to_string(un
 static int find_wldev_for_phymode(struct bcm43xx_wl *wl,
 				  unsigned int phymode,
 				  struct bcm43xx_wldev **dev,
-				  int *gmode)
+				  bool *gmode)
 {
 	struct bcm43xx_wldev *d;
 
@@ -2569,41 +2612,37 @@ static void bcm43xx_put_phy_into_reset(s
 	msleep(1);
 }
 
+/* Expects wl->mutex locked */
 static int bcm43xx_switch_phymode(struct bcm43xx_wl *wl,
 				  unsigned int new_mode)
 {
 	struct bcm43xx_wldev *up_dev;
 	struct bcm43xx_wldev *down_dev;
 	int err;
-	int gmode = -1;
-	int old_was_started = 0;
-	int old_was_inited = 0;
+	bool gmode = 0;
+	int prev_status;
 
 	err = find_wldev_for_phymode(wl, new_mode, &up_dev, &gmode);
 	if (err) {
-		printk(KERN_INFO PFX "Could not find a device for %s-PHY mode\n",
+		bcmerr(wl, "Could not find a device for %s-PHY mode\n",
 		       phymode_to_string(new_mode));
 		return err;
 	}
-	assert(gmode == 0 || gmode == 1);
 	if ((up_dev == wl->current_dev) &&
-	    (wl->current_dev->phy.gmode == gmode)) {
+	    (!!wl->current_dev->phy.gmode == !!gmode)) {
 		/* This device is already running. */
 		return 0;
 	}
-	dprintk(KERN_INFO PFX "Reconfiguring PHYmode to %s-PHY\n",
-		phymode_to_string(new_mode));
+	bcmdbg(wl, "Reconfiguring PHYmode to %s-PHY\n",
+	       phymode_to_string(new_mode));
 	down_dev = wl->current_dev;
 
+	prev_status = bcm43xx_status(down_dev);
 	/* Shutdown the currently running core. */
-	if (down_dev->started) {
-		old_was_started = 1;
+	if (prev_status >= BCM43xx_STAT_STARTED)
 		bcm43xx_wireless_core_stop(down_dev);
-	}
-	if (bcm43xx_status(down_dev) == BCM43xx_STAT_INITIALIZED) {
-		old_was_inited = 1;
+	if (prev_status >= BCM43xx_STAT_INITIALIZED)
 		bcm43xx_wireless_core_exit(down_dev);
-	}
 
 	if (down_dev != up_dev) {
 		/* We switch to a different core, so we put PHY into
@@ -2613,30 +2652,34 @@ static int bcm43xx_switch_phymode(struct
 
 	/* Now start the new core. */
 	up_dev->phy.gmode = gmode;
-	if (old_was_inited) {
+	if (prev_status >= BCM43xx_STAT_INITIALIZED) {
 		err = bcm43xx_wireless_core_init(up_dev);
 		if (err) {
-			printk(KERN_INFO PFX "Fatal: Could not initialize device for "
-			       "new selected %s-PHY mode\n",
+			bcmerr(wl, "Fatal: Could not initialize device for "
+			       "newly selected %s-PHY mode\n",
 			       phymode_to_string(new_mode));
-			return err;
+			goto init_failure;
 		}
 	}
-	if (old_was_started) {
-		assert(old_was_inited);
+	if (prev_status >= BCM43xx_STAT_STARTED) {
 		err = bcm43xx_wireless_core_start(up_dev);
 		if (err) {
-			printk(KERN_INFO PFX "Fatal: Coult not start device for "
-			       "new selected %s-PHY mode\n",
+			bcmerr(wl, "Fatal: Coult not start device for "
+			       "newly selected %s-PHY mode\n",
 			       phymode_to_string(new_mode));
 			bcm43xx_wireless_core_exit(up_dev);
-			return err;
+			goto init_failure;
 		}
 	}
+	assert(bcm43xx_status(up_dev) == prev_status);
 
 	wl->current_dev = up_dev;
 
 	return 0;
+init_failure:
+	/* Whoops, failed to init the new core. No core is operating now. */
+	wl->current_dev = NULL;
+	return err;
 }
 
 static int bcm43xx_antenna_from_ieee80211(u8 antenna)
@@ -2695,8 +2738,7 @@ static int bcm43xx_dev_config(struct iee
 	 * This makes it possible to drop the spinlock throughout
 	 * the reconfiguration process. */
 	spin_lock_irqsave(&wl->irq_lock, flags);
-	if ((bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED) ||
-	    !dev->started) {
+	if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED) {
 		spin_unlock_irqrestore(&wl->irq_lock, flags);
 		goto out_unlock_mutex;
 	}
@@ -2869,11 +2911,11 @@ out_unlock:
 	mutex_unlock(&wl->mutex);
 out:
 	if (!err) {
-		dprintk(KERN_DEBUG PFX "Using %s based encryption for keyidx: %d, "
-			"mac: " MAC_FMT "\n",
-			(key->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) ?
-			"software" : "hardware",
-			key->keyidx, MAC_ARG(addr));
+		bcmdbg(wl, "Using %s based encryption for keyidx: %d, "
+		       "mac: " MAC_FMT "\n",
+		       (key->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) ?
+		       "software" : "hardware",
+		       key->keyidx, MAC_ARG(addr));
 	}
 	return err;
 }
@@ -2932,9 +2974,9 @@ static void bcm43xx_wireless_core_stop(s
 	struct bcm43xx_wl *wl = dev->wl;
 	unsigned long flags;
 
-	if (!dev->started)
+	if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED)
 		return;
-	dev->started = 0;
+	bcm43xx_set_status(dev, BCM43xx_STAT_INITIALIZED);
 
 	mutex_unlock(&wl->mutex);
 	/* Must unlock as it would otherwise deadlock. No races here. */
@@ -2953,32 +2995,32 @@ static void bcm43xx_wireless_core_stop(s
 
 	bcm43xx_mac_suspend(dev);
 	free_irq(dev->dev->irq, dev);
-	dprintk(KERN_INFO PFX "Wireless interface stopped\n");
+	bcmdbg(wl, "Wireless interface stopped\n");
 }
 
 /* Locking: wl->mutex */
 static int bcm43xx_wireless_core_start(struct bcm43xx_wldev *dev)
 {
-	struct bcm43xx_wl *wl = dev->wl;
 	int err;
 
-	assert(!dev->started);
+	assert(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED);
 
 	drain_txstatus_queue(dev);
 	err = request_irq(dev->dev->irq, bcm43xx_interrupt_handler,
 			  IRQF_SHARED, KBUILD_MODNAME, dev);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot request IRQ-%d\n",
+		bcmerr(dev->wl, "Cannot request IRQ-%d\n",
 		       dev->dev->irq);
 		goto out;
 	}
-	dev->started = 1;
 	bcm43xx_interrupt_enable(dev, dev->irq_savedstate);
 	bcm43xx_mac_enable(dev);
 
-	ieee80211_start_queues(wl->hw);
 	bcm43xx_periodic_tasks_setup(dev);
-	dprintk(KERN_INFO PFX "Wireless interface started\n");
+
+	ieee80211_start_queues(dev->wl->hw);
+	bcm43xx_set_status(dev, BCM43xx_STAT_STARTED);
+	bcmdbg(dev->wl, "Wireless interface started\n");
 out:
 	return err;
 }
@@ -3018,13 +3060,13 @@ static int bcm43xx_phy_versioning(struct
 		unsupported = 1;
 	};
 	if (unsupported) {
-		printk(KERN_ERR PFX "FOUND UNSUPPORTED PHY "
+		bcmerr(dev->wl, "FOUND UNSUPPORTED PHY "
 		       "(Analog %u, Type %u, Revision %u)\n",
 		       analog_type, phy_type, phy_rev);
 		return -EOPNOTSUPP;
 	}
-	dprintk(KERN_INFO PFX "Found PHY: Analog %u, Type %u, Revision %u\n",
-		analog_type, phy_type, phy_rev);
+	bcmdbg(dev->wl, "Found PHY: Analog %u, Type %u, Revision %u\n",
+	       analog_type, phy_type, phy_rev);
 
 
 	/* Get RADIO versioning */
@@ -3068,13 +3110,13 @@ static int bcm43xx_phy_versioning(struct
 		assert(0);
 	}
 	if (unsupported) {
-		printk(KERN_ERR PFX "FOUND UNSUPPORTED RADIO "
+		bcmerr(dev->wl, "FOUND UNSUPPORTED RADIO "
 		       "(Manuf 0x%X, Version 0x%X, Revision %u)\n",
 		       radio_manuf, radio_ver, radio_rev);
 		return -EOPNOTSUPP;
 	}
-	dprintk(KERN_INFO PFX "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n",
-		radio_manuf, radio_ver, radio_rev);
+	bcmdbg(dev->wl, "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n",
+	       radio_manuf, radio_ver, radio_rev);
 
 
 	phy->radio_manuf = radio_manuf;
@@ -3205,6 +3247,7 @@ static void bcm43xx_wireless_core_exit(s
 {
 	struct bcm43xx_phy *phy = &dev->phy;
 
+	assert(bcm43xx_status(dev) <= BCM43xx_STAT_INITIALIZED);
 	if (bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED)
 		return;
 
@@ -3234,7 +3277,6 @@ static int bcm43xx_wireless_core_init(st
 	u32 hf, tmp;
 
 	assert(bcm43xx_status(dev) == BCM43xx_STAT_UNINIT);
-	bcm43xx_set_status(dev, BCM43xx_STAT_INITIALIZING);
 
 	err = ssb_bus_powerup(bus, 0);
 	if (err)
@@ -3355,7 +3397,7 @@ err_kfree_lo_control:
 	phy->lo_control = NULL;
 err_busdown:
 	ssb_bus_may_powerdown(bus);
-	bcm43xx_set_status(dev, BCM43xx_STAT_UNINIT);
+	assert(bcm43xx_status(dev) == BCM43xx_STAT_UNINIT);
 	return err;
 }
 
@@ -3373,16 +3415,16 @@ static int bcm43xx_add_interface(struct 
 	    wl->operating)
 		goto out_mutex_unlock;
 
-	dprintk(KERN_INFO PFX "Adding Interface type %d\n", conf->type);
+	bcmdbg(wl, "Adding Interface type %d\n", conf->type);
 
 	dev = wl->current_dev;
-	if (bcm43xx_status(dev) == BCM43xx_STAT_UNINIT) {
+	if (bcm43xx_status(dev) < BCM43xx_STAT_INITIALIZED) {
 		err = bcm43xx_wireless_core_init(dev);
 		if (err)
 			goto out_mutex_unlock;
 		did_init = 1;
 	}
-	if (!dev->started) {
+	if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED) {
 		err = bcm43xx_wireless_core_start(dev);
 		if (err) {
 			if (did_init)
@@ -3419,7 +3461,7 @@ static void bcm43xx_remove_interface(str
 	struct bcm43xx_wldev *dev;
 	unsigned long flags;
 
-	dprintk(KERN_INFO PFX "Removing Interface type %d\n", conf->type);
+	bcmdbg(wl, "Removing Interface type %d\n", conf->type);
 
 	mutex_lock(&wl->mutex);
 	if (conf->type == IEEE80211_IF_TYPE_MNTR) {
@@ -3433,7 +3475,7 @@ static void bcm43xx_remove_interface(str
 	dev = wl->current_dev;
 	if (!wl->operating && wl->monitor == 0) {
 		/* No interface left. */
-		if (dev->started)
+		if (bcm43xx_status(dev) >= BCM43xx_STAT_STARTED)
 			bcm43xx_wireless_core_stop(dev);
 		bcm43xx_wireless_core_exit(dev);
 	} else {
@@ -3470,30 +3512,25 @@ static void bcm43xx_chip_reset(struct wo
 	struct bcm43xx_wldev *dev =
 		container_of(work, struct bcm43xx_wldev, restart_work);
 	struct bcm43xx_wl *wl = dev->wl;
-	int err;
-	int was_started = 0;
-	int was_inited = 0;
+	int err = 0;
+	int prev_status;
 
 	mutex_lock(&wl->mutex);
 
+	prev_status = bcm43xx_status(dev);
 	/* Bring the device down... */
-	if (dev->started) {
-		was_started = 1;
+	if (prev_status >= BCM43xx_STAT_STARTED)
 		bcm43xx_wireless_core_stop(dev);
-	}
-	if (bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED) {
-		was_inited = 1;
+	if (prev_status >= BCM43xx_STAT_INITIALIZED)
 		bcm43xx_wireless_core_exit(dev);
-	}
 
 	/* ...and up again. */
-	if (was_inited) {
+	if (prev_status >= BCM43xx_STAT_INITIALIZED) {
 		err = bcm43xx_wireless_core_init(dev);
 		if (err)
 			goto out;
 	}
-	if (was_started) {
-		assert(was_inited);
+	if (prev_status >= BCM43xx_STAT_STARTED) {
 		err = bcm43xx_wireless_core_start(dev);
 		if (err) {
 			bcm43xx_wireless_core_exit(dev);
@@ -3503,9 +3540,9 @@ static void bcm43xx_chip_reset(struct wo
 out:
 	mutex_unlock(&wl->mutex);
 	if (err)
-		printk(KERN_ERR PFX "Controller restart FAILED\n");
+		bcmerr(wl, "Controller restart FAILED\n");
 	else
-		printk(KERN_INFO PFX "Controller restarted\n");
+		bcminfo(wl, "Controller restarted\n");
 }
 
 static int bcm43xx_setup_modes(struct bcm43xx_wldev *dev,
@@ -3718,7 +3755,7 @@ static int bcm43xx_one_core_attach(struc
 		    ((pdev->device != 0x4321) &&
 		     (pdev->device != 0x4313) &&
 		     (pdev->device != 0x431A))) {
-			dprintk(KERN_INFO PFX "Ignoring unconnected 802.11 core\n");
+			bcmdbg(wl, "Ignoring unconnected 802.11 core\n");
 			return -ENODEV;
 		}
 	}
@@ -3792,7 +3829,7 @@ static int bcm43xx_wireless_init(struct 
 
 	hw = ieee80211_alloc_hw(sizeof(*wl), &bcm43xx_hw_ops);
 	if (!hw) {
-		printk(KERN_ERR PFX "Could not allocate ieee80211 device\n");
+		bcmerr(NULL, "Could not allocate ieee80211 device\n");
 		goto out;
 	}
 
@@ -3821,7 +3858,7 @@ static int bcm43xx_wireless_init(struct 
 	INIT_LIST_HEAD(&wl->devlist);
 
 	ssb_set_devtypedata(dev, wl);
-	printk(KERN_INFO PFX "Broadcom %04X WLAN found\n", dev->bus->chip_id);
+	bcminfo(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
 	err = 0;
 out:
 	return err;
@@ -3892,7 +3929,7 @@ void bcm43xx_controller_restart(struct b
 {
 	if (bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED)
 		return;
-	printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
+	bcminfo(dev->wl, "Controller RESET (%s) ...\n", reason);
 	queue_work(dev->wl->hw->workqueue, &dev->restart_work);
 }
 
@@ -3903,19 +3940,17 @@ static int bcm43xx_suspend(struct ssb_de
 	struct bcm43xx_wldev *wldev = ssb_get_drvdata(dev);
 	struct bcm43xx_wl *wl = wldev->wl;
 
-	dprintk(KERN_INFO PFX "Suspending...\n");
+	bcmdbg(wl, "Suspending...\n");
 
 	mutex_lock(&wl->mutex);
-	wldev->was_started = !!wldev->started;
-	wldev->was_initialized = (bcm43xx_status(wldev) == BCM43xx_STAT_INITIALIZED);
-	if (wldev->started)
+	wldev->suspend_init_status = bcm43xx_status(wldev);
+	if (wldev->suspend_init_status >= BCM43xx_STAT_STARTED)
 		bcm43xx_wireless_core_stop(wldev);
-	if (bcm43xx_status(wldev) == BCM43xx_STAT_INITIALIZED)
+	if (wldev->suspend_init_status >= BCM43xx_STAT_INITIALIZED)
 		bcm43xx_wireless_core_exit(wldev);
-
 	mutex_unlock(&wl->mutex);
 
-	dprintk(KERN_INFO PFX "Device suspended.\n");
+	bcmdbg(wl, "Device suspended.\n");
 
 	return 0;
 }
@@ -3923,27 +3958,30 @@ static int bcm43xx_suspend(struct ssb_de
 static int bcm43xx_resume(struct ssb_device *dev)
 {
 	struct bcm43xx_wldev *wldev = ssb_get_drvdata(dev);
+	struct bcm43xx_wl *wl = wldev->wl;
 	int err = 0;
 
-	dprintk(KERN_INFO PFX "Resuming...\n");
+	bcmdbg(wl, "Resuming...\n");
 
-	if (wldev->was_initialized) {
+	mutex_lock(&wl->mutex);
+	if (wldev->suspend_init_status >= BCM43xx_STAT_INITIALIZED) {
 		err = bcm43xx_wireless_core_init(wldev);
 		if (err) {
-			printk(KERN_ERR PFX "Resume failed at core init\n");
+			bcmerr(wl, "Resume failed at core init\n");
 			goto out;
 		}
 	}
-	if (wldev->was_started) {
-		assert(wldev->was_initialized);
+	if (wldev->suspend_init_status >= BCM43xx_STAT_STARTED) {
 		err = bcm43xx_wireless_core_start(wldev);
 		if (err) {
-			printk(KERN_ERR PFX "Resume failed at core start\n");
+			bcm43xx_wireless_core_exit(wldev);
+			bcmerr(wl, "Resume failed at core start\n");
 			goto out;
 		}
 	}
+	mutex_unlock(&wl->mutex);
 
-	dprintk(KERN_INFO PFX "Device resumed.\n");
+	bcmdbg(wl, "Device resumed.\n");
 out:
 	return err;
 }
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.c
index 53a34f6..24855d6 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.c
@@ -248,7 +248,8 @@ void bcm43xx_raw_phy_unlock(struct bcm43
  * This adjusts (and does sanity checks on) the routing flags.
  */
 static inline u16 adjust_phyreg_for_phytype(struct bcm43xx_phy *phy,
-					    u16 offset)
+					    u16 offset,
+					    struct bcm43xx_wldev *dev)
 {
 	if (phy->type == BCM43xx_PHYTYPE_A) {
 		/* OFDM registers are base-registers for the A-PHY. */
@@ -257,9 +258,9 @@ static inline u16 adjust_phyreg_for_phyt
 	if (offset & BCM43xx_PHYROUTE_EXT_GPHY) {
 		/* Ext-G registers are only available on G-PHYs */
 		if (phy->type != BCM43xx_PHYTYPE_G) {
-			dprintk(KERN_ERR PFX "EXT-G PHY access at "
-				"0x%04X on %u type PHY\n",
-				offset, phy->type);
+			bcmdbg(dev->wl, "EXT-G PHY access at "
+			       "0x%04X on %u type PHY\n",
+			       offset, phy->type);
 		}
 	}
 
@@ -270,7 +271,7 @@ u16 bcm43xx_phy_read(struct bcm43xx_wlde
 {
 	struct bcm43xx_phy *phy = &dev->phy;
 
-	offset = adjust_phyreg_for_phytype(phy, offset);
+	offset = adjust_phyreg_for_phytype(phy, offset, dev);
 	bcm43xx_write16(dev, BCM43xx_MMIO_PHY_CONTROL, offset);
 	return bcm43xx_read16(dev, BCM43xx_MMIO_PHY_DATA);
 }
@@ -279,7 +280,7 @@ void bcm43xx_phy_write(struct bcm43xx_wl
 {
 	struct bcm43xx_phy *phy = &dev->phy;
 
-	offset = adjust_phyreg_for_phytype(phy, offset);
+	offset = adjust_phyreg_for_phytype(phy, offset, dev);
 	bcm43xx_write16(dev, BCM43xx_MMIO_PHY_CONTROL, offset);
 	mmiowb();
 	bcm43xx_write16(dev, BCM43xx_MMIO_PHY_DATA, val);
@@ -311,10 +312,10 @@ void bcm43xx_set_txpower_g(struct bcm43x
 	memcpy(&phy->bbatt, bbatt, sizeof(*bbatt));
 
 	if (bcm43xx_debug(dev, BCM43xx_DBG_XMITPOWER)) {
-		dprintk(KERN_DEBUG PFX "Tuning TX-power to bbatt(%u), "
-			"rfatt(%u), tx_control(0x%02X), "
-			"tx_bias(0x%02X), tx_magn(0x%02X)\n",
-			bb, rf, tx_control, tx_bias, tx_magn);
+		bcmdbg(dev->wl, "Tuning TX-power to bbatt(%u), "
+		       "rfatt(%u), tx_control(0x%02X), "
+		       "tx_bias(0x%02X), tx_magn(0x%02X)\n",
+		       bb, rf, tx_control, tx_bias, tx_magn);
 	}
 
 	bcm43xx_phy_set_baseband_attenuation(dev, bb);
@@ -739,9 +740,9 @@ static void bcm43xx_phy_init_pctl(struct
 		if (BCM43xx_DEBUG) {
 			/* Current-Idle-TSSI sanity check. */
 			if (abs(phy->cur_idle_tssi - phy->tgt_idle_tssi) >= 20) {
-				dprintk(KERN_ERR PFX "!WARNING! Idle-TSSI phy->cur_idle_tssi "
-					"measuring failed. (cur=%d, tgt=%d). Disabling TX power "
-					"adjustment.\n", phy->cur_idle_tssi, phy->tgt_idle_tssi);
+				bcmdbg(dev->wl, "!WARNING! Idle-TSSI phy->cur_idle_tssi "
+				       "measuring failed. (cur=%d, tgt=%d). Disabling TX power "
+				       "adjustment.\n", phy->cur_idle_tssi, phy->tgt_idle_tssi);
 				phy->cur_idle_tssi = 0;
 			}
 		}
@@ -957,12 +958,8 @@ static void bcm43xx_phy_setupg(struct bc
 	if (phy->rev == 1) {
 		for (i = 0; i < BCM43xx_TAB_RETARD_SIZE; i++)
 			bcm43xx_ofdmtab_write32(dev, 0x2400, i, bcm43xx_tab_retard[i]);
-		for (i = 0; i < 4; i++) {
-			bcm43xx_ofdmtab_write16(dev, 0x5404, i, 0x0020);
-			bcm43xx_ofdmtab_write16(dev, 0x5408, i, 0x0020);
-			bcm43xx_ofdmtab_write16(dev, 0x540C, i, 0x0020);
-			bcm43xx_ofdmtab_write16(dev, 0x5410, i, 0x0020);
-		}
+		for (i = 4; i < 20; i++)
+			bcm43xx_ofdmtab_write16(dev, 0x5400, i, 0x0020);
 		bcm43xx_phy_agcsetup(dev);
 
 		if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
@@ -973,7 +970,7 @@ static void bcm43xx_phy_setupg(struct bc
 		bcm43xx_ofdmtab_write16(dev, 0x5001, 0, 0x0002);
 		bcm43xx_ofdmtab_write16(dev, 0x5002, 0, 0x0001);
 	} else {
-		for (i = 0; i <= 0x2F; i++)
+		for (i = 0; i < 0x20; i++)
 			bcm43xx_ofdmtab_write16(dev, 0x1000, i, 0x0820);
 		bcm43xx_phy_agcsetup(dev);
 		bcm43xx_phy_read(dev, 0x0400); /* dummy read */
@@ -2065,7 +2062,7 @@ #endif
 		    (phy->type == BCM43xx_PHYTYPE_G))
 			max_pwr -= 0x3;
 		if (unlikely(max_pwr <= 0)) {
-			printk(KERN_ERR PFX "Invalid max-TX-power value in SPROM.\n");
+			bcmwarn(dev->wl, "Invalid max-TX-power value in SPROM.\n");
 			max_pwr = 60; /* fake it */
 			dev->dev->bus->sprom.r1.maxpwr_bg = max_pwr;
 		}
@@ -2079,10 +2076,9 @@ #endif
 		/* Convert the desired_pwr to Q5.2 and limit it. */
 		desired_pwr = limit_value((desired_pwr << 2), 0, max_pwr);
 		if (bcm43xx_debug(dev, BCM43xx_DBG_XMITPOWER)) {
-			dprintk(KERN_DEBUG PFX
-				"Current TX power output: " Q52_FMT " dBm, "
-				"Desired TX power output: " Q52_FMT " dBm\n",
-				Q52_ARG(estimated_pwr), Q52_ARG(desired_pwr));
+			bcmdbg(dev->wl, "Current TX power output: " Q52_FMT " dBm, "
+			       "Desired TX power output: " Q52_FMT " dBm\n",
+			       Q52_ARG(estimated_pwr), Q52_ARG(desired_pwr));
 		}
 
 		pwr_adjust = desired_pwr - estimated_pwr;
@@ -2210,15 +2206,15 @@ int bcm43xx_phy_init_tssi2dbm_table(stru
 		}
 		dyn_tssi2dbm = kmalloc(64, GFP_KERNEL);
 		if (dyn_tssi2dbm == NULL) {
-			printk(KERN_ERR PFX "Could not allocate memory"
-					    "for tssi2dbm table\n");
+			bcmerr(dev->wl, "Could not allocate memory"
+			       "for tssi2dbm table\n");
 			return -ENOMEM;
 		}
 		for (idx = 0; idx < 64; idx++)
 			if (bcm43xx_tssi2dbm_entry(dyn_tssi2dbm, idx, pab0, pab1, pab2)) {
 				phy->tssi2dbm = NULL;
-				printk(KERN_ERR PFX "Could not generate "
-						    "tssi2dBm table\n");
+				bcmerr(dev->wl, "Could not generate "
+				       "tssi2dBm table\n");
 				kfree(dyn_tssi2dbm);
 				return -ENODEV;
 			}
@@ -2230,8 +2226,8 @@ int bcm43xx_phy_init_tssi2dbm_table(stru
 		case BCM43xx_PHYTYPE_A:
 			/* APHY needs a generated table. */
 			phy->tssi2dbm = NULL;
-			printk(KERN_ERR PFX "Could not generate tssi2dBm "
-					    "table (wrong SPROM info)!\n");
+			bcmerr(dev->wl, "Could not generate tssi2dBm "
+			       "table (wrong SPROM info)!\n");
 			return -ENODEV;
 		case BCM43xx_PHYTYPE_B:
 			phy->tgt_idle_tssi = 0x34;
@@ -2285,7 +2281,7 @@ int bcm43xx_phy_init(struct bcm43xx_wlde
 		break;
 	}
 	if (err)
-		printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n");
+		bcmerr(dev->wl, "Unknown PHYTYPE found\n");
 
 	return err;
 }
@@ -4342,7 +4338,7 @@ void bcm43xx_radio_turn_on(struct bcm43x
 		assert(0);
 	}
 	phy->radio_on = 1;
-	dprintk(KERN_INFO PFX "Radio turned on\n");
+	bcmdbg(dev->wl, "Radio turned on\n");
 }
 
 void bcm43xx_radio_turn_off(struct bcm43xx_wldev *dev)
@@ -4361,5 +4357,5 @@ void bcm43xx_radio_turn_off(struct bcm43
 	} else
 		bcm43xx_phy_write(dev, 0x0015, 0xAA00);
 	phy->radio_on = 0;
-	dprintk(KERN_INFO PFX "Radio turned off\n");
+	bcmdbg(dev->wl, "Radio turned off\n");
 }
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.h b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.h
index 75cea5a..8660103 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.h
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.h
@@ -232,8 +232,8 @@ #define has_loopback_gain(phy) \
 
 /* Radio Attenuation (RF Attenuation) */
 struct bcm43xx_rfatt {
-	u8 att;		/* Attenuation value */
-	u8 with_padmix;	/* Flag, PAD Mixer enabled. */
+	u8 att;			/* Attenuation value */
+	bool with_padmix;	/* Flag, PAD Mixer enabled. */
 };
 struct bcm43xx_rfatt_list {
 	/* Attenuation values list */
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.c
index 3ae5ef5..16779c2 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.c
@@ -231,8 +231,8 @@ static int pio_tx_packet(struct bcm43xx_
 
 	octets = (u16)skb->len + sizeof(struct bcm43xx_txhdr_fw4);
 	if (queue->tx_devq_size < octets) {
-		printkl(KERN_WARNING PFX "PIO queue too small. "
-					 "Dropping packet.\n");
+		bcmwarn(queue->dev->wl, "PIO queue too small. "
+			"Dropping packet.\n");
 		/* Drop it silently (return success) */
 		free_txpacket(packet, 1);
 		return 0;
@@ -340,13 +340,13 @@ struct bcm43xx_pioqueue * bcm43xx_setup_
 
 	qsize = bcm43xx_read16(dev, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE);
 	if (qsize == 0) {
-		printk(KERN_ERR PFX "ERROR: This card does not support PIO "
-				    "operation mode. Please use DMA mode "
-				    "(module parameter pio=0).\n");
+		bcmerr(dev->wl, "This card does not support PIO "
+		       "operation mode. Please use DMA mode "
+		       "(module parameter pio=0).\n");
 		goto err_freequeue;
 	}
 	if (qsize <= BCM43xx_PIO_TXQADJUST) {
-		printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n",
+		bcmerr(dev->wl, "PIO tx device-queue too small (%u)\n",
 		       qsize);
 		goto err_freequeue;
 	}
@@ -432,7 +432,7 @@ int bcm43xx_pio_init(struct bcm43xx_wlde
 	if (dev->dev->id.revision < 3)
 		dev->irq_savedstate |= BCM43xx_IRQ_PIO_WORKAROUND;
 
-	dprintk(KERN_INFO PFX "PIO initialized\n");
+	bcmdbg(dev->wl, "PIO initialized\n");
 	err = 0;
 out:
 	return err;
@@ -522,7 +522,7 @@ static void pio_rx_error(struct bcm43xx_
 {
 	int i;
 
-	printkl("PIO RX error: %s\n", error);
+	bcmerr(queue->dev->wl, "PIO RX error: %s\n", error);
 	bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL,
 			  BCM43xx_PIO_RXCTL_READY);
 	if (clear_buffers) {
@@ -554,7 +554,7 @@ void bcm43xx_pio_rx(struct bcm43xx_pioqu
 			goto data_ready;
 		udelay(10);
 	}
-	dprintkl(KERN_ERR PFX "PIO RX timed out\n");
+	bcmdbg(queue->dev->wl, "PIO RX timed out\n");
 	return;
 data_ready:
 
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.h b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.h
index b9d919b..9d112f0 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.h
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.h
@@ -51,9 +51,9 @@ struct bcm43xx_pioqueue {
 	struct bcm43xx_wldev *dev;
 	u16 mmio_base;
 
-	u8 tx_suspended:1,
-	   tx_frozen:1,
-	   need_workarounds:1; /* Workarounds needed for core.rev < 3 */
+	bool tx_suspended;
+	bool tx_frozen;
+	bool need_workarounds; /* Workarounds needed for core.rev < 3 */
 
 	/* Adjusted size of the device internal TX buffer. */
 	u16 tx_devq_size;
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_sysfs.c
index eed688f..611f688 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_sysfs.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_sysfs.c
@@ -137,8 +137,8 @@ static ssize_t bcm43xx_attr_interfmode_s
 
 	err = bcm43xx_radio_set_interference_mitigation(wldev, mode);
 	if (err) {
-		printk(KERN_ERR PFX "Interference Mitigation not "
-				    "supported by device\n");
+		bcmerr(wldev->wl, "Interference Mitigation not "
+		       "supported by device\n");
 	}
 	mmiowb();
 	spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_xmit.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_xmit.c
index 469c9e0..8ca35d2 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_xmit.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_xmit.c
@@ -467,12 +467,19 @@ void bcm43xx_rx(struct bcm43xx_wldev *de
 
 	/* Skip PLCP and padding */
 	padding = (macstat & BCM43xx_RX_MAC_PADDING) ? 2 : 0;
+	if (unlikely(skb->len < (sizeof(struct bcm43xx_plcp_hdr6) + padding))) {
+		bcmdbg(dev->wl, "RX: Packet size underrun (1)\n");
+		goto drop;
+	}
 	plcp = (struct bcm43xx_plcp_hdr6 *)(skb->data + padding);
 	skb_pull(skb, sizeof(struct bcm43xx_plcp_hdr6) + padding);
 	/* The skb contains the Wireless Header + payload data now */
+	if (unlikely(skb->len < (2+2+6/*minimum hdr*/ + FCS_LEN))) {
+		bcmdbg(dev->wl, "RX: Packet size underrun (2)\n");
+		goto drop;
+	}
 	wlhdr = (struct ieee80211_hdr *)(skb->data);
 	fctl = le16_to_cpu(wlhdr->frame_control);
-
 	skb_trim(skb, skb->len - FCS_LEN);
 
 	if ((macstat & BCM43xx_RX_MAC_DEC) &&
@@ -497,6 +504,10 @@ void bcm43xx_rx(struct bcm43xx_wldev *de
 			wlhdr->frame_control = cpu_to_le16(fctl);
 
 			wlhdr_len = ieee80211_get_hdrlen(fctl);
+			if (unlikely(skb->len < (wlhdr_len + 3))) {
+				bcmdbg(dev->wl, "RX: Packet size underrun (3)\n");
+				goto drop;
+			}
 			if (skb->data[wlhdr_len + 3] & (1 << 5)) {
 				/* The Ext-IV Bit is set in the "KeyID"
 				 * octet of the IV.
@@ -507,7 +518,10 @@ void bcm43xx_rx(struct bcm43xx_wldev *de
 				iv_len = 4;
 				icv_len = 4;
 			}
-
+			if (unlikely(skb->len < (wlhdr_len + iv_len + icv_len))) {
+				bcmdbg(dev->wl, "RX: Packet size underrun (4)\n");
+				goto drop;
+			}
 			/* Remove the IV */
 			memmove(skb->data + iv_len, skb->data, wlhdr_len);
 			skb_pull(skb, iv_len);
@@ -554,6 +568,11 @@ void bcm43xx_rx(struct bcm43xx_wldev *de
 
 	dev->stats.last_rx = jiffies;
 	ieee80211_rx_irqsafe(dev->wl->hw, skb, &status);
+
+	return;
+drop:
+	bcmdbg(dev->wl, "RX: Packet dropped\n");
+	dev_kfree_skb_any(skb);
 }
 
 void bcm43xx_handle_txstatus(struct bcm43xx_wldev *dev,
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index 03c4945..34a9411 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -58,7 +58,6 @@ config SSB_SERIAL
 config SSB_DRIVER_PCICORE
 	bool "SSB PCI core driver"
 	depends on SSB && SSB_PCIHOST
-	default y
 	help
 	  Driver for the Sonics Silicon Backplane attached
 	  Broadcom PCI core.
diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile
index 9a2b379..045aff0 100644
--- a/drivers/ssb/Makefile
+++ b/drivers/ssb/Makefile
@@ -1,11 +1,13 @@
-ssb-builtin-drivers-y					+= driver_chipcommon.o
-ssb-builtin-drivers-$(CONFIG_SSB_DRIVER_MIPS)		+= driver_mipscore.o
-ssb-builtin-drivers-$(CONFIG_SSB_DRIVER_PCICORE)	+= driver_pcicore.o
+# core
+ssb-y					+= main.o scan.o
 
-ssb-hostsupport-$(CONFIG_SSB_PCIHOST)			+= pci.o pcihost_wrapper.o
-ssb-hostsupport-$(CONFIG_SSB_PCMCIAHOST)		+= pcmcia.o
+# host support
+ssb-$(CONFIG_SSB_PCIHOST)		+= pci.o pcihost_wrapper.o
+ssb-$(CONFIG_SSB_PCMCIAHOST)		+= pcmcia.o
 
-obj-$(CONFIG_SSB) += ssb.o
+# built-in drivers
+ssb-y					+= driver_chipcommon.o
+ssb-$(CONFIG_SSB_DRIVER_MIPS)		+= driver_mipscore.o
+ssb-$(CONFIG_SSB_DRIVER_PCICORE)	+= driver_pcicore.o
 
-ssb-objs	:= main.o scan.o \
-		   $(ssb-hostsupport-y) $(ssb-builtin-drivers-y)
+obj-$(CONFIG_SSB)			+= ssb.o
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index a283de9..8e5491c 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -16,7 +16,7 @@ #include "ssb_private.h"
 
 
 /* Clock sources */
-enum {
+enum ssb_clksrc {
 	/* PCI clock */
 	SSB_CHIPCO_CLKSRC_PCI,
 	/* Crystal slow clock oscillator */
@@ -85,15 +85,15 @@ void ssb_chipco_set_clockmode(struct ssb
 			ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
 		break;
 	default:
-		assert(0);
+		SSB_WARN_ON(1);
 	}
 }
 
 /* Get the Slow Clock Source */
-static int chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc)
+static enum ssb_clksrc chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc)
 {
 	struct ssb_bus *bus = cc->dev->bus;
-	u32 tmp = 0;
+	u32 uninitialized_var(tmp);
 
 	if (cc->dev->id.revision < 6) {
 		if (bus->bustype == SSB_BUSTYPE_SSB ||
@@ -123,9 +123,9 @@ static int chipco_pctl_get_slowclksrc(st
 /* Get maximum or minimum (depending on get_max flag) slowclock frequency. */
 static int chipco_pctl_clockfreqlimit(struct ssb_chipcommon *cc, int get_max)
 {
-	int limit;
-	int clocksrc;
-	int divisor;
+	int uninitialized_var(limit);
+	enum ssb_clksrc clocksrc;
+	int divisor = 1;
 	u32 tmp;
 
 	clocksrc = chipco_pctl_get_slowclksrc(cc);
@@ -138,13 +138,11 @@ static int chipco_pctl_clockfreqlimit(st
 			divisor = 32;
 			break;
 		default:
-			assert(0);
-			divisor = 1;
+			SSB_WARN_ON(1);
 		}
 	} else if (cc->dev->id.revision < 10) {
 		switch (clocksrc) {
 		case SSB_CHIPCO_CLKSRC_LOPWROS:
-			divisor = 1;
 			break;
 		case SSB_CHIPCO_CLKSRC_XTALOS:
 		case SSB_CHIPCO_CLKSRC_PCI:
@@ -152,9 +150,6 @@ static int chipco_pctl_clockfreqlimit(st
 			divisor = (tmp >> 16) + 1;
 			divisor *= 4;
 			break;
-		default:
-			assert(0);
-			divisor = 1;
 		}
 	} else {
 		tmp = chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL);
@@ -181,9 +176,6 @@ static int chipco_pctl_clockfreqlimit(st
 		else
 			limit = 25000000;
 		break;
-	default:
-		assert(0);
-		limit = 0;
 	}
 	limit /= divisor;
 
@@ -235,7 +227,7 @@ static void calc_fast_powerup_delay(stru
 	minfreq = chipco_pctl_clockfreqlimit(cc, 0);
 	pll_on_delay = chipco_read32(cc, SSB_CHIPCO_PLLONDELAY);
 	tmp = (((pll_on_delay + 2) * 1000000) + (minfreq - 1)) / minfreq;
-	assert((tmp & ~0xFFFF) == 0);
+	SSB_WARN_ON(tmp & ~0xFFFF);
 
 	cc->fast_pwrup_delay = tmp;
 }
@@ -355,7 +347,7 @@ int ssb_chipco_serial_init(struct ssb_ch
 			div = 2; /* Minimum divisor */
 			chipco_write32(cc, SSB_CHIPCO_CLKDIV,
 				       (chipco_read32(cc, SSB_CHIPCO_CLKDIV)
-				        & ~SSB_CHIPCO_CLKDIV_UART) | div);
+					& ~SSB_CHIPCO_CLKDIV_UART) | div);
 		} else {
 			/* Fixed internal backplane clock */
 			baud_base = 88000000;
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c
index 67d1017..3f09598 100644
--- a/drivers/ssb/driver_mipscore.c
+++ b/drivers/ssb/driver_mipscore.c
@@ -13,7 +13,7 @@ #include <linux/ssb/ssb.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 #include <linux/serial_reg.h>
-#include <asm/time.h>
+#include <linux/time.h>
 
 #include "ssb_private.h"
 
@@ -224,7 +224,6 @@ #if 0
 		tmp = tmp | CEIL(120, ns);		/* W0 = 120nS */
 		W_REG(&eir->prog_waitcount, tmp);
 	}
-	else... chipcommon
 #endif
 	if (bus->chipco.dev)
 		ssb_chipco_timing_init(&bus->chipco, ns);
@@ -233,23 +232,24 @@ #endif
 	for (irq = 2, i = 0; i < bus->nr_devices; i++) {
 		dev = &(bus->devices[i]);
 		dev->irq = ssb_mips_irq(dev) + 2;
-		switch(dev->id.coreid) {
-			case SSB_DEV_USB11_HOST:
-				/* shouldn't need a separate irq line for non-4710, most of them have a proper
-				 * external usb controller on the pci */
-				if ((bus->chip_id == 0x4710) && (irq <= 4)) {
-					set_irq(dev, irq++);
-					break;
-				}
-			case SSB_DEV_PCI:
-			case SSB_DEV_ETHERNET:
-			case SSB_DEV_80211:
-			case SSB_DEV_USB20_HOST:
-				/* These devices get their own IRQ line if available, the rest goes on IRQ0 */
-				if (irq <= 4) {
-					set_irq(dev, irq++);
-					break;
-				}
+		switch (dev->id.coreid) {
+		case SSB_DEV_USB11_HOST:
+			/* shouldn't need a separate irq line for non-4710, most of them have a proper
+			 * external usb controller on the pci */
+			if ((bus->chip_id == 0x4710) && (irq <= 4)) {
+				set_irq(dev, irq++);
+				break;
+			}
+			/* fallthrough */
+		case SSB_DEV_PCI:
+		case SSB_DEV_ETHERNET:
+		case SSB_DEV_80211:
+		case SSB_DEV_USB20_HOST:
+			/* These devices get their own IRQ line if available, the rest goes on IRQ0 */
+			if (irq <= 4) {
+				set_irq(dev, irq++);
+				break;
+			}
 		}
 	}
 
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c
index 841847b..76a9a51 100644
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -34,8 +34,10 @@ void pcicore_write32(struct ssb_pcicore 
 #ifdef CONFIG_SSB_PCICORE_HOSTMODE
 
 #include <asm/paccess.h>
-/* Read the bus and catch bus exceptions. This is MIPS specific. */
-#define mips_busprobe(val, addr)	get_dbe((val), (addr))
+/* Probe a 32bit value on the bus and catch bus exceptions.
+ * Returns nonzero on a bus exception.
+ * This is MIPS specific */
+#define mips_busprobe32(val, addr)	get_dbe((val), ((u32 *)(addr)))
 
 /* Assume one-hot slot wiring */
 #define SSB_PCI_SLOT_MAX	16
@@ -54,7 +56,8 @@ int pcibios_plat_dev_init(struct pci_dev
 	int pos, size;
 	u32 *base;
 
-	printk("PCI: Fixing up device %s\n", pci_name(d));
+	ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
+		   pci_name(d));
 
 	/* Fix up resource bases */
 	for (pos = 0; pos < 6; pos++) {
@@ -85,7 +88,7 @@ static void __init ssb_fixup_pcibridge(s
 	if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0)
 		return;
 
-	printk("PCI: fixing up bridge\n");
+	ssb_printk(KERN_INFO "PCI: fixing up bridge\n");
 
 	/* Enable PCI bridge bus mastering and memory space */
 	pci_set_master(dev);
@@ -147,7 +150,7 @@ static int ssb_extpci_read_config(struct
 	u32 addr, val;
 	void __iomem *mmio;
 
-	assert(pc->hostmode);
+	SSB_WARN_ON(!pc->hostmode);
 	if (unlikely(len != 1 && len != 2 && len != 4))
 		goto out;
 	addr = get_cfgspace_addr(pc, bus, dev, func, off);
@@ -158,7 +161,7 @@ static int ssb_extpci_read_config(struct
 	if (!mmio)
 		goto out;
 
-	if (mips_busprobe(val, (u32 *) mmio)) {
+	if (mips_busprobe32(val, mmio)) {
 		val = 0xffffffff;
 		goto unmap;
 	}
@@ -193,7 +196,7 @@ static int ssb_extpci_write_config(struc
 	u32 addr, val = 0;
 	void __iomem *mmio;
 
-	assert(pc->hostmode);
+	SSB_WARN_ON(!pc->hostmode);
 	if (unlikely(len != 1 && len != 2 && len != 4))
 		goto out;
 	addr = get_cfgspace_addr(pc, bus, dev, func, off);
@@ -204,7 +207,7 @@ static int ssb_extpci_write_config(struc
 	if (!mmio)
 		goto out;
 
-	if (mips_busprobe(val, (u32 *) mmio)) {
+	if (mips_busprobe32(val, mmio)) {
 		val = 0xffffffff;
 		goto unmap;
 	}
@@ -291,10 +294,8 @@ static void ssb_pcicore_init_hostmode(st
 {
 	u32 val;
 
-	if (extpci_core) {
-		WARN_ON(1);
+	if (WARN_ON(extpci_core))
 		return;
-	}
 	extpci_core = pc;
 
 	ssb_dprintk(KERN_INFO PFX "PCIcore in host mode found\n");
@@ -364,7 +365,7 @@ static int pcicore_is_in_hostmode(struct
 	if (bus->chip_id == 0x5350)
 		return 0;
 
-	return !mips_busprobe(tmp, (u32 *) (bus->mmio + (pc->dev->core_index * SSB_CORE_SIZE)));
+	return !mips_busprobe32(tmp, (bus->mmio + (pc->dev->core_index * SSB_CORE_SIZE)));
 }
 #endif /* CONFIG_SSB_PCICORE_HOSTMODE */
 
@@ -458,7 +459,8 @@ static void ssb_commit_settings(struct s
 	struct ssb_device *dev;
 
 	dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
-	assert(dev);
+	if (WARN_ON(!dev))
+		return;
 	/* This forces an update of the cached registers. */
 	ssb_broadcast_value(dev, 0xFD8, 0);
 }
@@ -531,7 +533,7 @@ int ssb_pcicore_dev_irqvecs_enable(struc
 			pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
 		}
 	} else {
-		assert(pdev->id.coreid == SSB_DEV_PCIE);
+		WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
 		//TODO: Better make defines for all these magic PCIE values.
 		if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) {
 			/* TLP Workaround register. */
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index f84ee37..9cc4985 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -14,27 +14,36 @@ #include <linux/delay.h>
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_regs.h>
 
-#ifdef CONFIG_SSB_PCIHOST
-# include <linux/pci.h>
-#endif
+#include <linux/pci.h>
 
-#ifdef CONFIG_SSB_PCMCIAHOST
-# include <pcmcia/cs_types.h>
-# include <pcmcia/cs.h>
-# include <pcmcia/cistpl.h>
-# include <pcmcia/ds.h>
-#endif
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
 
 
 MODULE_DESCRIPTION("Sonics Silicon Backplane driver");
 MODULE_LICENSE("GPL");
 
 
+/* Temporary list of yet-to-be-attached buses */
 static LIST_HEAD(attach_queue);
+/* List if running buses */
 static LIST_HEAD(buses);
-static int nr_buses;
+/* Software ID counter */
+static unsigned int next_busnumber;
+/* buses_mutes locks the two buslists and the next_busnumber.
+ * Don't lock this directly, but use ssb_buses_[un]lock() below. */
 static DEFINE_MUTEX(buses_mutex);
 
+/* There are differences in the codeflow, if the bus is
+ * initialized from early boot, as various needed services
+ * are not available early. This is a mechanism to delay
+ * these initializations to after early boot has finished.
+ * It's also used to avoid mutex locking, as that's not
+ * available and needed early. */
+static bool ssb_is_early_boot = 1;
+
 static void ssb_buses_lock(void);
 static void ssb_buses_unlock(void);
 
@@ -272,7 +281,7 @@ static int ssb_bus_match(struct device *
 }
 
 static struct bus_type ssb_bustype = {
-	.name		= NULL, /* Intentionally NULL to indicate early boot */
+	.name		= "ssb",
 	.match		= ssb_bus_match,
 	.probe		= ssb_device_probe,
 	.remove		= ssb_device_remove,
@@ -281,17 +290,15 @@ static struct bus_type ssb_bustype = {
 	.resume		= ssb_device_resume,
 };
 
-#define is_early_boot()		(ssb_bustype.name == NULL)
-
 static void ssb_buses_lock(void)
 {
-	if (!is_early_boot())
+	if (!ssb_is_early_boot)
 		mutex_lock(&buses_mutex);
 }
 
 static void ssb_buses_unlock(void)
 {
-	if (!is_early_boot())
+	if (!ssb_is_early_boot)
 		mutex_unlock(&buses_mutex);
 }
 
@@ -365,7 +372,7 @@ static int ssb_devices_register(struct s
 		dev->release = ssb_release_dev;
 		dev->bus = &ssb_bustype;
 		snprintf(dev->bus_id, sizeof(dev->bus_id),
-			 "ssb%d:%d", bus->busnumber, dev_idx);
+			 "ssb%u:%d", bus->busnumber, dev_idx);
 
 		switch (bus->bustype) {
 		case SSB_BUSTYPE_PCI:
@@ -467,6 +474,7 @@ static void ssb_ssb_write32(struct ssb_d
 	writel(value, bus->mmio + offset);
 }
 
+/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
 static const struct ssb_bus_ops ssb_ssb_ops = {
 	.read16		= ssb_ssb_read16,
 	.read32		= ssb_ssb_read32,
@@ -475,12 +483,12 @@ static const struct ssb_bus_ops ssb_ssb_
 };
 
 static int ssb_fetch_invariants(struct ssb_bus *bus,
-				int (*get_invariants)(struct ssb_bus *bus,
-						      struct ssb_init_invariants *iv))
+				ssb_invariants_func_t get_invariants)
 {
 	struct ssb_init_invariants iv;
 	int err;
 
+	memset(&iv, 0, sizeof(iv));
 	err = get_invariants(bus, &iv);
 	if (err)
 		goto out;
@@ -491,8 +499,7 @@ out:
 }
 
 static int ssb_bus_register(struct ssb_bus *bus,
-			    int (*get_invariants)(struct ssb_bus *bus,
-			    			  struct ssb_init_invariants *iv),
+			    ssb_invariants_func_t get_invariants,
 			    unsigned long baseaddr)
 {
 	int err;
@@ -505,7 +512,7 @@ static int ssb_bus_register(struct ssb_b
 	if (err)
 		goto out;
 	ssb_buses_lock();
-	bus->busnumber = nr_buses;
+	bus->busnumber = next_busnumber;
 	/* Scan for devices (cores) */
 	err = ssb_bus_scan(bus, baseaddr);
 	if (err)
@@ -529,13 +536,13 @@ static int ssb_bus_register(struct ssb_b
 
 	/* Queue it for attach */
 	list_add_tail(&bus->list, &attach_queue);
-	if (!is_early_boot()) {
+	if (!ssb_is_early_boot) {
 		/* This is not early boot, so we must attach the bus now */
 		err = ssb_attach_queued_buses();
 		if (err)
 			goto err_dequeue;
 	}
-	nr_buses++;
+	next_busnumber++;
 	ssb_buses_unlock();
 
 out:
@@ -600,8 +607,7 @@ #endif /* CONFIG_SSB_PCMCIAHOST */
 
 int ssb_bus_ssbbus_register(struct ssb_bus *bus,
 			    unsigned long baseaddr,
-			    int (*get_invariants)(struct ssb_bus *bus,
-			    			  struct ssb_init_invariants *iv))
+			    ssb_invariants_func_t get_invariants)
 {
 	int err;
 
@@ -694,13 +700,13 @@ u32 ssb_calc_clock_rate(u32 plltype, u32
 	case SSB_PLLTYPE_2: /* 48Mhz, 4 dividers */
 		n1 += SSB_CHIPCO_CLK_T2_BIAS;
 		n2 += SSB_CHIPCO_CLK_T2_BIAS;
-		assert((n1 >= 2) && (n1 <= 7));
-		assert((n2 >= 5) && (n2 <= 23));
+		SSB_WARN_ON(!((n1 >= 2) && (n1 <= 7)));
+		SSB_WARN_ON(!((n2 >= 5) && (n2 <= 23)));
 		break;
 	case SSB_PLLTYPE_5: /* 25Mhz, 4 dividers */
 		return 100000000;
 	default:
-		assert(0);
+		SSB_WARN_ON(1);
 	}
 
 	switch (plltype) {
@@ -749,9 +755,9 @@ u32 ssb_calc_clock_rate(u32 plltype, u32
 		m1 += SSB_CHIPCO_CLK_T2_BIAS;
 		m2 += SSB_CHIPCO_CLK_T2M2_BIAS;
 		m3 += SSB_CHIPCO_CLK_T2_BIAS;
-		assert((m1 >= 2) && (m1 <= 7));
-		assert((m2 >= 3) && (m2 <= 10));
-		assert((m3 >= 2) && (m3 <= 7));
+		SSB_WARN_ON(!((m1 >= 2) && (m1 <= 7)));
+		SSB_WARN_ON(!((m2 >= 3) && (m2 <= 10)));
+		SSB_WARN_ON(!((m3 >= 2) && (m3 <= 7)));
 
 		if (!(mc & SSB_CHIPCO_CLK_T2MC_M1BYP))
 			clock /= m1;
@@ -761,7 +767,7 @@ u32 ssb_calc_clock_rate(u32 plltype, u32
 			clock /= m3;
 		return clock;
 	default:
-		assert(0);
+		SSB_WARN_ON(1);
 	}
 	return 0;
 }
@@ -803,7 +809,7 @@ static u32 ssb_tmslow_reject_bitmask(str
 	case SSB_IDLOW_SSBREV_23:
 		return SSB_TMSLOW_REJECT_23;
 	default:
-		assert(0);
+		WARN_ON(1);
 	}
 	return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23);
 }
@@ -912,7 +918,7 @@ EXPORT_SYMBOL(ssb_device_disable);
 
 u32 ssb_dma_translation(struct ssb_device *dev)
 {
-	switch(dev->bus->bustype) {
+	switch (dev->bus->bustype) {
 	case SSB_BUSTYPE_SSB:
 		return 0;
 	case SSB_BUSTYPE_PCI:
@@ -963,7 +969,7 @@ error:
 }
 EXPORT_SYMBOL(ssb_bus_may_powerdown);
 
-int ssb_bus_powerup(struct ssb_bus *bus, int dynamic_pctl)
+int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
 {
 	struct ssb_chipcommon *cc;
 	int err;
@@ -992,15 +998,15 @@ u32 ssb_admatch_base(u32 adm)
 		base = (adm & SSB_ADM_BASE0);
 		break;
 	case SSB_ADM_TYPE1:
-		assert(!(adm & SSB_ADM_NEG)); /* unsupported */
+		SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
 		base = (adm & SSB_ADM_BASE1);
 		break;
 	case SSB_ADM_TYPE2:
-		assert(!(adm & SSB_ADM_NEG)); /* unsupported */
+		SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
 		base = (adm & SSB_ADM_BASE2);
 		break;
 	default:
-		assert(0);
+		SSB_WARN_ON(1);
 	}
 
 	return base;
@@ -1016,15 +1022,15 @@ u32 ssb_admatch_size(u32 adm)
 		size = ((adm & SSB_ADM_SZ0) >> SSB_ADM_SZ0_SHIFT);
 		break;
 	case SSB_ADM_TYPE1:
-		assert(!(adm & SSB_ADM_NEG)); /* unsupported */
+		SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
 		size = ((adm & SSB_ADM_SZ1) >> SSB_ADM_SZ1_SHIFT);
 		break;
 	case SSB_ADM_TYPE2:
-		assert(!(adm & SSB_ADM_NEG)); /* unsupported */
+		SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
 		size = ((adm & SSB_ADM_SZ2) >> SSB_ADM_SZ2_SHIFT);
 		break;
 	default:
-		assert(0);
+		SSB_WARN_ON(1);
 	}
 	size = (1 << (size + 1));
 
@@ -1036,7 +1042,7 @@ static int __init ssb_modinit(void)
 {
 	int err;
 
-	ssb_bustype.name = "ssb";
+	ssb_is_early_boot = 0;
 	err = bus_register(&ssb_bustype);
 	if (err)
 		return err;
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index f9dc28f..6767fd2 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -23,6 +23,7 @@ #include <linux/delay.h>
 #include "ssb_private.h"
 
 
+/* Lowlevel coreswitching */
 int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
 {
 	int err;
@@ -74,6 +75,7 @@ int ssb_pci_switch_core(struct ssb_bus *
 	return err;
 }
 
+/* Enable/disable the on board crystal oscillator and/or PLL. */
 int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on)
 {
 	int err;
@@ -158,7 +160,9 @@ err_pci:
 	goto out;
 }
 
+/* Get the word-offset for a SSB_SPROM_XXX define. */
 #define SPOFF(offset)	(((offset) - SSB_SPROM_BASE) / sizeof(u16))
+/* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
 #define SPEX(_outvar, _offset, _mask, _shift)	\
 	out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
 
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index b908563..f72afd8 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -112,7 +112,7 @@ int ssb_pcmcia_switch_segment(struct ssb
 	conf_reg_t reg;
 	int res, err = 0;
 
-	assert(seg == 0 || seg == 1);
+	SSB_WARN_ON((seg != 0) && (seg != 1));
 	reg.Offset = 0x34;
 	reg.Function = 0;
 	spin_lock_irqsave(&bus->bar_lock, flags);
@@ -145,6 +145,9 @@ error:
 	goto out_unlock;
 }
 
+/* These are the main device register access functions.
+ * do_select_core is inline to have the likely hotpath inline.
+ * All unlikely codepaths are out-of-line. */
 static inline int do_select_core(struct ssb_bus *bus,
 				 struct ssb_device *dev,
 				 u16 *offset)
@@ -176,7 +179,7 @@ static u16 ssb_pcmcia_read16(struct ssb_
 	if (unlikely(do_select_core(bus, dev, &offset)))
 		return 0xFFFF;
 	x = readw(bus->mmio + offset);
-//printk("R16 0x%04X, 0x%04X\n", offset, x);
+
 	return x;
 }
 
@@ -188,7 +191,7 @@ static u32 ssb_pcmcia_read32(struct ssb_
 	if (unlikely(do_select_core(bus, dev, &offset)))
 		return 0xFFFFFFFF;
 	x = readl(bus->mmio + offset);
-//printk("R32 0x%04X, 0x%08X\n", offset, x);
+
 	return x;
 }
 
@@ -198,7 +201,6 @@ static void ssb_pcmcia_write16(struct ss
 
 	if (unlikely(do_select_core(bus, dev, &offset)))
 		return;
-//printk("W16 0x%04X, 0x%04X\n", offset, value);
 	writew(value, bus->mmio + offset);
 }
 
@@ -208,7 +210,6 @@ static void ssb_pcmcia_write32(struct ss
 
 	if (unlikely(do_select_core(bus, dev, &offset)))
 		return;
-//printk("W32 0x%04X, 0x%08X\n", offset, value);
 	readw(bus->mmio + offset);
 	writew(value >> 16, bus->mmio + offset + 2);
 	readw(bus->mmio + offset);
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index feaf1e5..9c33425 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -15,14 +15,12 @@
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_regs.h>
 #include <linux/pci.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
-#ifdef CONFIG_SSB_PCMCIAHOST
-# include <pcmcia/cs_types.h>
-# include <pcmcia/cs.h>
-# include <pcmcia/cistpl.h>
-# include <pcmcia/ds.h>
-#endif
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
 
 #include "ssb_private.h"
 
@@ -202,7 +200,11 @@ void ssb_iounmap(struct ssb_bus *bus)
 		iounmap(bus->mmio);
 		break;
 	case SSB_BUSTYPE_PCI:
+#ifdef CONFIG_SSB_PCIHOST
 		pci_iounmap(bus->host_pci, bus->mmio);
+#else
+		SSB_BUG_ON(1); /* Can't reach this code. */
+#endif
 		break;
 	}
 	bus->mmio = NULL;
@@ -222,7 +224,11 @@ static void __iomem * ssb_ioremap(struct
 		mmio = ioremap(baseaddr, SSB_CORE_SIZE);
 		break;
 	case SSB_BUSTYPE_PCI:
+#ifdef CONFIG_SSB_PCIHOST
 		mmio = pci_iomap(bus->host_pci, 0, ~0UL);
+#else
+		SSB_BUG_ON(1); /* Can't reach this code. */
+#endif
 		break;
 	}
 
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index d00d186..8e2e310 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -3,7 +3,6 @@ #define LINUX_SSB_PRIVATE_H_
 
 #include <linux/ssb/ssb.h>
 #include <linux/types.h>
-#include <asm/io.h>
 
 
 #define PFX	"ssb: "
@@ -16,32 +15,19 @@ #endif /* CONFIG_SSB_SILENT */
 
 /* dprintk: Debugging printk; vanishes for non-debug compilation */
 #ifdef CONFIG_SSB_DEBUG
-# define ssb_dprintk(fmt, x...)	ssb_printk(fmt ,##x)
+# define ssb_dprintk(fmt, x...)	ssb_printk(fmt , ##x)
 #else
 # define ssb_dprintk(fmt, x...)	do { /* nothing */ } while (0)
 #endif
 
-/* printkl: Rate limited printk */
-#define ssb_printkl(fmt, x...)	do {		\
-	if (printk_ratelimit())			\
-		ssb_printk(fmt ,##x);		\
-				} while (0)
-
-/* dprintkl: Rate limited debugging printk */
 #ifdef CONFIG_SSB_DEBUG
-# define ssb_dprintkl			ssb_printkl
+# define SSB_WARN_ON(x)		WARN_ON(x)
+# define SSB_BUG_ON(x)		BUG_ON(x)
 #else
-# define ssb_dprintkl(fmt, x...)	do { /* nothing */ } while (0)
+# define SSB_WARN_ON(x)		do { /* nothing */ } while (0)
+# define SSB_BUG_ON(x)		do { /* nothing */ } while (0)
 #endif
 
-#define assert(cond)	do {						\
-	if (unlikely(!(cond))) {					\
-		ssb_dprintk(KERN_ERR PFX "BUG: Assertion failed (%s) "	\
-			    "at: %s:%d:%s()\n",				\
-			    #cond, __FILE__, __LINE__, __func__);	\
-	}								\
-		       } while (0)
-
 
 /* pci.c */
 #ifdef CONFIG_SSB_PCIHOST
@@ -128,10 +114,8 @@ extern void ssb_iounmap(struct ssb_bus *
 
 /* core.c */
 extern u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m);
-#ifdef CONFIG_SSB_PCIHOST
 extern int ssb_devices_freeze(struct ssb_bus *bus);
 extern int ssb_devices_thaw(struct ssb_bus *bus);
 extern struct ssb_bus * ssb_pci_dev_to_bus(struct pci_dev *pdev);
-#endif /* CONFIG_SSB_PCIHOST */
 
 #endif /* LINUX_SSB_PRIVATE_H_ */
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 709e2fa..a3c63ae 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -1,14 +1,11 @@
 #ifndef LINUX_SSB_H_
 #define LINUX_SSB_H_
-#ifdef __KERNEL__
 
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
-#ifdef CONFIG_SSB_PCIHOST
-# include <linux/pci.h>
-#endif
+#include <linux/pci.h>
 
 #include <linux/ssb/ssb_regs.h>
 
@@ -296,6 +293,7 @@ struct ssb_bus {
 	struct pcmcia_device *host_pcmcia;
 
 #ifdef CONFIG_SSB_PCIHOST
+	/* Mutex to protect the SPROM writing. */
 	struct mutex pci_sprom_mutex;
 #endif
 
@@ -312,7 +310,7 @@ #endif
 	u8 suspend_cnt;
 
 	/* Software ID number for this bus. */
-	int busnumber;
+	unsigned int busnumber;
 
 	/* The ChipCommon device (if available). */
 	struct ssb_chipcommon chipco;
@@ -342,6 +340,9 @@ struct ssb_init_invariants {
 	struct ssb_boardinfo boardinfo;
 	struct ssb_sprom sprom;
 };
+/* Type of function to fetch the invariants. */
+typedef int (*ssb_invariants_func_t)(struct ssb_bus *bus,
+				     struct ssb_init_invariants *iv);
 
 /* Register a SSB system bus. get_invariants() is called after the
  * basic system devices are initialized.
@@ -349,8 +350,7 @@ struct ssb_init_invariants {
  * Put the invariants into the struct pointed to by iv. */
 extern int ssb_bus_ssbbus_register(struct ssb_bus *bus,
 				   unsigned long baseaddr,
-				   int (*get_invariants)(struct ssb_bus *bus,
-				   			 struct ssb_init_invariants *iv));
+				   ssb_invariants_func_t get_invariants);
 #ifdef CONFIG_SSB_PCIHOST
 extern int ssb_bus_pcibus_register(struct ssb_bus *bus,
 				   struct pci_dev *host_pci);
@@ -365,8 +365,12 @@ extern void ssb_bus_unregister(struct ss
 
 extern u32 ssb_clockspeed(struct ssb_bus *bus);
 
+/* Is the device enabled in hardware? */
 int ssb_device_is_enabled(struct ssb_device *dev);
+/* Enable a device and pass device-specific SSB_TMSLOW flags.
+ * If no device-specific flags are available, use 0. */
 void ssb_device_enable(struct ssb_device *dev, u32 core_specific_flags);
+/* Disable a device in hardware and pass SSB_TMSLOW flags (if any). */
 void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags);
 
 
@@ -408,9 +412,15 @@ static inline void ssb_pcihost_unregiste
 #endif /* CONFIG_SSB_PCIHOST */
 
 
-/* Bus-Power handling functions. */
+/* If a driver is shutdown or suspended, call this to signal
+ * that the bus may be completely powered down. SSB will decide,
+ * if it's really time to power down the bus, based on if there
+ * are other devices that want to run. */
 extern int ssb_bus_may_powerdown(struct ssb_bus *bus);
-extern int ssb_bus_powerup(struct ssb_bus *bus, int dynamic_pctl);
+/* Before initializing and enabling a device, call this to power-up the bus.
+ * If you want to allow use of dynamic-power-control, pass the flag.
+ * Otherwise static always-on powercontrol will be used. */
+extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl);
 
 
 /* Various helper functions */
@@ -418,5 +428,4 @@ extern u32 ssb_admatch_base(u32 adm);
 extern u32 ssb_admatch_size(u32 adm);
 
 
-#endif /* __KERNEL__ */
 #endif /* LINUX_SSB_H_ */
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
index 8856590..d58c24b 100644
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -12,7 +12,6 @@ #define LINUX_SSB_CHIPCO_H_
  *
  * Licensed under the GPL version 2. See COPYING for details.
  */
-#ifdef __KERNEL__
 
 /** ChipCommon core registers. **/
 
@@ -383,5 +382,4 @@ extern int ssb_chipco_serial_init(struct
 				  struct ssb_serial_port *ports);
 #endif /* CONFIG_SSB_SERIAL */
 
-#endif /* __KERNEL__ */
 #endif /* LINUX_SSB_CHIPCO_H_ */
diff --git a/include/linux/ssb/ssb_driver_extif.h b/include/linux/ssb/ssb_driver_extif.h
index 278a637..00de749 100644
--- a/include/linux/ssb/ssb_driver_extif.h
+++ b/include/linux/ssb/ssb_driver_extif.h
@@ -20,8 +20,6 @@
 #ifndef LINUX_SSB_EXTIFCORE_H_
 #define LINUX_SSB_EXTIFCORE_H_
 
-#ifdef __KERNEL__
-
 struct ssb_extif {
 	struct ssb_device *dev;
 };
@@ -159,5 +157,4 @@ #define	SSB_FLASH_WCNT_3_SHIFT		24
 #define SSB_EXTIF_WATCHDOG_CLK		48000000	/* Hz */
 
 
-#endif /* __KERNEL__ */
 #endif /* LINUX_SSB_EXTIFCORE_H_ */
diff --git a/include/linux/ssb/ssb_driver_mips.h b/include/linux/ssb/ssb_driver_mips.h
index 91f2373..cdbb985 100644
--- a/include/linux/ssb/ssb_driver_mips.h
+++ b/include/linux/ssb/ssb_driver_mips.h
@@ -1,8 +1,6 @@
 #ifndef LINUX_SSB_MIPSCORE_H_
 #define LINUX_SSB_MIPSCORE_H_
 
-#ifdef __KERNEL__
-
 #ifdef CONFIG_SSB_DRIVER_MIPS
 
 struct ssb_device;
@@ -43,5 +41,4 @@ void ssb_mipscore_init(struct ssb_mipsco
 
 #endif /* CONFIG_SSB_DRIVER_MIPS */
 
-#endif /* __KERNEL__ */
 #endif /* LINUX_SSB_MIPSCORE_H_ */
diff --git a/include/linux/ssb/ssb_driver_pci.h b/include/linux/ssb/ssb_driver_pci.h
index 5132f26..9cfffb7 100644
--- a/include/linux/ssb/ssb_driver_pci.h
+++ b/include/linux/ssb/ssb_driver_pci.h
@@ -1,6 +1,5 @@
 #ifndef LINUX_SSB_PCICORE_H_
 #define LINUX_SSB_PCICORE_H_
-#ifdef __KERNEL__
 
 #ifdef CONFIG_SSB_DRIVER_PCICORE
 
@@ -104,5 +103,4 @@ int ssb_pcicore_dev_irqvecs_enable(struc
 }
 
 #endif /* CONFIG_SSB_DRIVER_PCICORE */
-#endif /* __KERNEL__ */
 #endif /* LINUX_SSB_PCICORE_H_ */
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
index 1fa4bf8..66751a6 100644
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -1,6 +1,5 @@
 #ifndef LINUX_SSB_REGS_H_
 #define LINUX_SSB_REGS_H_
-#ifdef __KERNEL__
 
 
 /* SiliconBackplane Address Map.
@@ -22,10 +21,10 @@ #define	SSB_FLASH1_SZ		0x00400000	/* Siz
 
 #define SSB_PCI_DMA		0x40000000	/* Client Mode sb2pcitranslation2 (1 GB) */
 #define SSB_PCI_DMA_SZ		0x40000000	/* Client Mode sb2pcitranslation2 size in bytes */
-#define SSB_PCIE_DMA_L32		0x00000000	/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
-#define SSB_PCIE_DMA_H32		0x80000000	/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
-#define	SSB_EUART		(SB_EXTIF_BASE + 0x00800000)
-#define	SSB_LED			(SB_EXTIF_BASE + 0x00900000)
+#define SSB_PCIE_DMA_L32	0x00000000	/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
+#define SSB_PCIE_DMA_H32	0x80000000	/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
+#define	SSB_EUART		(SSB_EXTIF_BASE + 0x00800000)
+#define	SSB_LED			(SSB_EXTIF_BASE + 0x00900000)
 
 
 /* Enumeration space constants */
@@ -268,7 +267,7 @@ enum {
 	SSB_SPROM1CCODE_NONE,
 };
 
-/* Address-Match values and masks (SSB_ADMATCH?) */
+/* Address-Match values and masks (SSB_ADMATCHxxx) */
 #define SSB_ADM_TYPE			0x00000003	/* Address type */
 #define  SSB_ADM_TYPE0			0
 #define  SSB_ADM_TYPE1			1
@@ -290,5 +289,4 @@ #define SSB_ADM_BASE2			0xFFFF0000	/* Ty
 #define SSB_ADM_BASE2_SHIFT		16
 
 
-#endif /* __KERNEL__ */
 #endif /* LINUX_SSB_REGS_H_ */

-- 
Greetings Michael.
-
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux