|
@@ -3163,9 +3163,11 @@ static int estimate_periodic_work_badness(unsigned int state)
|
|
static void bcm43xx_periodic_work_handler(void *d)
|
|
static void bcm43xx_periodic_work_handler(void *d)
|
|
{
|
|
{
|
|
struct bcm43xx_private *bcm = d;
|
|
struct bcm43xx_private *bcm = d;
|
|
|
|
+ struct net_device *net_dev = bcm->net_dev;
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
u32 savedirqs = 0;
|
|
u32 savedirqs = 0;
|
|
int badness;
|
|
int badness;
|
|
|
|
+ unsigned long orig_trans_start = 0;
|
|
|
|
|
|
mutex_lock(&bcm->mutex);
|
|
mutex_lock(&bcm->mutex);
|
|
badness = estimate_periodic_work_badness(bcm->periodic_state);
|
|
badness = estimate_periodic_work_badness(bcm->periodic_state);
|
|
@@ -3173,7 +3175,18 @@ static void bcm43xx_periodic_work_handler(void *d)
|
|
/* Periodic work will take a long time, so we want it to
|
|
/* Periodic work will take a long time, so we want it to
|
|
* be preemtible.
|
|
* be preemtible.
|
|
*/
|
|
*/
|
|
- netif_tx_disable(bcm->net_dev);
|
|
|
|
|
|
+
|
|
|
|
+ netif_tx_lock_bh(net_dev);
|
|
|
|
+ /* We must fake a started transmission here, as we are going to
|
|
|
|
+ * disable TX. If we wouldn't fake a TX, it would be possible to
|
|
|
|
+ * trigger the netdev watchdog, if the last real TX is already
|
|
|
|
+ * some time on the past (slightly less than 5secs)
|
|
|
|
+ */
|
|
|
|
+ orig_trans_start = net_dev->trans_start;
|
|
|
|
+ net_dev->trans_start = jiffies;
|
|
|
|
+ netif_stop_queue(net_dev);
|
|
|
|
+ netif_tx_unlock_bh(net_dev);
|
|
|
|
+
|
|
spin_lock_irqsave(&bcm->irq_lock, flags);
|
|
spin_lock_irqsave(&bcm->irq_lock, flags);
|
|
bcm43xx_mac_suspend(bcm);
|
|
bcm43xx_mac_suspend(bcm);
|
|
if (bcm43xx_using_pio(bcm))
|
|
if (bcm43xx_using_pio(bcm))
|
|
@@ -3198,6 +3211,7 @@ static void bcm43xx_periodic_work_handler(void *d)
|
|
bcm43xx_pio_thaw_txqueues(bcm);
|
|
bcm43xx_pio_thaw_txqueues(bcm);
|
|
bcm43xx_mac_enable(bcm);
|
|
bcm43xx_mac_enable(bcm);
|
|
netif_wake_queue(bcm->net_dev);
|
|
netif_wake_queue(bcm->net_dev);
|
|
|
|
+ net_dev->trans_start = orig_trans_start;
|
|
}
|
|
}
|
|
mmiowb();
|
|
mmiowb();
|
|
spin_unlock_irqrestore(&bcm->irq_lock, flags);
|
|
spin_unlock_irqrestore(&bcm->irq_lock, flags);
|