b43: Remove unnecessary MMIO accesses in the interrupt hotpath.
SVN-Revision: 15160
This commit is contained in:
parent
908e5f64bf
commit
efceb0938c
1 changed files with 177 additions and 0 deletions
177
package/mac80211/patches/530-b43-optimize-hotpath-mmio.patch
Normal file
177
package/mac80211/patches/530-b43-optimize-hotpath-mmio.patch
Normal file
|
@ -0,0 +1,177 @@
|
|||
Index: compat-wireless-2009-03-31/drivers/net/wireless/b43/b43.h
|
||||
===================================================================
|
||||
--- compat-wireless-2009-03-31.orig/drivers/net/wireless/b43/b43.h 2009-04-08 20:27:37.000000000 +0200
|
||||
+++ compat-wireless-2009-03-31/drivers/net/wireless/b43/b43.h 2009-04-08 20:28:14.000000000 +0200
|
||||
@@ -778,8 +778,8 @@ struct b43_wldev {
|
||||
/* Reason code of the last interrupt. */
|
||||
u32 irq_reason;
|
||||
u32 dma_reason[6];
|
||||
- /* saved irq enable/disable state bitfield. */
|
||||
- u32 irq_savedstate;
|
||||
+ /* The currently active generic-interrupt mask. */
|
||||
+ u32 irq_mask;
|
||||
/* Link Quality calculation context. */
|
||||
struct b43_noise_calculation noisecalc;
|
||||
/* if > 0 MAC is suspended. if == 0 MAC is enabled. */
|
||||
Index: compat-wireless-2009-03-31/drivers/net/wireless/b43/main.c
|
||||
===================================================================
|
||||
--- compat-wireless-2009-03-31.orig/drivers/net/wireless/b43/main.c 2009-04-08 20:22:24.000000000 +0200
|
||||
+++ compat-wireless-2009-03-31/drivers/net/wireless/b43/main.c 2009-04-08 20:41:43.000000000 +0200
|
||||
@@ -673,32 +673,6 @@ static void b43_short_slot_timing_disabl
|
||||
b43_set_slot_time(dev, 20);
|
||||
}
|
||||
|
||||
-/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
|
||||
- * Returns the _previously_ enabled IRQ mask.
|
||||
- */
|
||||
-static inline u32 b43_interrupt_enable(struct b43_wldev *dev, u32 mask)
|
||||
-{
|
||||
- u32 old_mask;
|
||||
-
|
||||
- old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
|
||||
- b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask | mask);
|
||||
-
|
||||
- return old_mask;
|
||||
-}
|
||||
-
|
||||
-/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
|
||||
- * Returns the _previously_ enabled IRQ mask.
|
||||
- */
|
||||
-static inline u32 b43_interrupt_disable(struct b43_wldev *dev, u32 mask)
|
||||
-{
|
||||
- u32 old_mask;
|
||||
-
|
||||
- old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
|
||||
- b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
|
||||
-
|
||||
- return old_mask;
|
||||
-}
|
||||
-
|
||||
/* Synchronize IRQ top- and bottom-half.
|
||||
* IRQs must be masked before calling this.
|
||||
* This must not be called with the irq_lock held.
|
||||
@@ -1593,7 +1567,7 @@ static void handle_irq_beacon(struct b43
|
||||
/* This is the bottom half of the asynchronous beacon update. */
|
||||
|
||||
/* Ignore interrupt in the future. */
|
||||
- dev->irq_savedstate &= ~B43_IRQ_BEACON;
|
||||
+ dev->irq_mask &= ~B43_IRQ_BEACON;
|
||||
|
||||
cmd = b43_read32(dev, B43_MMIO_MACCMD);
|
||||
beacon0_valid = (cmd & B43_MACCMD_BEACON0_VALID);
|
||||
@@ -1602,7 +1576,7 @@ static void handle_irq_beacon(struct b43
|
||||
/* Schedule interrupt manually, if busy. */
|
||||
if (beacon0_valid && beacon1_valid) {
|
||||
b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_BEACON);
|
||||
- dev->irq_savedstate |= B43_IRQ_BEACON;
|
||||
+ dev->irq_mask |= B43_IRQ_BEACON;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1641,11 +1615,9 @@ static void b43_beacon_update_trigger_wo
|
||||
if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
|
||||
spin_lock_irq(&wl->irq_lock);
|
||||
/* update beacon right away or defer to irq */
|
||||
- dev->irq_savedstate = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
|
||||
handle_irq_beacon(dev);
|
||||
/* The handler might have updated the IRQ mask. */
|
||||
- b43_write32(dev, B43_MMIO_GEN_IRQ_MASK,
|
||||
- dev->irq_savedstate);
|
||||
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
|
||||
mmiowb();
|
||||
spin_unlock_irq(&wl->irq_lock);
|
||||
}
|
||||
@@ -1879,7 +1851,7 @@ static void b43_interrupt_tasklet(struct
|
||||
if (reason & B43_IRQ_TX_OK)
|
||||
handle_irq_transmit_status(dev);
|
||||
|
||||
- b43_interrupt_enable(dev, dev->irq_savedstate);
|
||||
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
|
||||
mmiowb();
|
||||
spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
|
||||
}
|
||||
@@ -1893,7 +1865,9 @@ static void b43_interrupt_ack(struct b43
|
||||
b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]);
|
||||
b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]);
|
||||
b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]);
|
||||
+/* Unused ring
|
||||
b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]);
|
||||
+*/
|
||||
}
|
||||
|
||||
/* Interrupt handler top-half */
|
||||
@@ -1903,18 +1877,19 @@ static irqreturn_t b43_interrupt_handler
|
||||
struct b43_wldev *dev = dev_id;
|
||||
u32 reason;
|
||||
|
||||
- if (!dev)
|
||||
- return IRQ_NONE;
|
||||
+ B43_WARN_ON(!dev);
|
||||
|
||||
spin_lock(&dev->wl->irq_lock);
|
||||
|
||||
- if (b43_status(dev) < B43_STAT_STARTED)
|
||||
+ if (unlikely(b43_status(dev) < B43_STAT_STARTED)) {
|
||||
+ /* This can only happen on shared IRQ lines. */
|
||||
goto out;
|
||||
+ }
|
||||
reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
|
||||
if (reason == 0xffffffff) /* shared IRQ */
|
||||
goto out;
|
||||
ret = IRQ_HANDLED;
|
||||
- reason &= b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
|
||||
+ reason &= dev->irq_mask;
|
||||
if (!reason)
|
||||
goto out;
|
||||
|
||||
@@ -1928,16 +1903,18 @@ static irqreturn_t b43_interrupt_handler
|
||||
& 0x0001DC00;
|
||||
dev->dma_reason[4] = b43_read32(dev, B43_MMIO_DMA4_REASON)
|
||||
& 0x0000DC00;
|
||||
+/* Unused ring
|
||||
dev->dma_reason[5] = b43_read32(dev, B43_MMIO_DMA5_REASON)
|
||||
& 0x0000DC00;
|
||||
+*/
|
||||
|
||||
b43_interrupt_ack(dev, reason);
|
||||
/* disable all IRQs. They are enabled again in the bottom half. */
|
||||
- dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
|
||||
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
|
||||
/* save the reason code and call our bottom half. */
|
||||
dev->irq_reason = reason;
|
||||
tasklet_schedule(&dev->isr_tasklet);
|
||||
- out:
|
||||
+out:
|
||||
mmiowb();
|
||||
spin_unlock(&dev->wl->irq_lock);
|
||||
|
||||
@@ -3799,7 +3776,7 @@ static void b43_wireless_core_stop(struc
|
||||
* setting the status to INITIALIZED, as the interrupt handler
|
||||
* won't care about IRQs then. */
|
||||
spin_lock_irqsave(&wl->irq_lock, flags);
|
||||
- dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
|
||||
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
|
||||
b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */
|
||||
spin_unlock_irqrestore(&wl->irq_lock, flags);
|
||||
b43_synchronize_irq(dev);
|
||||
@@ -3840,7 +3817,7 @@ static int b43_wireless_core_start(struc
|
||||
|
||||
/* Start data flow (TX/RX). */
|
||||
b43_mac_enable(dev);
|
||||
- b43_interrupt_enable(dev, dev->irq_savedstate);
|
||||
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
|
||||
|
||||
/* Start maintainance work */
|
||||
b43_periodic_tasks_setup(dev);
|
||||
@@ -3998,9 +3975,9 @@ static void setup_struct_wldev_for_init(
|
||||
/* IRQ related flags */
|
||||
dev->irq_reason = 0;
|
||||
memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
|
||||
- dev->irq_savedstate = B43_IRQ_MASKTEMPLATE;
|
||||
+ dev->irq_mask = B43_IRQ_MASKTEMPLATE;
|
||||
if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
|
||||
- dev->irq_savedstate &= ~B43_IRQ_PHY_TXERR;
|
||||
+ dev->irq_mask &= ~B43_IRQ_PHY_TXERR;
|
||||
|
||||
dev->mac_suspended = 1;
|
||||
|
Loading…
Reference in a new issue