diff options
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.c | 49 |
2 files changed, 33 insertions, 18 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index ee6571ed706d..bee84b58060c 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h | |||
@@ -737,6 +737,8 @@ struct bcm43xx_private { | |||
737 | u32 irq_savedstate; | 737 | u32 irq_savedstate; |
738 | /* Link Quality calculation context. */ | 738 | /* Link Quality calculation context. */ |
739 | struct bcm43xx_noise_calculation noisecalc; | 739 | struct bcm43xx_noise_calculation noisecalc; |
740 | /* if > 0 MAC is suspended. if == 0 MAC is enabled. */ | ||
741 | int mac_suspended; | ||
740 | 742 | ||
741 | /* Threshold values. */ | 743 | /* Threshold values. */ |
742 | //TODO: The RTS thr has to be _used_. Currently, it is only set via WX. | 744 | //TODO: The RTS thr has to be _used_. Currently, it is only set via WX. |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index ab3a0ee9fac8..1af330d496fc 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -2298,13 +2298,17 @@ static int bcm43xx_gpio_cleanup(struct bcm43xx_private *bcm) | |||
2298 | /* http://bcm-specs.sipsolutions.net/EnableMac */ | 2298 | /* http://bcm-specs.sipsolutions.net/EnableMac */ |
2299 | void bcm43xx_mac_enable(struct bcm43xx_private *bcm) | 2299 | void bcm43xx_mac_enable(struct bcm43xx_private *bcm) |
2300 | { | 2300 | { |
2301 | bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, | 2301 | bcm->mac_suspended--; |
2302 | bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) | 2302 | assert(bcm->mac_suspended >= 0); |
2303 | | BCM43xx_SBF_MAC_ENABLED); | 2303 | if (bcm->mac_suspended == 0) { |
2304 | bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY); | 2304 | bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, |
2305 | bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ | 2305 | bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) |
2306 | bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */ | 2306 | | BCM43xx_SBF_MAC_ENABLED); |
2307 | bcm43xx_power_saving_ctl_bits(bcm, -1, -1); | 2307 | bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY); |
2308 | bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ | ||
2309 | bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */ | ||
2310 | bcm43xx_power_saving_ctl_bits(bcm, -1, -1); | ||
2311 | } | ||
2308 | } | 2312 | } |
2309 | 2313 | ||
2310 | /* http://bcm-specs.sipsolutions.net/SuspendMAC */ | 2314 | /* http://bcm-specs.sipsolutions.net/SuspendMAC */ |
@@ -2313,18 +2317,23 @@ void bcm43xx_mac_suspend(struct bcm43xx_private *bcm) | |||
2313 | int i; | 2317 | int i; |
2314 | u32 tmp; | 2318 | u32 tmp; |
2315 | 2319 | ||
2316 | bcm43xx_power_saving_ctl_bits(bcm, -1, 1); | 2320 | assert(bcm->mac_suspended >= 0); |
2317 | bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, | 2321 | if (bcm->mac_suspended == 0) { |
2318 | bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) | 2322 | bcm43xx_power_saving_ctl_bits(bcm, -1, 1); |
2319 | & ~BCM43xx_SBF_MAC_ENABLED); | 2323 | bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, |
2320 | bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */ | 2324 | bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) |
2321 | for (i = 100000; i; i--) { | 2325 | & ~BCM43xx_SBF_MAC_ENABLED); |
2322 | tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); | 2326 | bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */ |
2323 | if (tmp & BCM43xx_IRQ_READY) | 2327 | for (i = 100000; i; i--) { |
2324 | return; | 2328 | tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); |
2325 | udelay(10); | 2329 | if (tmp & BCM43xx_IRQ_READY) |
2330 | goto out; | ||
2331 | udelay(10); | ||
2332 | } | ||
2333 | printkl(KERN_ERR PFX "MAC suspend failed\n"); | ||
2326 | } | 2334 | } |
2327 | printkl(KERN_ERR PFX "MAC suspend failed\n"); | 2335 | out: |
2336 | bcm->mac_suspended++; | ||
2328 | } | 2337 | } |
2329 | 2338 | ||
2330 | void bcm43xx_set_iwmode(struct bcm43xx_private *bcm, | 2339 | void bcm43xx_set_iwmode(struct bcm43xx_private *bcm, |
@@ -3183,7 +3192,9 @@ static void bcm43xx_periodic_work_handler(void *d) | |||
3183 | * be preemtible. | 3192 | * be preemtible. |
3184 | */ | 3193 | */ |
3185 | netif_stop_queue(bcm->net_dev); | 3194 | netif_stop_queue(bcm->net_dev); |
3195 | synchronize_net(); | ||
3186 | spin_lock_irqsave(&bcm->irq_lock, flags); | 3196 | spin_lock_irqsave(&bcm->irq_lock, flags); |
3197 | bcm43xx_mac_suspend(bcm); | ||
3187 | if (bcm43xx_using_pio(bcm)) | 3198 | if (bcm43xx_using_pio(bcm)) |
3188 | bcm43xx_pio_freeze_txqueues(bcm); | 3199 | bcm43xx_pio_freeze_txqueues(bcm); |
3189 | savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); | 3200 | savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); |
@@ -3207,6 +3218,7 @@ static void bcm43xx_periodic_work_handler(void *d) | |||
3207 | bcm43xx_interrupt_enable(bcm, savedirqs); | 3218 | bcm43xx_interrupt_enable(bcm, savedirqs); |
3208 | if (bcm43xx_using_pio(bcm)) | 3219 | if (bcm43xx_using_pio(bcm)) |
3209 | bcm43xx_pio_thaw_txqueues(bcm); | 3220 | bcm43xx_pio_thaw_txqueues(bcm); |
3221 | bcm43xx_mac_enable(bcm); | ||
3210 | } | 3222 | } |
3211 | netif_wake_queue(bcm->net_dev); | 3223 | netif_wake_queue(bcm->net_dev); |
3212 | } | 3224 | } |
@@ -3820,6 +3832,7 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, | |||
3820 | bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan; | 3832 | bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan; |
3821 | 3833 | ||
3822 | bcm->irq_savedstate = BCM43xx_IRQ_INITIAL; | 3834 | bcm->irq_savedstate = BCM43xx_IRQ_INITIAL; |
3835 | bcm->mac_suspended = 1; | ||
3823 | bcm->pci_dev = pci_dev; | 3836 | bcm->pci_dev = pci_dev; |
3824 | bcm->net_dev = net_dev; | 3837 | bcm->net_dev = net_dev; |
3825 | bcm->bad_frames_preempt = modparam_bad_frames_preempt; | 3838 | bcm->bad_frames_preempt = modparam_bad_frames_preempt; |