[PATCH] bcm43xx: preemptible periodic work
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / bcm43xx / bcm43xx_pio.c
index e77e9d859f875a90aaefea5892ded253121a1d39..574085c461526927d97a1b896f2dbbb2f4df8b8e 100644 (file)
@@ -264,6 +264,8 @@ static void tx_tasklet(unsigned long d)
 
        bcm43xx_lock_irqonly(bcm, flags);
 
+       if (queue->tx_frozen)
+               goto out_unlock;
        txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL);
        if (txctl & BCM43xx_PIO_TXCTL_SUSPEND)
                goto out_unlock;
@@ -633,5 +635,40 @@ void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue)
                          bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL)
                          & ~BCM43xx_PIO_TXCTL_SUSPEND);
        bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1);
-       tasklet_schedule(&queue->txtask);
+       if (!list_empty(&queue->txqueue))
+               tasklet_schedule(&queue->txtask);
+}
+
+void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm)
+{
+       struct bcm43xx_pio *pio;
+
+       assert(bcm43xx_using_pio(bcm));
+       pio = bcm43xx_current_pio(bcm);
+       pio->queue0->tx_frozen = 1;
+       pio->queue1->tx_frozen = 1;
+       pio->queue2->tx_frozen = 1;
+       pio->queue3->tx_frozen = 1;
 }
+
+void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm)
+{
+       struct bcm43xx_pio *pio;
+
+       assert(bcm43xx_using_pio(bcm));
+       pio = bcm43xx_current_pio(bcm);
+       pio->queue0->tx_frozen = 0;
+       pio->queue1->tx_frozen = 0;
+       pio->queue2->tx_frozen = 0;
+       pio->queue3->tx_frozen = 0;
+       if (!list_empty(&pio->queue0->txqueue))
+               tasklet_schedule(&pio->queue0->txtask);
+       if (!list_empty(&pio->queue1->txqueue))
+               tasklet_schedule(&pio->queue1->txtask);
+       if (!list_empty(&pio->queue2->txqueue))
+               tasklet_schedule(&pio->queue2->txtask);
+       if (!list_empty(&pio->queue3->txqueue))
+               tasklet_schedule(&pio->queue3->txtask);
+}
+
+