aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h2
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c49
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 */
2299void bcm43xx_mac_enable(struct bcm43xx_private *bcm) 2299void 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"); 2335out:
2336 bcm->mac_suspended++;
2328} 2337}
2329 2338
2330void bcm43xx_set_iwmode(struct bcm43xx_private *bcm, 2339void 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;