aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Brivio <stefano.brivio@polimi.it>2009-05-15 16:39:20 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-20 14:46:26 -0400
commit44710bbc073b2e7ea269cf716b817297cd35ae10 (patch)
tree81b09c09fc7e2eb6937c5cefe6873e0887c2b793
parent6b96f93e962e25d38d7a73c0009597672d87c496 (diff)
b43legacy: Remove unnecessary MMIO in interrupt hotpath
This removes unnecessary MMIO accesses in the interrupt hotpath. The patch by Michael Buesch for b43 has been ported to b43legacy. Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it> Tested-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h4
-rw-r--r--drivers/net/wireless/b43legacy/main.c78
-rw-r--r--drivers/net/wireless/b43legacy/pio.c2
3 files changed, 25 insertions, 59 deletions
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index da59ef02b6ef..19a4b0bc0d87 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -694,8 +694,8 @@ struct b43legacy_wldev {
694 /* Reason code of the last interrupt. */ 694 /* Reason code of the last interrupt. */
695 u32 irq_reason; 695 u32 irq_reason;
696 u32 dma_reason[6]; 696 u32 dma_reason[6];
697 /* saved irq enable/disable state bitfield. */ 697 /* The currently active generic-interrupt mask. */
698 u32 irq_savedstate; 698 u32 irq_mask;
699 /* Link Quality calculation context. */ 699 /* Link Quality calculation context. */
700 struct b43legacy_noise_calculation noisecalc; 700 struct b43legacy_noise_calculation noisecalc;
701 /* if > 0 MAC is suspended. if == 0 MAC is enabled. */ 701 /* if > 0 MAC is suspended. if == 0 MAC is enabled. */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 07c7898c87ac..0062b340d989 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -583,35 +583,6 @@ static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev)
583 b43legacy_set_slot_time(dev, 20); 583 b43legacy_set_slot_time(dev, 20);
584} 584}
585 585
586/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
587 * Returns the _previously_ enabled IRQ mask.
588 */
589static inline u32 b43legacy_interrupt_enable(struct b43legacy_wldev *dev,
590 u32 mask)
591{
592 u32 old_mask;
593
594 old_mask = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK);
595 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, old_mask |
596 mask);
597
598 return old_mask;
599}
600
601/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
602 * Returns the _previously_ enabled IRQ mask.
603 */
604static inline u32 b43legacy_interrupt_disable(struct b43legacy_wldev *dev,
605 u32 mask)
606{
607 u32 old_mask;
608
609 old_mask = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK);
610 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
611
612 return old_mask;
613}
614
615/* Synchronize IRQ top- and bottom-half. 586/* Synchronize IRQ top- and bottom-half.
616 * IRQs must be masked before calling this. 587 * IRQs must be masked before calling this.
617 * This must not be called with the irq_lock held. 588 * This must not be called with the irq_lock held.
@@ -1200,7 +1171,7 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev)
1200 /* This is the bottom half of the asynchronous beacon update. */ 1171 /* This is the bottom half of the asynchronous beacon update. */
1201 1172
1202 /* Ignore interrupt in the future. */ 1173 /* Ignore interrupt in the future. */
1203 dev->irq_savedstate &= ~B43legacy_IRQ_BEACON; 1174 dev->irq_mask &= ~B43legacy_IRQ_BEACON;
1204 1175
1205 cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); 1176 cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
1206 beacon0_valid = (cmd & B43legacy_MACCMD_BEACON0_VALID); 1177 beacon0_valid = (cmd & B43legacy_MACCMD_BEACON0_VALID);
@@ -1209,7 +1180,7 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev)
1209 /* Schedule interrupt manually, if busy. */ 1180 /* Schedule interrupt manually, if busy. */
1210 if (beacon0_valid && beacon1_valid) { 1181 if (beacon0_valid && beacon1_valid) {
1211 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, B43legacy_IRQ_BEACON); 1182 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, B43legacy_IRQ_BEACON);
1212 dev->irq_savedstate |= B43legacy_IRQ_BEACON; 1183 dev->irq_mask |= B43legacy_IRQ_BEACON;
1213 return; 1184 return;
1214 } 1185 }
1215 1186
@@ -1247,12 +1218,11 @@ static void b43legacy_beacon_update_trigger_work(struct work_struct *work)
1247 dev = wl->current_dev; 1218 dev = wl->current_dev;
1248 if (likely(dev && (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED))) { 1219 if (likely(dev && (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED))) {
1249 spin_lock_irq(&wl->irq_lock); 1220 spin_lock_irq(&wl->irq_lock);
1250 /* update beacon right away or defer to irq */ 1221 /* Update beacon right away or defer to IRQ. */
1251 dev->irq_savedstate = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK);
1252 handle_irq_beacon(dev); 1222 handle_irq_beacon(dev);
1253 /* The handler might have updated the IRQ mask. */ 1223 /* The handler might have updated the IRQ mask. */
1254 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 1224 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK,
1255 dev->irq_savedstate); 1225 dev->irq_mask);
1256 mmiowb(); 1226 mmiowb();
1257 spin_unlock_irq(&wl->irq_lock); 1227 spin_unlock_irq(&wl->irq_lock);
1258 } 1228 }
@@ -1398,7 +1368,7 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev)
1398 if (reason & B43legacy_IRQ_TX_OK) 1368 if (reason & B43legacy_IRQ_TX_OK)
1399 handle_irq_transmit_status(dev); 1369 handle_irq_transmit_status(dev);
1400 1370
1401 b43legacy_interrupt_enable(dev, dev->irq_savedstate); 1371 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
1402 mmiowb(); 1372 mmiowb();
1403 spin_unlock_irqrestore(&dev->wl->irq_lock, flags); 1373 spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
1404} 1374}
@@ -1450,18 +1420,18 @@ static irqreturn_t b43legacy_interrupt_handler(int irq, void *dev_id)
1450 struct b43legacy_wldev *dev = dev_id; 1420 struct b43legacy_wldev *dev = dev_id;
1451 u32 reason; 1421 u32 reason;
1452 1422
1453 if (!dev) 1423 B43legacy_WARN_ON(!dev);
1454 return IRQ_NONE;
1455 1424
1456 spin_lock(&dev->wl->irq_lock); 1425 spin_lock(&dev->wl->irq_lock);
1457 1426
1458 if (b43legacy_status(dev) < B43legacy_STAT_STARTED) 1427 if (unlikely(b43legacy_status(dev) < B43legacy_STAT_STARTED))
1428 /* This can only happen on shared IRQ lines. */
1459 goto out; 1429 goto out;
1460 reason = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON); 1430 reason = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
1461 if (reason == 0xffffffff) /* shared IRQ */ 1431 if (reason == 0xffffffff) /* shared IRQ */
1462 goto out; 1432 goto out;
1463 ret = IRQ_HANDLED; 1433 ret = IRQ_HANDLED;
1464 reason &= b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); 1434 reason &= dev->irq_mask;
1465 if (!reason) 1435 if (!reason)
1466 goto out; 1436 goto out;
1467 1437
@@ -1485,10 +1455,9 @@ static irqreturn_t b43legacy_interrupt_handler(int irq, void *dev_id)
1485 & 0x0000DC00; 1455 & 0x0000DC00;
1486 1456
1487 b43legacy_interrupt_ack(dev, reason); 1457 b43legacy_interrupt_ack(dev, reason);
1488 /* disable all IRQs. They are enabled again in the bottom half. */ 1458 /* Disable all IRQs. They are enabled again in the bottom half. */
1489 dev->irq_savedstate = b43legacy_interrupt_disable(dev, 1459 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
1490 B43legacy_IRQ_ALL); 1460 /* Save the reason code and call our bottom half. */
1491 /* save the reason code and call our bottom half. */
1492 dev->irq_reason = reason; 1461 dev->irq_reason = reason;
1493 tasklet_schedule(&dev->isr_tasklet); 1462 tasklet_schedule(&dev->isr_tasklet);
1494out: 1463out:
@@ -1948,7 +1917,8 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev)
1948 1917
1949 /* Re-enable IRQs. */ 1918 /* Re-enable IRQs. */
1950 spin_lock_irq(&dev->wl->irq_lock); 1919 spin_lock_irq(&dev->wl->irq_lock);
1951 b43legacy_interrupt_enable(dev, dev->irq_savedstate); 1920 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK,
1921 dev->irq_mask);
1952 spin_unlock_irq(&dev->wl->irq_lock); 1922 spin_unlock_irq(&dev->wl->irq_lock);
1953 } 1923 }
1954} 1924}
@@ -1967,10 +1937,9 @@ void b43legacy_mac_suspend(struct b43legacy_wldev *dev)
1967 /* Mask IRQs before suspending MAC. Otherwise 1937 /* Mask IRQs before suspending MAC. Otherwise
1968 * the MAC stays busy and won't suspend. */ 1938 * the MAC stays busy and won't suspend. */
1969 spin_lock_irq(&dev->wl->irq_lock); 1939 spin_lock_irq(&dev->wl->irq_lock);
1970 tmp = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL); 1940 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
1971 spin_unlock_irq(&dev->wl->irq_lock); 1941 spin_unlock_irq(&dev->wl->irq_lock);
1972 b43legacy_synchronize_irq(dev); 1942 b43legacy_synchronize_irq(dev);
1973 dev->irq_savedstate = tmp;
1974 1943
1975 b43legacy_power_saving_ctl_bits(dev, -1, 1); 1944 b43legacy_power_saving_ctl_bits(dev, -1, 1);
1976 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, 1945 b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
@@ -2659,7 +2628,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
2659 int antenna_tx; 2628 int antenna_tx;
2660 int antenna_rx; 2629 int antenna_rx;
2661 int err = 0; 2630 int err = 0;
2662 u32 savedirqs;
2663 2631
2664 antenna_tx = B43legacy_ANTENNA_DEFAULT; 2632 antenna_tx = B43legacy_ANTENNA_DEFAULT;
2665 antenna_rx = B43legacy_ANTENNA_DEFAULT; 2633 antenna_rx = B43legacy_ANTENNA_DEFAULT;
@@ -2699,7 +2667,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
2699 spin_unlock_irqrestore(&wl->irq_lock, flags); 2667 spin_unlock_irqrestore(&wl->irq_lock, flags);
2700 goto out_unlock_mutex; 2668 goto out_unlock_mutex;
2701 } 2669 }
2702 savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL); 2670 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
2703 spin_unlock_irqrestore(&wl->irq_lock, flags); 2671 spin_unlock_irqrestore(&wl->irq_lock, flags);
2704 b43legacy_synchronize_irq(dev); 2672 b43legacy_synchronize_irq(dev);
2705 2673
@@ -2738,7 +2706,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
2738 } 2706 }
2739 2707
2740 spin_lock_irqsave(&wl->irq_lock, flags); 2708 spin_lock_irqsave(&wl->irq_lock, flags);
2741 b43legacy_interrupt_enable(dev, savedirqs); 2709 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
2742 mmiowb(); 2710 mmiowb();
2743 spin_unlock_irqrestore(&wl->irq_lock, flags); 2711 spin_unlock_irqrestore(&wl->irq_lock, flags);
2744out_unlock_mutex: 2712out_unlock_mutex:
@@ -2801,7 +2769,6 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
2801 struct b43legacy_wldev *dev; 2769 struct b43legacy_wldev *dev;
2802 struct b43legacy_phy *phy; 2770 struct b43legacy_phy *phy;
2803 unsigned long flags; 2771 unsigned long flags;
2804 u32 savedirqs;
2805 2772
2806 mutex_lock(&wl->mutex); 2773 mutex_lock(&wl->mutex);
2807 B43legacy_WARN_ON(wl->vif != vif); 2774 B43legacy_WARN_ON(wl->vif != vif);
@@ -2817,7 +2784,7 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
2817 spin_unlock_irqrestore(&wl->irq_lock, flags); 2784 spin_unlock_irqrestore(&wl->irq_lock, flags);
2818 goto out_unlock_mutex; 2785 goto out_unlock_mutex;
2819 } 2786 }
2820 savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL); 2787 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
2821 2788
2822 if (changed & BSS_CHANGED_BSSID) { 2789 if (changed & BSS_CHANGED_BSSID) {
2823 spin_unlock_irqrestore(&wl->irq_lock, flags); 2790 spin_unlock_irqrestore(&wl->irq_lock, flags);
@@ -2862,7 +2829,7 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
2862 b43legacy_mac_enable(dev); 2829 b43legacy_mac_enable(dev);
2863 2830
2864 spin_lock_irqsave(&wl->irq_lock, flags); 2831 spin_lock_irqsave(&wl->irq_lock, flags);
2865 b43legacy_interrupt_enable(dev, savedirqs); 2832 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
2866 /* XXX: why? */ 2833 /* XXX: why? */
2867 mmiowb(); 2834 mmiowb();
2868 spin_unlock_irqrestore(&wl->irq_lock, flags); 2835 spin_unlock_irqrestore(&wl->irq_lock, flags);
@@ -2922,8 +2889,7 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
2922 * setting the status to INITIALIZED, as the interrupt handler 2889 * setting the status to INITIALIZED, as the interrupt handler
2923 * won't care about IRQs then. */ 2890 * won't care about IRQs then. */
2924 spin_lock_irqsave(&wl->irq_lock, flags); 2891 spin_lock_irqsave(&wl->irq_lock, flags);
2925 dev->irq_savedstate = b43legacy_interrupt_disable(dev, 2892 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
2926 B43legacy_IRQ_ALL);
2927 b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); /* flush */ 2893 b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); /* flush */
2928 spin_unlock_irqrestore(&wl->irq_lock, flags); 2894 spin_unlock_irqrestore(&wl->irq_lock, flags);
2929 b43legacy_synchronize_irq(dev); 2895 b43legacy_synchronize_irq(dev);
@@ -2963,7 +2929,7 @@ static int b43legacy_wireless_core_start(struct b43legacy_wldev *dev)
2963 2929
2964 /* Start data flow (TX/RX) */ 2930 /* Start data flow (TX/RX) */
2965 b43legacy_mac_enable(dev); 2931 b43legacy_mac_enable(dev);
2966 b43legacy_interrupt_enable(dev, dev->irq_savedstate); 2932 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
2967 2933
2968 /* Start maintenance work */ 2934 /* Start maintenance work */
2969 b43legacy_periodic_tasks_setup(dev); 2935 b43legacy_periodic_tasks_setup(dev);
@@ -3126,7 +3092,7 @@ static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev)
3126 /* IRQ related flags */ 3092 /* IRQ related flags */
3127 dev->irq_reason = 0; 3093 dev->irq_reason = 0;
3128 memset(dev->dma_reason, 0, sizeof(dev->dma_reason)); 3094 memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
3129 dev->irq_savedstate = B43legacy_IRQ_MASKTEMPLATE; 3095 dev->irq_mask = B43legacy_IRQ_MASKTEMPLATE;
3130 3096
3131 dev->mac_suspended = 1; 3097 dev->mac_suspended = 1;
3132 3098
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index 746d5361bba0..51866c9a2769 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -443,7 +443,7 @@ int b43legacy_pio_init(struct b43legacy_wldev *dev)
443 pio->queue3 = queue; 443 pio->queue3 = queue;
444 444
445 if (dev->dev->id.revision < 3) 445 if (dev->dev->id.revision < 3)
446 dev->irq_savedstate |= B43legacy_IRQ_PIO_WORKAROUND; 446 dev->irq_mask |= B43legacy_IRQ_PIO_WORKAROUND;
447 447
448 b43legacydbg(dev->wl, "PIO initialized\n"); 448 b43legacydbg(dev->wl, "PIO initialized\n");
449 err = 0; 449 err = 0;