diff options
author | Stefano Brivio <stefano.brivio@polimi.it> | 2009-05-15 16:39:20 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-05-20 14:46:26 -0400 |
commit | 44710bbc073b2e7ea269cf716b817297cd35ae10 (patch) | |
tree | 81b09c09fc7e2eb6937c5cefe6873e0887c2b793 /drivers/net/wireless/b43legacy/main.c | |
parent | 6b96f93e962e25d38d7a73c0009597672d87c496 (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>
Diffstat (limited to 'drivers/net/wireless/b43legacy/main.c')
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 78 |
1 files changed, 22 insertions, 56 deletions
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 | */ | ||
589 | static 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 | */ | ||
604 | static 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); |
1494 | out: | 1463 | out: |
@@ -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); |
2744 | out_unlock_mutex: | 2712 | out_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 | ||