b43: Use a threaded IRQ handler
PATCH 1/5 b43: Use a threaded IRQ handler
Use a threaded IRQ handler to allow locking the mutex and sleeping while executing an interrupt.
This removes usage of the irq_lock spinlock, but introduces a new hardirq_lock, which is _only_ used for the PCI/SSB lowlevel hard-irq handler. Sleeping busses (SDIO) will use mutex instead.
Signed-off-by Michael Buesch <[email protected]>
drivers/net/wireless/b43/b43.h +8 -15
@@ -616,6 +616,12 @@ struct b43_wl {/* Pointer to the ieee80211 hardware data structure */ struct ieee80211_hw *hw; +/* Global driver mutex. Every operation must run with this mutex locked. */ +struct mutex mutex; +/* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ +* handler, only. This basically is just the IRQ mask register. */ +spinlock_t hardirq_lock; +/* The number of queues that were registered with the mac80211 subsystem * initially. This is a backup copy of hw->queues in case hw->queues has * to be dynamically lowered at runtime (Firmware does not support QoS).
@@ -623,8 +629,6 @@ struct b43_wl {* from the mac80211 subsystem. */ u16 mac80211_initially_registered_queues; -struct mutex mutex; -spinlock_t irq_lock;/* R/W lock for data transmission. * Transmissions on 2+ queues can run concurrently, but somebody else * might sync with TX by write_lock_irqsave()'ing. */
@@ -665,8 +669,7 @@ struct b43_wl {bool radiotap_enabled;bool radio_enabled; -/* The beacon we are currently using (AP or IBSS mode). -* This beacon stuff is protected by the irq_lock. */ +/* The beacon we are currently using (AP or IBSS mode). */ struct sk_buff *current_beacon;bool beacon0_uploaded;bool beacon1_uploaded;
@@ -754,14 +757,6 @@ enum {smp_wmb (); \ }while (0 ) -/* XXX--- HOW LOCKING WORKS IN B43 ---XXX -* -* You should always acquire both, wl->mutex and wl->irq_lock unless: -* - You don't need to acquire wl->irq_lock, if the interface is stopped. -* - You don't need to acquire wl->mutex in the IRQ handler, IRQ tasklet -* and packet TX path (and _ONLY_ there.) -*/ -/* Data structure for one wireless device (802.11 core) */ struct b43_wldev {struct ssb_device *dev;
@@ -807,14 +802,12 @@ struct b43_wldev {u32 dma_reason[6 ];/* 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. */ int mac_suspended; -/* Interrupt Service Routine tasklet (bottom-half) */ -struct tasklet_struct isr_tasklet; -/* Periodic tasks */ struct delayed_work periodic_work;unsigned int periodic_state;
drivers/net/wireless/b43/debugfs.c +16 -37
130 lines not on this page · raw message
drivers/net/wireless/b43/main.c +172 -147
639 lines not on this page · raw message
drivers/net/wireless/b43/phy_common.c +0 -1
@@ -347,7 +347,6 @@ void b43_phy_txpower_adjust_work(structmutex_unlock (&wl->mutex); } -/* Called with wl->irq_lock locked */ void b43_phy_txpower_check (struct b43_wldev *dev,unsigned int flags) {struct b43_phy *phy = &dev->phy;
drivers/net/wireless/b43/phy_common.h +1 -2
@@ -131,7 +131,7 @@ enum b43_txpwr_result {* If the parameter "ignore_tssi" is true, the TSSI values should * be ignored and a recalculation of the power settings should be * done even if the TSSI values did not change. -* This callback is called with wl->irq_lock held and must not sleep. +* This function may sleep, but should not. * Must not be NULL. * @adjust_txpower: Write the previously calculated TX power settings * (from @recalc_txpower) to the hardware.
@@ -379,7 +379,6 @@ void b43_software_rfkill(struct b43_wlde* * Compare the current TX power output to the desired power emission * and schedule an adjustment in case it mismatches. -* Requires wl->irq_lock locked. * * @flags: OR'ed enum b43_phy_txpower_check_flags flags. * See the docs below.
drivers/net/wireless/b43/phy_g.c +0 -7
@@ -2823,8 +2823,6 @@ static void b43_gphy_op_adjust_txpower(sb43_mac_suspend (dev); -spin_lock_irq (&dev->wl->irq_lock); -/* Calculate the new attenuation values. */ bbatt = gphy->bbatt.att; bbatt += gphy->bbatt_delta;
@@ -2864,11 +2862,6 @@ static void b43_gphy_op_adjust_txpower(s gphy->rfatt.att = rfatt; gphy->bbatt.att = bbatt; -/* We drop the lock early, so we can sleep during hardware -* adjustment. Possible races with op_recalc_txpower are harmless, -* as we will be called once again in case we raced. */ -spin_unlock_irq (&dev->wl->irq_lock); -if (b43_debug (dev,B43_DBG_XMITPOWER ))b43dbg (dev->wl,"Adjusting TX power\n" );
drivers/net/wireless/b43/phy_g.h +1 -2
@@ -141,8 +141,7 @@ struct b43_phy_g {int tgt_idle_tssi;/* Current idle TSSI */ int cur_idle_tssi; -/* The current average TSSI. -* Needs irq_lock, as it's updated in the IRQ path. */ +/* The current average TSSI. */ u8 average_tssi;/* Current TX power level attenuation control values */ struct b43_bbatt bbatt;
drivers/net/wireless/b43/sysfs.c +0 -3
@@ -94,7 +94,6 @@ static ssize_t b43_attr_interfmode_store const char *buf, size_t count) {struct b43_wldev *wldev =dev_to_b43_wldev (dev); -unsigned long flags;int err;int mode;
@@ -120,7 +119,6 @@ static ssize_t b43_attr_interfmode_store }mutex_lock (&wldev->wl->mutex); -spin_lock_irqsave (&wldev->wl->irq_lock, flags);if (wldev->phy.ops->interf_mitigation) { err = wldev->phy.ops->interf_mitigation (wldev, mode);
@@ -132,7 +130,6 @@ static ssize_t b43_attr_interfmode_store err = -ENOSYS ;mmiowb (); -spin_unlock_irqrestore (&wldev->wl->irq_lock, flags);mutex_unlock (&wldev->wl->mutex);return err ? err : count;
drivers/net/wireless/b43/dma.c +2 -3
@@ -1387,7 +1387,6 @@ out_unlock:return err; } -/* Called with IRQs disabled. */ void b43_dma_handle_txstatus (struct b43_wldev *dev,const struct b43_txstatus *status) {
@@ -1402,7 +1401,7 @@ void b43_dma_handle_txstatus(struct b43_if (unlikely (!ring))return ; -spin_lock (&ring->lock);/* IRQs are already disabled. */ +spin_lock_irq (&ring->lock);B43_WARN_ON (!ring->tx); ops = ring->ops;
@@ -1463,7 +1462,7 @@ void b43_dma_handle_txstatus(struct b43_ } } -spin_unlock (&ring->lock); +spin_unlock_irq (&ring->lock); } void b43_dma_get_tx_stats(struct b43_wldev *dev,
drivers/net/wireless/b43/pio.c +2 -3
@@ -570,7 +570,6 @@ out_unlock:return err; } -/* Called with IRQs disabled. */ void b43_pio_handle_txstatus (struct b43_wldev *dev,const struct b43_txstatus *status) {
@@ -584,7 +583,7 @@ void b43_pio_handle_txstatus(struct b43_return ;B43_WARN_ON (!pack); -spin_lock (&q->lock);/* IRQs are already disabled. */ +spin_lock_irq (&q->lock); info =IEEE80211_SKB_CB (pack->skb);
@@ -604,7 +603,7 @@ void b43_pio_handle_txstatus(struct b43_ q->stopped =0 ; } -spin_unlock (&q->lock); +spin_unlock_irq (&q->lock); } void b43_pio_get_tx_stats(struct b43_wldev *dev,
drivers/net/wireless/b43/debugfs.h +2 -1
@@ -23,9 +23,10 @@ struct dentry;#define B43_NR_LOGGED_TXSTATUS 100struct b43_txstatus_log { +/* This structure is protected by wl->mutex */ +struct b43_txstatus *log;int end; -spinlock_t lock; };struct b43_dfs_file {
Signature · 1 line
Greetings, Michael.