diff options
Diffstat (limited to 'drivers/net/wireless/bcm43xx/bcm43xx_main.c')
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.c | 75 |
1 files changed, 40 insertions, 35 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 6da0beb0a933..b7192559833c 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -482,14 +482,14 @@ static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *old | |||
482 | u32 old; | 482 | u32 old; |
483 | unsigned long flags; | 483 | unsigned long flags; |
484 | 484 | ||
485 | spin_lock_irqsave(&bcm->lock, flags); | 485 | bcm43xx_lock_mmio(bcm, flags); |
486 | if (bcm43xx_is_initializing(bcm) || bcm->shutting_down) { | 486 | if (bcm43xx_is_initializing(bcm) || bcm->shutting_down) { |
487 | spin_unlock_irqrestore(&bcm->lock, flags); | 487 | bcm43xx_unlock_mmio(bcm, flags); |
488 | return -EBUSY; | 488 | return -EBUSY; |
489 | } | 489 | } |
490 | old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); | 490 | old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); |
491 | tasklet_disable(&bcm->isr_tasklet); | 491 | tasklet_disable(&bcm->isr_tasklet); |
492 | spin_unlock_irqrestore(&bcm->lock, flags); | 492 | bcm43xx_unlock_mmio(bcm, flags); |
493 | if (oldstate) | 493 | if (oldstate) |
494 | *oldstate = old; | 494 | *oldstate = old; |
495 | 495 | ||
@@ -746,6 +746,7 @@ int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom) | |||
746 | else if (i % 2) | 746 | else if (i % 2) |
747 | printk("."); | 747 | printk("."); |
748 | bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]); | 748 | bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]); |
749 | mmiowb(); | ||
749 | mdelay(20); | 750 | mdelay(20); |
750 | } | 751 | } |
751 | spromctl &= ~0x10; /* SPROM WRITE enable. */ | 752 | spromctl &= ~0x10; /* SPROM WRITE enable. */ |
@@ -1676,7 +1677,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) | |||
1676 | # define bcmirq_handled(irq) do { /* nothing */ } while (0) | 1677 | # define bcmirq_handled(irq) do { /* nothing */ } while (0) |
1677 | #endif /* CONFIG_BCM43XX_DEBUG*/ | 1678 | #endif /* CONFIG_BCM43XX_DEBUG*/ |
1678 | 1679 | ||
1679 | spin_lock_irqsave(&bcm->lock, flags); | 1680 | bcm43xx_lock_mmio(bcm, flags); |
1680 | reason = bcm->irq_reason; | 1681 | reason = bcm->irq_reason; |
1681 | dma_reason[0] = bcm->dma_reason[0]; | 1682 | dma_reason[0] = bcm->dma_reason[0]; |
1682 | dma_reason[1] = bcm->dma_reason[1]; | 1683 | dma_reason[1] = bcm->dma_reason[1]; |
@@ -1776,7 +1777,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) | |||
1776 | if (!modparam_noleds) | 1777 | if (!modparam_noleds) |
1777 | bcm43xx_leds_update(bcm, activity); | 1778 | bcm43xx_leds_update(bcm, activity); |
1778 | bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); | 1779 | bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); |
1779 | spin_unlock_irqrestore(&bcm->lock, flags); | 1780 | bcm43xx_unlock_mmio(bcm, flags); |
1780 | } | 1781 | } |
1781 | 1782 | ||
1782 | #undef bcmirq_print_reasons | 1783 | #undef bcmirq_print_reasons |
@@ -1830,25 +1831,24 @@ static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, | |||
1830 | /* Interrupt handler top-half */ | 1831 | /* Interrupt handler top-half */ |
1831 | static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs) | 1832 | static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs) |
1832 | { | 1833 | { |
1834 | irqreturn_t ret = IRQ_HANDLED; | ||
1833 | struct bcm43xx_private *bcm = dev_id; | 1835 | struct bcm43xx_private *bcm = dev_id; |
1834 | u32 reason, mask; | 1836 | u32 reason, mask; |
1835 | 1837 | ||
1836 | if (!bcm) | 1838 | if (!bcm) |
1837 | return IRQ_NONE; | 1839 | return IRQ_NONE; |
1838 | 1840 | ||
1839 | spin_lock(&bcm->lock); | 1841 | spin_lock(&bcm->_lock); |
1840 | 1842 | ||
1841 | reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); | 1843 | reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); |
1842 | if (reason == 0xffffffff) { | 1844 | if (reason == 0xffffffff) { |
1843 | /* irq not for us (shared irq) */ | 1845 | /* irq not for us (shared irq) */ |
1844 | spin_unlock(&bcm->lock); | 1846 | ret = IRQ_NONE; |
1845 | return IRQ_NONE; | 1847 | goto out; |
1846 | } | 1848 | } |
1847 | mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); | 1849 | mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); |
1848 | if (!(reason & mask)) { | 1850 | if (!(reason & mask)) |
1849 | spin_unlock(&bcm->lock); | 1851 | goto out; |
1850 | return IRQ_HANDLED; | ||
1851 | } | ||
1852 | 1852 | ||
1853 | bcm43xx_interrupt_ack(bcm, reason, mask); | 1853 | bcm43xx_interrupt_ack(bcm, reason, mask); |
1854 | 1854 | ||
@@ -1866,9 +1866,11 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re | |||
1866 | tasklet_schedule(&bcm->isr_tasklet); | 1866 | tasklet_schedule(&bcm->isr_tasklet); |
1867 | } | 1867 | } |
1868 | 1868 | ||
1869 | spin_unlock(&bcm->lock); | 1869 | out: |
1870 | mmiowb(); | ||
1871 | spin_unlock(&bcm->_lock); | ||
1870 | 1872 | ||
1871 | return IRQ_HANDLED; | 1873 | return ret; |
1872 | } | 1874 | } |
1873 | 1875 | ||
1874 | static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force) | 1876 | static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force) |
@@ -3112,7 +3114,7 @@ static void bcm43xx_periodic_task_handler(unsigned long d) | |||
3112 | unsigned long flags; | 3114 | unsigned long flags; |
3113 | unsigned int state; | 3115 | unsigned int state; |
3114 | 3116 | ||
3115 | spin_lock_irqsave(&bcm->lock, flags); | 3117 | bcm43xx_lock_mmio(bcm, flags); |
3116 | 3118 | ||
3117 | assert(bcm->initialized); | 3119 | assert(bcm->initialized); |
3118 | state = bcm->periodic_state; | 3120 | state = bcm->periodic_state; |
@@ -3127,7 +3129,7 @@ static void bcm43xx_periodic_task_handler(unsigned long d) | |||
3127 | 3129 | ||
3128 | mod_timer(&bcm->periodic_tasks, jiffies + (HZ * 15)); | 3130 | mod_timer(&bcm->periodic_tasks, jiffies + (HZ * 15)); |
3129 | 3131 | ||
3130 | spin_unlock_irqrestore(&bcm->lock, flags); | 3132 | bcm43xx_unlock_mmio(bcm, flags); |
3131 | } | 3133 | } |
3132 | 3134 | ||
3133 | static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) | 3135 | static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) |
@@ -3164,10 +3166,10 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm) | |||
3164 | 3166 | ||
3165 | bcm43xx_periodic_tasks_delete(bcm); | 3167 | bcm43xx_periodic_tasks_delete(bcm); |
3166 | 3168 | ||
3167 | spin_lock_irqsave(&bcm->lock, flags); | 3169 | bcm43xx_lock(bcm, flags); |
3168 | bcm->initialized = 0; | 3170 | bcm->initialized = 0; |
3169 | bcm->shutting_down = 1; | 3171 | bcm->shutting_down = 1; |
3170 | spin_unlock_irqrestore(&bcm->lock, flags); | 3172 | bcm43xx_unlock(bcm, flags); |
3171 | 3173 | ||
3172 | for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { | 3174 | for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { |
3173 | if (!(bcm->core_80211[i].flags & BCM43xx_COREFLAG_AVAILABLE)) | 3175 | if (!(bcm->core_80211[i].flags & BCM43xx_COREFLAG_AVAILABLE)) |
@@ -3182,9 +3184,9 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm) | |||
3182 | 3184 | ||
3183 | bcm43xx_pctl_set_crystal(bcm, 0); | 3185 | bcm43xx_pctl_set_crystal(bcm, 0); |
3184 | 3186 | ||
3185 | spin_lock_irqsave(&bcm->lock, flags); | 3187 | bcm43xx_lock(bcm, flags); |
3186 | bcm->shutting_down = 0; | 3188 | bcm->shutting_down = 0; |
3187 | spin_unlock_irqrestore(&bcm->lock, flags); | 3189 | bcm43xx_unlock(bcm, flags); |
3188 | } | 3190 | } |
3189 | 3191 | ||
3190 | static int bcm43xx_init_board(struct bcm43xx_private *bcm) | 3192 | static int bcm43xx_init_board(struct bcm43xx_private *bcm) |
@@ -3196,10 +3198,10 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) | |||
3196 | 3198 | ||
3197 | might_sleep(); | 3199 | might_sleep(); |
3198 | 3200 | ||
3199 | spin_lock_irqsave(&bcm->lock, flags); | 3201 | bcm43xx_lock(bcm, flags); |
3200 | bcm->initialized = 0; | 3202 | bcm->initialized = 0; |
3201 | bcm->shutting_down = 0; | 3203 | bcm->shutting_down = 0; |
3202 | spin_unlock_irqrestore(&bcm->lock, flags); | 3204 | bcm43xx_unlock(bcm, flags); |
3203 | 3205 | ||
3204 | err = bcm43xx_pctl_set_crystal(bcm, 1); | 3206 | err = bcm43xx_pctl_set_crystal(bcm, 1); |
3205 | if (err) | 3207 | if (err) |
@@ -3267,9 +3269,9 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) | |||
3267 | } | 3269 | } |
3268 | 3270 | ||
3269 | /* Initialization of the board is done. Flag it as such. */ | 3271 | /* Initialization of the board is done. Flag it as such. */ |
3270 | spin_lock_irqsave(&bcm->lock, flags); | 3272 | bcm43xx_lock(bcm, flags); |
3271 | bcm->initialized = 1; | 3273 | bcm->initialized = 1; |
3272 | spin_unlock_irqrestore(&bcm->lock, flags); | 3274 | bcm43xx_unlock(bcm, flags); |
3273 | 3275 | ||
3274 | bcm43xx_periodic_tasks_setup(bcm); | 3276 | bcm43xx_periodic_tasks_setup(bcm); |
3275 | bcm43xx_sysfs_register(bcm); | 3277 | bcm43xx_sysfs_register(bcm); |
@@ -3570,11 +3572,11 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, | |||
3570 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 3572 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
3571 | unsigned long flags; | 3573 | unsigned long flags; |
3572 | 3574 | ||
3573 | spin_lock_irqsave(&bcm->lock, flags); | 3575 | bcm43xx_lock_mmio(bcm, flags); |
3574 | bcm43xx_mac_suspend(bcm); | 3576 | bcm43xx_mac_suspend(bcm); |
3575 | bcm43xx_radio_selectchannel(bcm, channel, 0); | 3577 | bcm43xx_radio_selectchannel(bcm, channel, 0); |
3576 | bcm43xx_mac_enable(bcm); | 3578 | bcm43xx_mac_enable(bcm); |
3577 | spin_unlock_irqrestore(&bcm->lock, flags); | 3579 | bcm43xx_unlock_mmio(bcm, flags); |
3578 | } | 3580 | } |
3579 | 3581 | ||
3580 | /* set_security() callback in struct ieee80211_device */ | 3582 | /* set_security() callback in struct ieee80211_device */ |
@@ -3587,9 +3589,9 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, | |||
3587 | int keyidx; | 3589 | int keyidx; |
3588 | 3590 | ||
3589 | dprintk(KERN_INFO PFX "set security called\n"); | 3591 | dprintk(KERN_INFO PFX "set security called\n"); |
3590 | 3592 | ||
3591 | spin_lock_irqsave(&bcm->lock, flags); | 3593 | bcm43xx_lock_mmio(bcm, flags); |
3592 | 3594 | ||
3593 | for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) | 3595 | for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) |
3594 | if (sec->flags & (1<<keyidx)) { | 3596 | if (sec->flags & (1<<keyidx)) { |
3595 | secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx]; | 3597 | secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx]; |
@@ -3651,7 +3653,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, | |||
3651 | } else | 3653 | } else |
3652 | bcm43xx_clear_keys(bcm); | 3654 | bcm43xx_clear_keys(bcm); |
3653 | } | 3655 | } |
3654 | spin_unlock_irqrestore(&bcm->lock, flags); | 3656 | bcm43xx_unlock_mmio(bcm, flags); |
3655 | } | 3657 | } |
3656 | 3658 | ||
3657 | /* hard_start_xmit() callback in struct ieee80211_device */ | 3659 | /* hard_start_xmit() callback in struct ieee80211_device */ |
@@ -3663,10 +3665,10 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb, | |||
3663 | int err = -ENODEV; | 3665 | int err = -ENODEV; |
3664 | unsigned long flags; | 3666 | unsigned long flags; |
3665 | 3667 | ||
3666 | spin_lock_irqsave(&bcm->lock, flags); | 3668 | bcm43xx_lock_mmio(bcm, flags); |
3667 | if (likely(bcm->initialized)) | 3669 | if (likely(bcm->initialized)) |
3668 | err = bcm43xx_tx(bcm, txb); | 3670 | err = bcm43xx_tx(bcm, txb); |
3669 | spin_unlock_irqrestore(&bcm->lock, flags); | 3671 | bcm43xx_unlock_mmio(bcm, flags); |
3670 | 3672 | ||
3671 | return err; | 3673 | return err; |
3672 | } | 3674 | } |
@@ -3679,8 +3681,11 @@ static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_de | |||
3679 | static void bcm43xx_net_tx_timeout(struct net_device *net_dev) | 3681 | static void bcm43xx_net_tx_timeout(struct net_device *net_dev) |
3680 | { | 3682 | { |
3681 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 3683 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
3684 | unsigned long flags; | ||
3682 | 3685 | ||
3686 | bcm43xx_lock_mmio(bcm, flags); | ||
3683 | bcm43xx_controller_restart(bcm, "TX timeout"); | 3687 | bcm43xx_controller_restart(bcm, "TX timeout"); |
3688 | bcm43xx_unlock_mmio(bcm, flags); | ||
3684 | } | 3689 | } |
3685 | 3690 | ||
3686 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3691 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -3738,7 +3743,7 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, | |||
3738 | bcm->pci_dev = pci_dev; | 3743 | bcm->pci_dev = pci_dev; |
3739 | bcm->net_dev = net_dev; | 3744 | bcm->net_dev = net_dev; |
3740 | bcm->bad_frames_preempt = modparam_bad_frames_preempt; | 3745 | bcm->bad_frames_preempt = modparam_bad_frames_preempt; |
3741 | spin_lock_init(&bcm->lock); | 3746 | spin_lock_init(&bcm->_lock); |
3742 | tasklet_init(&bcm->isr_tasklet, | 3747 | tasklet_init(&bcm->isr_tasklet, |
3743 | (void (*)(unsigned long))bcm43xx_interrupt_tasklet, | 3748 | (void (*)(unsigned long))bcm43xx_interrupt_tasklet, |
3744 | (unsigned long)bcm); | 3749 | (unsigned long)bcm); |
@@ -3921,11 +3926,11 @@ static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3921 | 3926 | ||
3922 | dprintk(KERN_INFO PFX "Suspending...\n"); | 3927 | dprintk(KERN_INFO PFX "Suspending...\n"); |
3923 | 3928 | ||
3924 | spin_lock_irqsave(&bcm->lock, flags); | 3929 | bcm43xx_lock(bcm, flags); |
3925 | bcm->was_initialized = bcm->initialized; | 3930 | bcm->was_initialized = bcm->initialized; |
3926 | if (bcm->initialized) | 3931 | if (bcm->initialized) |
3927 | try_to_shutdown = 1; | 3932 | try_to_shutdown = 1; |
3928 | spin_unlock_irqrestore(&bcm->lock, flags); | 3933 | bcm43xx_unlock(bcm, flags); |
3929 | 3934 | ||
3930 | netif_device_detach(net_dev); | 3935 | netif_device_detach(net_dev); |
3931 | if (try_to_shutdown) { | 3936 | if (try_to_shutdown) { |