aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2006-06-27 15:38:40 -0400
committerJohn W. Linville <linville@tuxdriver.com>2006-07-10 14:19:41 -0400
commitefa6a370216f1816456b49aac03295071720f7eb (patch)
treea29c205e603d96ad3b4ef34b274335a851672aac /drivers/net/wireless
parentb312d799b324e895745ffe148def234fc60d5b74 (diff)
[PATCH] bcm43xx: opencoded locking
As many people don't seem to like the locking "obfuscation" in the bcm43xx driver, this patch removes it. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h64
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c34
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.c10
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c64
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_pio.c4
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c34
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.c121
7 files changed, 167 insertions, 164 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 17a56828e232..ee6571ed706d 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -649,6 +649,19 @@ enum {
649#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status) 649#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status)
650#define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat)) 650#define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat))
651 651
652/* *** THEORY OF LOCKING ***
653 *
654 * We have two different locks in the bcm43xx driver.
655 * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
656 * and the device registers. This mutex does _not_ protect
657 * against concurrency from the IRQ handler.
658 * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
659 *
660 * Please note that, if you only take the irq_lock, you are not protected
661 * against concurrency from the periodic work handlers.
662 * Most times you want to take _both_ locks.
663 */
664
652struct bcm43xx_private { 665struct bcm43xx_private {
653 struct ieee80211_device *ieee; 666 struct ieee80211_device *ieee;
654 struct ieee80211softmac_device *softmac; 667 struct ieee80211softmac_device *softmac;
@@ -659,7 +672,6 @@ struct bcm43xx_private {
659 672
660 void __iomem *mmio_addr; 673 void __iomem *mmio_addr;
661 674
662 /* Locking, see "theory of locking" text below. */
663 spinlock_t irq_lock; 675 spinlock_t irq_lock;
664 struct mutex mutex; 676 struct mutex mutex;
665 677
@@ -691,6 +703,7 @@ struct bcm43xx_private {
691 struct bcm43xx_sprominfo sprom; 703 struct bcm43xx_sprominfo sprom;
692#define BCM43xx_NR_LEDS 4 704#define BCM43xx_NR_LEDS 4
693 struct bcm43xx_led leds[BCM43xx_NR_LEDS]; 705 struct bcm43xx_led leds[BCM43xx_NR_LEDS];
706 spinlock_t leds_lock;
694 707
695 /* The currently active core. */ 708 /* The currently active core. */
696 struct bcm43xx_coreinfo *current_core; 709 struct bcm43xx_coreinfo *current_core;
@@ -763,55 +776,6 @@ struct bcm43xx_private {
763}; 776};
764 777
765 778
766/* *** THEORY OF LOCKING ***
767 *
768 * We have two different locks in the bcm43xx driver.
769 * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
770 * and the device registers.
771 * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
772 *
773 * We have three types of helper function pairs to utilize these locks.
774 * (Always use the helper functions.)
775 * 1) bcm43xx_{un}lock_noirq():
776 * Takes bcm->mutex. Does _not_ protect against IRQ concurrency,
777 * so it is almost always unsafe, if device IRQs are enabled.
778 * So only use this, if device IRQs are masked.
779 * Locking may sleep.
780 * You can sleep within the critical section.
781 * 2) bcm43xx_{un}lock_irqonly():
782 * Takes bcm->irq_lock. Does _not_ protect against
783 * bcm43xx_lock_noirq() critical sections.
784 * Does only protect against the IRQ handler path and other
785 * irqonly() critical sections.
786 * Locking does not sleep.
787 * You must not sleep within the critical section.
788 * 3) bcm43xx_{un}lock_irqsafe():
789 * This is the cummulative lock and takes both, mutex and irq_lock.
790 * Protects against noirq() and irqonly() critical sections (and
791 * the IRQ handler path).
792 * Locking may sleep.
793 * You must not sleep within the critical section.
794 */
795
796/* Lock type 1 */
797#define bcm43xx_lock_noirq(bcm) mutex_lock(&(bcm)->mutex)
798#define bcm43xx_unlock_noirq(bcm) mutex_unlock(&(bcm)->mutex)
799/* Lock type 2 */
800#define bcm43xx_lock_irqonly(bcm, flags) \
801 spin_lock_irqsave(&(bcm)->irq_lock, flags)
802#define bcm43xx_unlock_irqonly(bcm, flags) \
803 spin_unlock_irqrestore(&(bcm)->irq_lock, flags)
804/* Lock type 3 */
805#define bcm43xx_lock_irqsafe(bcm, flags) do { \
806 bcm43xx_lock_noirq(bcm); \
807 bcm43xx_lock_irqonly(bcm, flags); \
808 } while (0)
809#define bcm43xx_unlock_irqsafe(bcm, flags) do { \
810 bcm43xx_unlock_irqonly(bcm, flags); \
811 bcm43xx_unlock_noirq(bcm); \
812 } while (0)
813
814
815static inline 779static inline
816struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) 780struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
817{ 781{
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
index ce2e40b29b4f..2600ee4b803a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
@@ -77,7 +77,8 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
77 77
78 down(&big_buffer_sem); 78 down(&big_buffer_sem);
79 79
80 bcm43xx_lock_irqsafe(bcm, flags); 80 mutex_lock(&bcm->mutex);
81 spin_lock_irqsave(&bcm->irq_lock, flags);
81 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { 82 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
82 fappend("Board not initialized.\n"); 83 fappend("Board not initialized.\n");
83 goto out; 84 goto out;
@@ -121,7 +122,8 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
121 fappend("\n"); 122 fappend("\n");
122 123
123out: 124out:
124 bcm43xx_unlock_irqsafe(bcm, flags); 125 spin_unlock_irqrestore(&bcm->irq_lock, flags);
126 mutex_unlock(&bcm->mutex);
125 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 127 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
126 up(&big_buffer_sem); 128 up(&big_buffer_sem);
127 return res; 129 return res;
@@ -159,7 +161,8 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
159 unsigned long flags; 161 unsigned long flags;
160 162
161 down(&big_buffer_sem); 163 down(&big_buffer_sem);
162 bcm43xx_lock_irqsafe(bcm, flags); 164 mutex_lock(&bcm->mutex);
165 spin_lock_irqsave(&bcm->irq_lock, flags);
163 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { 166 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
164 fappend("Board not initialized.\n"); 167 fappend("Board not initialized.\n");
165 goto out; 168 goto out;
@@ -169,7 +172,8 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
169 fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags); 172 fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
170 173
171out: 174out:
172 bcm43xx_unlock_irqsafe(bcm, flags); 175 spin_unlock_irqrestore(&bcm->irq_lock, flags);
176 mutex_unlock(&bcm->mutex);
173 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 177 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
174 up(&big_buffer_sem); 178 up(&big_buffer_sem);
175 return res; 179 return res;
@@ -188,7 +192,8 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
188 u64 tsf; 192 u64 tsf;
189 193
190 down(&big_buffer_sem); 194 down(&big_buffer_sem);
191 bcm43xx_lock_irqsafe(bcm, flags); 195 mutex_lock(&bcm->mutex);
196 spin_lock_irqsave(&bcm->irq_lock, flags);
192 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { 197 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
193 fappend("Board not initialized.\n"); 198 fappend("Board not initialized.\n");
194 goto out; 199 goto out;
@@ -199,7 +204,8 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
199 (unsigned int)(tsf & 0xFFFFFFFFULL)); 204 (unsigned int)(tsf & 0xFFFFFFFFULL));
200 205
201out: 206out:
202 bcm43xx_unlock_irqsafe(bcm, flags); 207 spin_unlock_irqrestore(&bcm->irq_lock, flags);
208 mutex_unlock(&bcm->mutex);
203 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 209 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
204 up(&big_buffer_sem); 210 up(&big_buffer_sem);
205 return res; 211 return res;
@@ -221,7 +227,8 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
221 res = -EFAULT; 227 res = -EFAULT;
222 goto out_up; 228 goto out_up;
223 } 229 }
224 bcm43xx_lock_irqsafe(bcm, flags); 230 mutex_lock(&bcm->mutex);
231 spin_lock_irqsave(&bcm->irq_lock, flags);
225 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { 232 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
226 printk(KERN_INFO PFX "debugfs: Board not initialized.\n"); 233 printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
227 res = -EFAULT; 234 res = -EFAULT;
@@ -237,7 +244,8 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
237 res = buf_size; 244 res = buf_size;
238 245
239out_unlock: 246out_unlock:
240 bcm43xx_unlock_irqsafe(bcm, flags); 247 spin_unlock_irqrestore(&bcm->irq_lock, flags);
248 mutex_unlock(&bcm->mutex);
241out_up: 249out_up:
242 up(&big_buffer_sem); 250 up(&big_buffer_sem);
243 return res; 251 return res;
@@ -258,7 +266,8 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
258 int i, cnt, j = 0; 266 int i, cnt, j = 0;
259 267
260 down(&big_buffer_sem); 268 down(&big_buffer_sem);
261 bcm43xx_lock_irqsafe(bcm, flags); 269 mutex_lock(&bcm->mutex);
270 spin_lock_irqsave(&bcm->irq_lock, flags);
262 271
263 fappend("Last %d logged xmitstatus blobs (Latest first):\n\n", 272 fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
264 BCM43xx_NR_LOGGED_XMITSTATUS); 273 BCM43xx_NR_LOGGED_XMITSTATUS);
@@ -294,14 +303,15 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
294 i = BCM43xx_NR_LOGGED_XMITSTATUS - 1; 303 i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
295 } 304 }
296 305
297 bcm43xx_unlock_irqsafe(bcm, flags); 306 spin_unlock_irqrestore(&bcm->irq_lock, flags);
298 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 307 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
299 bcm43xx_lock_irqsafe(bcm, flags); 308 spin_lock_irqsave(&bcm->irq_lock, flags);
300 if (*ppos == pos) { 309 if (*ppos == pos) {
301 /* Done. Drop the copied data. */ 310 /* Done. Drop the copied data. */
302 e->xmitstatus_printing = 0; 311 e->xmitstatus_printing = 0;
303 } 312 }
304 bcm43xx_unlock_irqsafe(bcm, flags); 313 spin_unlock_irqrestore(&bcm->irq_lock, flags);
314 mutex_unlock(&bcm->mutex);
305 up(&big_buffer_sem); 315 up(&big_buffer_sem);
306 return res; 316 return res;
307} 317}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
index ec80692d638a..c3f90c8563d9 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
@@ -51,12 +51,12 @@ static void bcm43xx_led_blink(unsigned long d)
51 struct bcm43xx_private *bcm = led->bcm; 51 struct bcm43xx_private *bcm = led->bcm;
52 unsigned long flags; 52 unsigned long flags;
53 53
54 bcm43xx_lock_irqonly(bcm, flags); 54 spin_lock_irqsave(&bcm->leds_lock, flags);
55 if (led->blink_interval) { 55 if (led->blink_interval) {
56 bcm43xx_led_changestate(led); 56 bcm43xx_led_changestate(led);
57 mod_timer(&led->blink_timer, jiffies + led->blink_interval); 57 mod_timer(&led->blink_timer, jiffies + led->blink_interval);
58 } 58 }
59 bcm43xx_unlock_irqonly(bcm, flags); 59 spin_unlock_irqrestore(&bcm->leds_lock, flags);
60} 60}
61 61
62static void bcm43xx_led_blink_start(struct bcm43xx_led *led, 62static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
@@ -177,7 +177,9 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
177 int i, turn_on; 177 int i, turn_on;
178 unsigned long interval = 0; 178 unsigned long interval = 0;
179 u16 ledctl; 179 u16 ledctl;
180 unsigned long flags;
180 181
182 spin_lock_irqsave(&bcm->leds_lock, flags);
181 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); 183 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
182 for (i = 0; i < BCM43xx_NR_LEDS; i++) { 184 for (i = 0; i < BCM43xx_NR_LEDS; i++) {
183 led = &(bcm->leds[i]); 185 led = &(bcm->leds[i]);
@@ -266,6 +268,7 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
266 ledctl &= ~(1 << i); 268 ledctl &= ~(1 << i);
267 } 269 }
268 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); 270 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
271 spin_unlock_irqrestore(&bcm->leds_lock, flags);
269} 272}
270 273
271void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on) 274void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
@@ -274,7 +277,9 @@ void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
274 u16 ledctl; 277 u16 ledctl;
275 int i; 278 int i;
276 int bit_on; 279 int bit_on;
280 unsigned long flags;
277 281
282 spin_lock_irqsave(&bcm->leds_lock, flags);
278 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); 283 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
279 for (i = 0; i < BCM43xx_NR_LEDS; i++) { 284 for (i = 0; i < BCM43xx_NR_LEDS; i++) {
280 led = &(bcm->leds[i]); 285 led = &(bcm->leds[i]);
@@ -290,4 +295,5 @@ void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
290 ledctl &= ~(1 << i); 295 ledctl &= ~(1 << i);
291 } 296 }
292 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); 297 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
298 spin_unlock_irqrestore(&bcm->leds_lock, flags);
293} 299}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index 3889f79e7128..ef9bc80bee01 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -514,13 +514,13 @@ static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *old
514 unsigned long flags; 514 unsigned long flags;
515 u32 old; 515 u32 old;
516 516
517 bcm43xx_lock_irqonly(bcm, flags); 517 spin_lock_irqsave(&bcm->irq_lock, flags);
518 if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) { 518 if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) {
519 bcm43xx_unlock_irqonly(bcm, flags); 519 spin_unlock_irqrestore(&bcm->irq_lock, flags);
520 return -EBUSY; 520 return -EBUSY;
521 } 521 }
522 old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 522 old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
523 bcm43xx_unlock_irqonly(bcm, flags); 523 spin_unlock_irqrestore(&bcm->irq_lock, flags);
524 bcm43xx_synchronize_irq(bcm); 524 bcm43xx_synchronize_irq(bcm);
525 525
526 if (oldstate) 526 if (oldstate)
@@ -1720,7 +1720,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1720# define bcmirq_handled(irq) do { /* nothing */ } while (0) 1720# define bcmirq_handled(irq) do { /* nothing */ } while (0)
1721#endif /* CONFIG_BCM43XX_DEBUG*/ 1721#endif /* CONFIG_BCM43XX_DEBUG*/
1722 1722
1723 bcm43xx_lock_irqonly(bcm, flags); 1723 spin_lock_irqsave(&bcm->irq_lock, flags);
1724 reason = bcm->irq_reason; 1724 reason = bcm->irq_reason;
1725 dma_reason[0] = bcm->dma_reason[0]; 1725 dma_reason[0] = bcm->dma_reason[0];
1726 dma_reason[1] = bcm->dma_reason[1]; 1726 dma_reason[1] = bcm->dma_reason[1];
@@ -1746,7 +1746,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1746 dma_reason[2], dma_reason[3]); 1746 dma_reason[2], dma_reason[3]);
1747 bcm43xx_controller_restart(bcm, "DMA error"); 1747 bcm43xx_controller_restart(bcm, "DMA error");
1748 mmiowb(); 1748 mmiowb();
1749 bcm43xx_unlock_irqonly(bcm, flags); 1749 spin_unlock_irqrestore(&bcm->irq_lock, flags);
1750 return; 1750 return;
1751 } 1751 }
1752 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | 1752 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
@@ -1834,7 +1834,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1834 bcm43xx_leds_update(bcm, activity); 1834 bcm43xx_leds_update(bcm, activity);
1835 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); 1835 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
1836 mmiowb(); 1836 mmiowb();
1837 bcm43xx_unlock_irqonly(bcm, flags); 1837 spin_unlock_irqrestore(&bcm->irq_lock, flags);
1838} 1838}
1839 1839
1840static void pio_irq_workaround(struct bcm43xx_private *bcm, 1840static void pio_irq_workaround(struct bcm43xx_private *bcm,
@@ -3182,25 +3182,26 @@ static void bcm43xx_periodic_work_handler(void *d)
3182 /* Periodic work will take a long time, so we want it to 3182 /* Periodic work will take a long time, so we want it to
3183 * be preemtible. 3183 * be preemtible.
3184 */ 3184 */
3185 bcm43xx_lock_irqonly(bcm, flags);
3186 netif_stop_queue(bcm->net_dev); 3185 netif_stop_queue(bcm->net_dev);
3186 spin_lock_irqsave(&bcm->irq_lock, flags);
3187 if (bcm43xx_using_pio(bcm)) 3187 if (bcm43xx_using_pio(bcm))
3188 bcm43xx_pio_freeze_txqueues(bcm); 3188 bcm43xx_pio_freeze_txqueues(bcm);
3189 savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 3189 savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3190 bcm43xx_unlock_irqonly(bcm, flags); 3190 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3191 bcm43xx_lock_noirq(bcm); 3191 mutex_lock(&bcm->mutex);
3192 bcm43xx_synchronize_irq(bcm); 3192 bcm43xx_synchronize_irq(bcm);
3193 } else { 3193 } else {
3194 /* Periodic work should take short time, so we want low 3194 /* Periodic work should take short time, so we want low
3195 * locking overhead. 3195 * locking overhead.
3196 */ 3196 */
3197 bcm43xx_lock_irqsafe(bcm, flags); 3197 mutex_lock(&bcm->mutex);
3198 spin_lock_irqsave(&bcm->irq_lock, flags);
3198 } 3199 }
3199 3200
3200 do_periodic_work(bcm); 3201 do_periodic_work(bcm);
3201 3202
3202 if (badness > BADNESS_LIMIT) { 3203 if (badness > BADNESS_LIMIT) {
3203 bcm43xx_lock_irqonly(bcm, flags); 3204 spin_lock_irqsave(&bcm->irq_lock, flags);
3204 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { 3205 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) {
3205 tasklet_enable(&bcm->isr_tasklet); 3206 tasklet_enable(&bcm->isr_tasklet);
3206 bcm43xx_interrupt_enable(bcm, savedirqs); 3207 bcm43xx_interrupt_enable(bcm, savedirqs);
@@ -3208,13 +3209,10 @@ static void bcm43xx_periodic_work_handler(void *d)
3208 bcm43xx_pio_thaw_txqueues(bcm); 3209 bcm43xx_pio_thaw_txqueues(bcm);
3209 } 3210 }
3210 netif_wake_queue(bcm->net_dev); 3211 netif_wake_queue(bcm->net_dev);
3211 mmiowb();
3212 bcm43xx_unlock_irqonly(bcm, flags);
3213 bcm43xx_unlock_noirq(bcm);
3214 } else {
3215 mmiowb();
3216 bcm43xx_unlock_irqsafe(bcm, flags);
3217 } 3212 }
3213 mmiowb();
3214 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3215 mutex_unlock(&bcm->mutex);
3218} 3216}
3219 3217
3220static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) 3218static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
@@ -3276,7 +3274,7 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3276{ 3274{
3277 int i, err; 3275 int i, err;
3278 3276
3279 bcm43xx_lock_noirq(bcm); 3277 mutex_lock(&bcm->mutex);
3280 bcm43xx_sysfs_unregister(bcm); 3278 bcm43xx_sysfs_unregister(bcm);
3281 bcm43xx_periodic_tasks_delete(bcm); 3279 bcm43xx_periodic_tasks_delete(bcm);
3282 3280
@@ -3297,7 +3295,7 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3297 bcm43xx_pctl_set_crystal(bcm, 0); 3295 bcm43xx_pctl_set_crystal(bcm, 0);
3298 3296
3299 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); 3297 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3300 bcm43xx_unlock_noirq(bcm); 3298 mutex_unlock(&bcm->mutex);
3301} 3299}
3302 3300
3303static int bcm43xx_init_board(struct bcm43xx_private *bcm) 3301static int bcm43xx_init_board(struct bcm43xx_private *bcm)
@@ -3307,7 +3305,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3307 3305
3308 might_sleep(); 3306 might_sleep();
3309 3307
3310 bcm43xx_lock_noirq(bcm); 3308 mutex_lock(&bcm->mutex);
3311 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING); 3309 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
3312 3310
3313 err = bcm43xx_pctl_set_crystal(bcm, 1); 3311 err = bcm43xx_pctl_set_crystal(bcm, 1);
@@ -3389,7 +3387,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3389 3387
3390 assert(err == 0); 3388 assert(err == 0);
3391out: 3389out:
3392 bcm43xx_unlock_noirq(bcm); 3390 mutex_unlock(&bcm->mutex);
3393 3391
3394 return err; 3392 return err;
3395 3393
@@ -3647,7 +3645,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3647 struct bcm43xx_radioinfo *radio; 3645 struct bcm43xx_radioinfo *radio;
3648 unsigned long flags; 3646 unsigned long flags;
3649 3647
3650 bcm43xx_lock_irqsafe(bcm, flags); 3648 mutex_lock(&bcm->mutex);
3649 spin_lock_irqsave(&bcm->irq_lock, flags);
3651 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { 3650 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
3652 bcm43xx_mac_suspend(bcm); 3651 bcm43xx_mac_suspend(bcm);
3653 bcm43xx_radio_selectchannel(bcm, channel, 0); 3652 bcm43xx_radio_selectchannel(bcm, channel, 0);
@@ -3656,7 +3655,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3656 radio = bcm43xx_current_radio(bcm); 3655 radio = bcm43xx_current_radio(bcm);
3657 radio->initial_channel = channel; 3656 radio->initial_channel = channel;
3658 } 3657 }
3659 bcm43xx_unlock_irqsafe(bcm, flags); 3658 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3659 mutex_unlock(&bcm->mutex);
3660} 3660}
3661 3661
3662/* set_security() callback in struct ieee80211_device */ 3662/* set_security() callback in struct ieee80211_device */
@@ -3670,7 +3670,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3670 3670
3671 dprintk(KERN_INFO PFX "set security called"); 3671 dprintk(KERN_INFO PFX "set security called");
3672 3672
3673 bcm43xx_lock_irqsafe(bcm, flags); 3673 mutex_lock(&bcm->mutex);
3674 spin_lock_irqsave(&bcm->irq_lock, flags);
3674 3675
3675 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) 3676 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
3676 if (sec->flags & (1<<keyidx)) { 3677 if (sec->flags & (1<<keyidx)) {
@@ -3739,7 +3740,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3739 } else 3740 } else
3740 bcm43xx_clear_keys(bcm); 3741 bcm43xx_clear_keys(bcm);
3741 } 3742 }
3742 bcm43xx_unlock_irqsafe(bcm, flags); 3743 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3744 mutex_unlock(&bcm->mutex);
3743} 3745}
3744 3746
3745/* hard_start_xmit() callback in struct ieee80211_device */ 3747/* hard_start_xmit() callback in struct ieee80211_device */
@@ -3751,10 +3753,10 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
3751 int err = -ENODEV; 3753 int err = -ENODEV;
3752 unsigned long flags; 3754 unsigned long flags;
3753 3755
3754 bcm43xx_lock_irqonly(bcm, flags); 3756 spin_lock_irqsave(&bcm->irq_lock, flags);
3755 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) 3757 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED))
3756 err = bcm43xx_tx(bcm, txb); 3758 err = bcm43xx_tx(bcm, txb);
3757 bcm43xx_unlock_irqonly(bcm, flags); 3759 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3758 3760
3759 return err; 3761 return err;
3760} 3762}
@@ -3769,9 +3771,9 @@ static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
3769 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 3771 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3770 unsigned long flags; 3772 unsigned long flags;
3771 3773
3772 bcm43xx_lock_irqonly(bcm, flags); 3774 spin_lock_irqsave(&bcm->irq_lock, flags);
3773 bcm43xx_controller_restart(bcm, "TX timeout"); 3775 bcm43xx_controller_restart(bcm, "TX timeout");
3774 bcm43xx_unlock_irqonly(bcm, flags); 3776 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3775} 3777}
3776 3778
3777#ifdef CONFIG_NET_POLL_CONTROLLER 3779#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -3822,6 +3824,7 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
3822 bcm->net_dev = net_dev; 3824 bcm->net_dev = net_dev;
3823 bcm->bad_frames_preempt = modparam_bad_frames_preempt; 3825 bcm->bad_frames_preempt = modparam_bad_frames_preempt;
3824 spin_lock_init(&bcm->irq_lock); 3826 spin_lock_init(&bcm->irq_lock);
3827 spin_lock_init(&bcm->leds_lock);
3825 mutex_init(&bcm->mutex); 3828 mutex_init(&bcm->mutex);
3826 tasklet_init(&bcm->isr_tasklet, 3829 tasklet_init(&bcm->isr_tasklet,
3827 (void (*)(unsigned long))bcm43xx_interrupt_tasklet, 3830 (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
@@ -4002,16 +4005,13 @@ static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
4002{ 4005{
4003 struct net_device *net_dev = pci_get_drvdata(pdev); 4006 struct net_device *net_dev = pci_get_drvdata(pdev);
4004 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 4007 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4005 unsigned long flags;
4006 int try_to_shutdown = 0, err; 4008 int try_to_shutdown = 0, err;
4007 4009
4008 dprintk(KERN_INFO PFX "Suspending...\n"); 4010 dprintk(KERN_INFO PFX "Suspending...\n");
4009 4011
4010 bcm43xx_lock_irqsafe(bcm, flags);
4011 bcm->was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); 4012 bcm->was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
4012 if (bcm->was_initialized) 4013 if (bcm->was_initialized)
4013 try_to_shutdown = 1; 4014 try_to_shutdown = 1;
4014 bcm43xx_unlock_irqsafe(bcm, flags);
4015 4015
4016 netif_device_detach(net_dev); 4016 netif_device_detach(net_dev);
4017 if (try_to_shutdown) { 4017 if (try_to_shutdown) {
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
index 574085c46152..c60c1743ea06 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
@@ -262,7 +262,7 @@ static void tx_tasklet(unsigned long d)
262 int err; 262 int err;
263 u16 txctl; 263 u16 txctl;
264 264
265 bcm43xx_lock_irqonly(bcm, flags); 265 spin_lock_irqsave(&bcm->irq_lock, flags);
266 266
267 if (queue->tx_frozen) 267 if (queue->tx_frozen)
268 goto out_unlock; 268 goto out_unlock;
@@ -300,7 +300,7 @@ static void tx_tasklet(unsigned long d)
300 continue; 300 continue;
301 } 301 }
302out_unlock: 302out_unlock:
303 bcm43xx_unlock_irqonly(bcm, flags); 303 spin_unlock_irqrestore(&bcm->irq_lock, flags);
304} 304}
305 305
306static void setup_txqueues(struct bcm43xx_pioqueue *queue) 306static void setup_txqueues(struct bcm43xx_pioqueue *queue)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
index 6a23bdc75412..cc1ff3c6f140 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
@@ -120,12 +120,14 @@ static ssize_t bcm43xx_attr_sprom_show(struct device *dev,
120 GFP_KERNEL); 120 GFP_KERNEL);
121 if (!sprom) 121 if (!sprom)
122 return -ENOMEM; 122 return -ENOMEM;
123 bcm43xx_lock_irqsafe(bcm, flags); 123 mutex_lock(&bcm->mutex);
124 spin_lock_irqsave(&bcm->irq_lock, flags);
124 err = bcm43xx_sprom_read(bcm, sprom); 125 err = bcm43xx_sprom_read(bcm, sprom);
125 if (!err) 126 if (!err)
126 err = sprom2hex(sprom, buf, PAGE_SIZE); 127 err = sprom2hex(sprom, buf, PAGE_SIZE);
127 mmiowb(); 128 mmiowb();
128 bcm43xx_unlock_irqsafe(bcm, flags); 129 spin_unlock_irqrestore(&bcm->irq_lock, flags);
130 mutex_unlock(&bcm->mutex);
129 kfree(sprom); 131 kfree(sprom);
130 132
131 return err; 133 return err;
@@ -150,10 +152,14 @@ static ssize_t bcm43xx_attr_sprom_store(struct device *dev,
150 err = hex2sprom(sprom, buf, count); 152 err = hex2sprom(sprom, buf, count);
151 if (err) 153 if (err)
152 goto out_kfree; 154 goto out_kfree;
153 bcm43xx_lock_irqsafe(bcm, flags); 155 mutex_lock(&bcm->mutex);
156 spin_lock_irqsave(&bcm->irq_lock, flags);
157 spin_lock(&bcm->leds_lock);
154 err = bcm43xx_sprom_write(bcm, sprom); 158 err = bcm43xx_sprom_write(bcm, sprom);
155 mmiowb(); 159 mmiowb();
156 bcm43xx_unlock_irqsafe(bcm, flags); 160 spin_unlock(&bcm->leds_lock);
161 spin_unlock_irqrestore(&bcm->irq_lock, flags);
162 mutex_unlock(&bcm->mutex);
157out_kfree: 163out_kfree:
158 kfree(sprom); 164 kfree(sprom);
159 165
@@ -176,7 +182,7 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
176 if (!capable(CAP_NET_ADMIN)) 182 if (!capable(CAP_NET_ADMIN))
177 return -EPERM; 183 return -EPERM;
178 184
179 bcm43xx_lock_noirq(bcm); 185 mutex_lock(&bcm->mutex);
180 186
181 switch (bcm43xx_current_radio(bcm)->interfmode) { 187 switch (bcm43xx_current_radio(bcm)->interfmode) {
182 case BCM43xx_RADIO_INTERFMODE_NONE: 188 case BCM43xx_RADIO_INTERFMODE_NONE:
@@ -193,7 +199,7 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
193 } 199 }
194 err = 0; 200 err = 0;
195 201
196 bcm43xx_unlock_noirq(bcm); 202 mutex_unlock(&bcm->mutex);
197 203
198 return err ? err : count; 204 return err ? err : count;
199 205
@@ -229,7 +235,8 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
229 return -EINVAL; 235 return -EINVAL;
230 } 236 }
231 237
232 bcm43xx_lock_irqsafe(bcm, flags); 238 mutex_lock(&bcm->mutex);
239 spin_lock_irqsave(&bcm->irq_lock, flags);
233 240
234 err = bcm43xx_radio_set_interference_mitigation(bcm, mode); 241 err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
235 if (err) { 242 if (err) {
@@ -237,7 +244,8 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
237 "supported by device\n"); 244 "supported by device\n");
238 } 245 }
239 mmiowb(); 246 mmiowb();
240 bcm43xx_unlock_irqsafe(bcm, flags); 247 spin_unlock_irqrestore(&bcm->irq_lock, flags);
248 mutex_unlock(&bcm->mutex);
241 249
242 return err ? err : count; 250 return err ? err : count;
243} 251}
@@ -257,7 +265,7 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
257 if (!capable(CAP_NET_ADMIN)) 265 if (!capable(CAP_NET_ADMIN))
258 return -EPERM; 266 return -EPERM;
259 267
260 bcm43xx_lock_noirq(bcm); 268 mutex_lock(&bcm->mutex);
261 269
262 if (bcm->short_preamble) 270 if (bcm->short_preamble)
263 count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); 271 count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n");
@@ -265,7 +273,7 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
265 count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); 273 count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n");
266 274
267 err = 0; 275 err = 0;
268 bcm43xx_unlock_noirq(bcm); 276 mutex_unlock(&bcm->mutex);
269 277
270 return err ? err : count; 278 return err ? err : count;
271} 279}
@@ -285,12 +293,14 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
285 value = get_boolean(buf, count); 293 value = get_boolean(buf, count);
286 if (value < 0) 294 if (value < 0)
287 return value; 295 return value;
288 bcm43xx_lock_irqsafe(bcm, flags); 296 mutex_lock(&bcm->mutex);
297 spin_lock_irqsave(&bcm->irq_lock, flags);
289 298
290 bcm->short_preamble = !!value; 299 bcm->short_preamble = !!value;
291 300
292 err = 0; 301 err = 0;
293 bcm43xx_unlock_irqsafe(bcm, flags); 302 spin_unlock_irqrestore(&bcm->irq_lock, flags);
303 mutex_unlock(&bcm->mutex);
294 304
295 return err ? err : count; 305 return err ? err : count;
296} 306}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
index 5c36e29efff7..ebe2a8469a78 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -56,12 +56,11 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev,
56{ 56{
57 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 57 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
58 int i; 58 int i;
59 unsigned long flags;
60 struct bcm43xx_phyinfo *phy; 59 struct bcm43xx_phyinfo *phy;
61 char suffix[7] = { 0 }; 60 char suffix[7] = { 0 };
62 int have_a = 0, have_b = 0, have_g = 0; 61 int have_a = 0, have_b = 0, have_g = 0;
63 62
64 bcm43xx_lock_irqsafe(bcm, flags); 63 mutex_lock(&bcm->mutex);
65 for (i = 0; i < bcm->nr_80211_available; i++) { 64 for (i = 0; i < bcm->nr_80211_available; i++) {
66 phy = &(bcm->core_80211_ext[i].phy); 65 phy = &(bcm->core_80211_ext[i].phy);
67 switch (phy->type) { 66 switch (phy->type) {
@@ -77,7 +76,7 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev,
77 assert(0); 76 assert(0);
78 } 77 }
79 } 78 }
80 bcm43xx_unlock_irqsafe(bcm, flags); 79 mutex_unlock(&bcm->mutex);
81 80
82 i = 0; 81 i = 0;
83 if (have_a) { 82 if (have_a) {
@@ -111,7 +110,9 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev,
111 int freq; 110 int freq;
112 int err = -EINVAL; 111 int err = -EINVAL;
113 112
114 bcm43xx_lock_irqsafe(bcm, flags); 113 mutex_lock(&bcm->mutex);
114 spin_lock_irqsave(&bcm->irq_lock, flags);
115
115 if ((data->freq.m >= 0) && (data->freq.m <= 1000)) { 116 if ((data->freq.m >= 0) && (data->freq.m <= 1000)) {
116 channel = data->freq.m; 117 channel = data->freq.m;
117 freq = bcm43xx_channel_to_freq(bcm, channel); 118 freq = bcm43xx_channel_to_freq(bcm, channel);
@@ -131,7 +132,8 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev,
131 err = 0; 132 err = 0;
132 } 133 }
133out_unlock: 134out_unlock:
134 bcm43xx_unlock_irqsafe(bcm, flags); 135 spin_unlock_irqrestore(&bcm->irq_lock, flags);
136 mutex_unlock(&bcm->mutex);
135 137
136 return err; 138 return err;
137} 139}
@@ -143,11 +145,10 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev,
143{ 145{
144 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 146 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
145 struct bcm43xx_radioinfo *radio; 147 struct bcm43xx_radioinfo *radio;
146 unsigned long flags;
147 int err = -ENODEV; 148 int err = -ENODEV;
148 u16 channel; 149 u16 channel;
149 150
150 bcm43xx_lock_irqsafe(bcm, flags); 151 mutex_lock(&bcm->mutex);
151 radio = bcm43xx_current_radio(bcm); 152 radio = bcm43xx_current_radio(bcm);
152 channel = radio->channel; 153 channel = radio->channel;
153 if (channel == 0xFF) { 154 if (channel == 0xFF) {
@@ -162,7 +163,7 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev,
162 163
163 err = 0; 164 err = 0;
164out_unlock: 165out_unlock:
165 bcm43xx_unlock_irqsafe(bcm, flags); 166 mutex_unlock(&bcm->mutex);
166 167
167 return err; 168 return err;
168} 169}
@@ -180,13 +181,15 @@ static int bcm43xx_wx_set_mode(struct net_device *net_dev,
180 if (mode == IW_MODE_AUTO) 181 if (mode == IW_MODE_AUTO)
181 mode = BCM43xx_INITIAL_IWMODE; 182 mode = BCM43xx_INITIAL_IWMODE;
182 183
183 bcm43xx_lock_irqsafe(bcm, flags); 184 mutex_lock(&bcm->mutex);
185 spin_lock_irqsave(&bcm->irq_lock, flags);
184 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { 186 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
185 if (bcm->ieee->iw_mode != mode) 187 if (bcm->ieee->iw_mode != mode)
186 bcm43xx_set_iwmode(bcm, mode); 188 bcm43xx_set_iwmode(bcm, mode);
187 } else 189 } else
188 bcm->ieee->iw_mode = mode; 190 bcm->ieee->iw_mode = mode;
189 bcm43xx_unlock_irqsafe(bcm, flags); 191 spin_unlock_irqrestore(&bcm->irq_lock, flags);
192 mutex_unlock(&bcm->mutex);
190 193
191 return 0; 194 return 0;
192} 195}
@@ -197,11 +200,10 @@ static int bcm43xx_wx_get_mode(struct net_device *net_dev,
197 char *extra) 200 char *extra)
198{ 201{
199 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 202 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
200 unsigned long flags;
201 203
202 bcm43xx_lock_irqsafe(bcm, flags); 204 mutex_lock(&bcm->mutex);
203 data->mode = bcm->ieee->iw_mode; 205 data->mode = bcm->ieee->iw_mode;
204 bcm43xx_unlock_irqsafe(bcm, flags); 206 mutex_unlock(&bcm->mutex);
205 207
206 return 0; 208 return 0;
207} 209}
@@ -214,7 +216,6 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
214 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 216 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
215 struct iw_range *range = (struct iw_range *)extra; 217 struct iw_range *range = (struct iw_range *)extra;
216 const struct ieee80211_geo *geo; 218 const struct ieee80211_geo *geo;
217 unsigned long flags;
218 int i, j; 219 int i, j;
219 struct bcm43xx_phyinfo *phy; 220 struct bcm43xx_phyinfo *phy;
220 221
@@ -254,7 +255,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
254 IW_ENC_CAPA_CIPHER_TKIP | 255 IW_ENC_CAPA_CIPHER_TKIP |
255 IW_ENC_CAPA_CIPHER_CCMP; 256 IW_ENC_CAPA_CIPHER_CCMP;
256 257
257 bcm43xx_lock_irqsafe(bcm, flags); 258 mutex_lock(&bcm->mutex);
258 phy = bcm43xx_current_phy(bcm); 259 phy = bcm43xx_current_phy(bcm);
259 260
260 range->num_bitrates = 0; 261 range->num_bitrates = 0;
@@ -301,7 +302,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
301 } 302 }
302 range->num_frequency = j; 303 range->num_frequency = j;
303 304
304 bcm43xx_unlock_irqsafe(bcm, flags); 305 mutex_unlock(&bcm->mutex);
305 306
306 return 0; 307 return 0;
307} 308}
@@ -314,11 +315,11 @@ static int bcm43xx_wx_set_nick(struct net_device *net_dev,
314 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 315 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
315 size_t len; 316 size_t len;
316 317
317 bcm43xx_lock_noirq(bcm); 318 mutex_lock(&bcm->mutex);
318 len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE); 319 len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE);
319 memcpy(bcm->nick, extra, len); 320 memcpy(bcm->nick, extra, len);
320 bcm->nick[len] = '\0'; 321 bcm->nick[len] = '\0';
321 bcm43xx_unlock_noirq(bcm); 322 mutex_unlock(&bcm->mutex);
322 323
323 return 0; 324 return 0;
324} 325}
@@ -331,12 +332,12 @@ static int bcm43xx_wx_get_nick(struct net_device *net_dev,
331 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 332 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
332 size_t len; 333 size_t len;
333 334
334 bcm43xx_lock_noirq(bcm); 335 mutex_lock(&bcm->mutex);
335 len = strlen(bcm->nick) + 1; 336 len = strlen(bcm->nick) + 1;
336 memcpy(extra, bcm->nick, len); 337 memcpy(extra, bcm->nick, len);
337 data->data.length = (__u16)len; 338 data->data.length = (__u16)len;
338 data->data.flags = 1; 339 data->data.flags = 1;
339 bcm43xx_unlock_noirq(bcm); 340 mutex_unlock(&bcm->mutex);
340 341
341 return 0; 342 return 0;
342} 343}
@@ -350,7 +351,8 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev,
350 unsigned long flags; 351 unsigned long flags;
351 int err = -EINVAL; 352 int err = -EINVAL;
352 353
353 bcm43xx_lock_irqsafe(bcm, flags); 354 mutex_lock(&bcm->mutex);
355 spin_lock_irqsave(&bcm->irq_lock, flags);
354 if (data->rts.disabled) { 356 if (data->rts.disabled) {
355 bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD; 357 bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD;
356 err = 0; 358 err = 0;
@@ -361,7 +363,8 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev,
361 err = 0; 363 err = 0;
362 } 364 }
363 } 365 }
364 bcm43xx_unlock_irqsafe(bcm, flags); 366 spin_unlock_irqrestore(&bcm->irq_lock, flags);
367 mutex_unlock(&bcm->mutex);
365 368
366 return err; 369 return err;
367} 370}
@@ -372,13 +375,12 @@ static int bcm43xx_wx_get_rts(struct net_device *net_dev,
372 char *extra) 375 char *extra)
373{ 376{
374 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 377 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
375 unsigned long flags;
376 378
377 bcm43xx_lock_irqsafe(bcm, flags); 379 mutex_lock(&bcm->mutex);
378 data->rts.value = bcm->rts_threshold; 380 data->rts.value = bcm->rts_threshold;
379 data->rts.fixed = 0; 381 data->rts.fixed = 0;
380 data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD); 382 data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD);
381 bcm43xx_unlock_irqsafe(bcm, flags); 383 mutex_unlock(&bcm->mutex);
382 384
383 return 0; 385 return 0;
384} 386}
@@ -392,7 +394,8 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev,
392 unsigned long flags; 394 unsigned long flags;
393 int err = -EINVAL; 395 int err = -EINVAL;
394 396
395 bcm43xx_lock_irqsafe(bcm, flags); 397 mutex_lock(&bcm->mutex);
398 spin_lock_irqsave(&bcm->irq_lock, flags);
396 if (data->frag.disabled) { 399 if (data->frag.disabled) {
397 bcm->ieee->fts = MAX_FRAG_THRESHOLD; 400 bcm->ieee->fts = MAX_FRAG_THRESHOLD;
398 err = 0; 401 err = 0;
@@ -403,7 +406,8 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev,
403 err = 0; 406 err = 0;
404 } 407 }
405 } 408 }
406 bcm43xx_unlock_irqsafe(bcm, flags); 409 spin_unlock_irqrestore(&bcm->irq_lock, flags);
410 mutex_unlock(&bcm->mutex);
407 411
408 return err; 412 return err;
409} 413}
@@ -414,13 +418,12 @@ static int bcm43xx_wx_get_frag(struct net_device *net_dev,
414 char *extra) 418 char *extra)
415{ 419{
416 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 420 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
417 unsigned long flags;
418 421
419 bcm43xx_lock_irqsafe(bcm, flags); 422 mutex_lock(&bcm->mutex);
420 data->frag.value = bcm->ieee->fts; 423 data->frag.value = bcm->ieee->fts;
421 data->frag.fixed = 0; 424 data->frag.fixed = 0;
422 data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD); 425 data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD);
423 bcm43xx_unlock_irqsafe(bcm, flags); 426 mutex_unlock(&bcm->mutex);
424 427
425 return 0; 428 return 0;
426} 429}
@@ -442,7 +445,8 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev,
442 return -EOPNOTSUPP; 445 return -EOPNOTSUPP;
443 } 446 }
444 447
445 bcm43xx_lock_irqsafe(bcm, flags); 448 mutex_lock(&bcm->mutex);
449 spin_lock_irqsave(&bcm->irq_lock, flags);
446 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) 450 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
447 goto out_unlock; 451 goto out_unlock;
448 radio = bcm43xx_current_radio(bcm); 452 radio = bcm43xx_current_radio(bcm);
@@ -466,7 +470,8 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev,
466 err = 0; 470 err = 0;
467 471
468out_unlock: 472out_unlock:
469 bcm43xx_unlock_irqsafe(bcm, flags); 473 spin_unlock_irqrestore(&bcm->irq_lock, flags);
474 mutex_unlock(&bcm->mutex);
470 475
471 return err; 476 return err;
472} 477}
@@ -478,10 +483,9 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev,
478{ 483{
479 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 484 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
480 struct bcm43xx_radioinfo *radio; 485 struct bcm43xx_radioinfo *radio;
481 unsigned long flags;
482 int err = -ENODEV; 486 int err = -ENODEV;
483 487
484 bcm43xx_lock_irqsafe(bcm, flags); 488 mutex_lock(&bcm->mutex);
485 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) 489 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
486 goto out_unlock; 490 goto out_unlock;
487 radio = bcm43xx_current_radio(bcm); 491 radio = bcm43xx_current_radio(bcm);
@@ -493,7 +497,7 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev,
493 497
494 err = 0; 498 err = 0;
495out_unlock: 499out_unlock:
496 bcm43xx_unlock_irqsafe(bcm, flags); 500 mutex_unlock(&bcm->mutex);
497 501
498 return err; 502 return err;
499} 503}
@@ -580,7 +584,8 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev,
580 return -EINVAL; 584 return -EINVAL;
581 } 585 }
582 586
583 bcm43xx_lock_irqsafe(bcm, flags); 587 mutex_lock(&bcm->mutex);
588 spin_lock_irqsave(&bcm->irq_lock, flags);
584 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { 589 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
585 err = bcm43xx_radio_set_interference_mitigation(bcm, mode); 590 err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
586 if (err) { 591 if (err) {
@@ -595,7 +600,8 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev,
595 } else 600 } else
596 bcm43xx_current_radio(bcm)->interfmode = mode; 601 bcm43xx_current_radio(bcm)->interfmode = mode;
597 } 602 }
598 bcm43xx_unlock_irqsafe(bcm, flags); 603 spin_unlock_irqrestore(&bcm->irq_lock, flags);
604 mutex_unlock(&bcm->mutex);
599 605
600 return err; 606 return err;
601} 607}
@@ -606,12 +612,11 @@ static int bcm43xx_wx_get_interfmode(struct net_device *net_dev,
606 char *extra) 612 char *extra)
607{ 613{
608 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 614 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
609 unsigned long flags;
610 int mode; 615 int mode;
611 616
612 bcm43xx_lock_irqsafe(bcm, flags); 617 mutex_lock(&bcm->mutex);
613 mode = bcm43xx_current_radio(bcm)->interfmode; 618 mode = bcm43xx_current_radio(bcm)->interfmode;
614 bcm43xx_unlock_irqsafe(bcm, flags); 619 mutex_unlock(&bcm->mutex);
615 620
616 switch (mode) { 621 switch (mode) {
617 case BCM43xx_RADIO_INTERFMODE_NONE: 622 case BCM43xx_RADIO_INTERFMODE_NONE:
@@ -641,9 +646,11 @@ static int bcm43xx_wx_set_shortpreamble(struct net_device *net_dev,
641 int on; 646 int on;
642 647
643 on = *((int *)extra); 648 on = *((int *)extra);
644 bcm43xx_lock_irqsafe(bcm, flags); 649 mutex_lock(&bcm->mutex);
650 spin_lock_irqsave(&bcm->irq_lock, flags);
645 bcm->short_preamble = !!on; 651 bcm->short_preamble = !!on;
646 bcm43xx_unlock_irqsafe(bcm, flags); 652 spin_unlock_irqrestore(&bcm->irq_lock, flags);
653 mutex_unlock(&bcm->mutex);
647 654
648 return 0; 655 return 0;
649} 656}
@@ -654,12 +661,11 @@ static int bcm43xx_wx_get_shortpreamble(struct net_device *net_dev,
654 char *extra) 661 char *extra)
655{ 662{
656 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 663 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
657 unsigned long flags;
658 int on; 664 int on;
659 665
660 bcm43xx_lock_irqsafe(bcm, flags); 666 mutex_lock(&bcm->mutex);
661 on = bcm->short_preamble; 667 on = bcm->short_preamble;
662 bcm43xx_unlock_irqsafe(bcm, flags); 668 mutex_unlock(&bcm->mutex);
663 669
664 if (on) 670 if (on)
665 strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING); 671 strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING);
@@ -681,11 +687,13 @@ static int bcm43xx_wx_set_swencryption(struct net_device *net_dev,
681 687
682 on = *((int *)extra); 688 on = *((int *)extra);
683 689
684 bcm43xx_lock_irqsafe(bcm, flags); 690 mutex_lock(&bcm->mutex);
691 spin_lock_irqsave(&bcm->irq_lock, flags);
685 bcm->ieee->host_encrypt = !!on; 692 bcm->ieee->host_encrypt = !!on;
686 bcm->ieee->host_decrypt = !!on; 693 bcm->ieee->host_decrypt = !!on;
687 bcm->ieee->host_build_iv = !on; 694 bcm->ieee->host_build_iv = !on;
688 bcm43xx_unlock_irqsafe(bcm, flags); 695 spin_unlock_irqrestore(&bcm->irq_lock, flags);
696 mutex_unlock(&bcm->mutex);
689 697
690 return 0; 698 return 0;
691} 699}
@@ -696,12 +704,11 @@ static int bcm43xx_wx_get_swencryption(struct net_device *net_dev,
696 char *extra) 704 char *extra)
697{ 705{
698 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 706 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
699 unsigned long flags;
700 int on; 707 int on;
701 708
702 bcm43xx_lock_irqsafe(bcm, flags); 709 mutex_lock(&bcm->mutex);
703 on = bcm->ieee->host_encrypt; 710 on = bcm->ieee->host_encrypt;
704 bcm43xx_unlock_irqsafe(bcm, flags); 711 mutex_unlock(&bcm->mutex);
705 712
706 if (on) 713 if (on)
707 strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING); 714 strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING);
@@ -764,11 +771,13 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev,
764 if (!sprom) 771 if (!sprom)
765 goto out; 772 goto out;
766 773
767 bcm43xx_lock_irqsafe(bcm, flags); 774 mutex_lock(&bcm->mutex);
775 spin_lock_irqsave(&bcm->irq_lock, flags);
768 err = -ENODEV; 776 err = -ENODEV;
769 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) 777 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
770 err = bcm43xx_sprom_read(bcm, sprom); 778 err = bcm43xx_sprom_read(bcm, sprom);
771 bcm43xx_unlock_irqsafe(bcm, flags); 779 spin_unlock_irqrestore(&bcm->irq_lock, flags);
780 mutex_unlock(&bcm->mutex);
772 if (!err) 781 if (!err)
773 data->data.length = sprom2hex(sprom, extra); 782 data->data.length = sprom2hex(sprom, extra);
774 kfree(sprom); 783 kfree(sprom);
@@ -809,11 +818,15 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev,
809 if (err) 818 if (err)
810 goto out_kfree; 819 goto out_kfree;
811 820
812 bcm43xx_lock_irqsafe(bcm, flags); 821 mutex_lock(&bcm->mutex);
822 spin_lock_irqsave(&bcm->irq_lock, flags);
823 spin_lock(&bcm->leds_lock);
813 err = -ENODEV; 824 err = -ENODEV;
814 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) 825 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
815 err = bcm43xx_sprom_write(bcm, sprom); 826 err = bcm43xx_sprom_write(bcm, sprom);
816 bcm43xx_unlock_irqsafe(bcm, flags); 827 spin_unlock(&bcm->leds_lock);
828 spin_unlock_irqrestore(&bcm->irq_lock, flags);
829 mutex_unlock(&bcm->mutex);
817out_kfree: 830out_kfree:
818 kfree(sprom); 831 kfree(sprom);
819out: 832out: