[<prev] [next>] [day] [month] [year] [list]
Message-Id: <200707271415.25087.mb@bu3sch.de>
Date: Fri, 27 Jul 2007 14:15:24 +0200
From: Michael Buesch <mb@...sch.de>
To: John Linville <linville@...driver.com>
Cc: bcm43xx-dev@...ts.berlios.de, linux-wireless@...r.kernel.org,
netdev@...r.kernel.org
Subject: Please pull latest bcm43xx-mac80211 + ssb
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 netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists