Commit 225ec70a authored by Jeff Garzik's avatar Jeff Garzik
Browse files

Merge branch 'upstream' of...

parents 3fac0613 dd2f5538
Loading
Loading
Loading
Loading
+14 −50
Original line number Diff line number Diff line
@@ -649,6 +649,19 @@ enum {
#define bcm43xx_status(bcm)		atomic_read(&(bcm)->init_status)
#define bcm43xx_set_status(bcm, stat)	atomic_set(&(bcm)->init_status, (stat))

/*    *** THEORY OF LOCKING ***
 *
 * We have two different locks in the bcm43xx driver.
 * => bcm->mutex:    General sleeping mutex. Protects struct bcm43xx_private
 *                   and the device registers. This mutex does _not_ protect
 *                   against concurrency from the IRQ handler.
 * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
 *
 * Please note that, if you only take the irq_lock, you are not protected
 * against concurrency from the periodic work handlers.
 * Most times you want to take _both_ locks.
 */

struct bcm43xx_private {
	struct ieee80211_device *ieee;
	struct ieee80211softmac_device *softmac;
@@ -659,7 +672,6 @@ struct bcm43xx_private {

	void __iomem *mmio_addr;

	/* Locking, see "theory of locking" text below. */
	spinlock_t irq_lock;
	struct mutex mutex;

@@ -691,6 +703,7 @@ struct bcm43xx_private {
	struct bcm43xx_sprominfo sprom;
#define BCM43xx_NR_LEDS		4
	struct bcm43xx_led leds[BCM43xx_NR_LEDS];
	spinlock_t leds_lock;

	/* The currently active core. */
	struct bcm43xx_coreinfo *current_core;
@@ -763,55 +776,6 @@ struct bcm43xx_private {
};


/*    *** THEORY OF LOCKING ***
 *
 * We have two different locks in the bcm43xx driver.
 * => bcm->mutex:    General sleeping mutex. Protects struct bcm43xx_private
 *                   and the device registers.
 * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
 *
 * We have three types of helper function pairs to utilize these locks.
 *     (Always use the helper functions.)
 * 1) bcm43xx_{un}lock_noirq():
 *     Takes bcm->mutex. Does _not_ protect against IRQ concurrency,
 *     so it is almost always unsafe, if device IRQs are enabled.
 *     So only use this, if device IRQs are masked.
 *     Locking may sleep.
 *     You can sleep within the critical section.
 * 2) bcm43xx_{un}lock_irqonly():
 *     Takes bcm->irq_lock. Does _not_ protect against
 *     bcm43xx_lock_noirq() critical sections.
 *     Does only protect against the IRQ handler path and other
 *     irqonly() critical sections.
 *     Locking does not sleep.
 *     You must not sleep within the critical section.
 * 3) bcm43xx_{un}lock_irqsafe():
 *     This is the cummulative lock and takes both, mutex and irq_lock.
 *     Protects against noirq() and irqonly() critical sections (and
 *     the IRQ handler path).
 *     Locking may sleep.
 *     You must not sleep within the critical section.
 */

/* Lock type 1 */
#define bcm43xx_lock_noirq(bcm)		mutex_lock(&(bcm)->mutex)
#define bcm43xx_unlock_noirq(bcm)	mutex_unlock(&(bcm)->mutex)
/* Lock type 2 */
#define bcm43xx_lock_irqonly(bcm, flags)	\
	spin_lock_irqsave(&(bcm)->irq_lock, flags)
#define bcm43xx_unlock_irqonly(bcm, flags)	\
	spin_unlock_irqrestore(&(bcm)->irq_lock, flags)
/* Lock type 3 */
#define bcm43xx_lock_irqsafe(bcm, flags) do {	\
	bcm43xx_lock_noirq(bcm);		\
	bcm43xx_lock_irqonly(bcm, flags);	\
		} while (0)
#define bcm43xx_unlock_irqsafe(bcm, flags) do {	\
	bcm43xx_unlock_irqonly(bcm, flags);	\
	bcm43xx_unlock_noirq(bcm);		\
		} while (0)


static inline
struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
{
+22 −12
Original line number Diff line number Diff line
@@ -77,7 +77,8 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,

	down(&big_buffer_sem);

	bcm43xx_lock_irqsafe(bcm, flags);
	mutex_lock(&bcm->mutex);
	spin_lock_irqsave(&bcm->irq_lock, flags);
	if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
		fappend("Board not initialized.\n");
		goto out;
@@ -121,7 +122,8 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
	fappend("\n");

out:
	bcm43xx_unlock_irqsafe(bcm, flags);
	spin_unlock_irqrestore(&bcm->irq_lock, flags);
	mutex_unlock(&bcm->mutex);
	res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
	up(&big_buffer_sem);
	return res;
@@ -159,7 +161,8 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
	unsigned long flags;

	down(&big_buffer_sem);
	bcm43xx_lock_irqsafe(bcm, flags);
	mutex_lock(&bcm->mutex);
	spin_lock_irqsave(&bcm->irq_lock, flags);
	if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
		fappend("Board not initialized.\n");
		goto out;
@@ -169,7 +172,8 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
	fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);

out:
	bcm43xx_unlock_irqsafe(bcm, flags);
	spin_unlock_irqrestore(&bcm->irq_lock, flags);
	mutex_unlock(&bcm->mutex);
	res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
	up(&big_buffer_sem);
	return res;
@@ -188,7 +192,8 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
	u64 tsf;

	down(&big_buffer_sem);
	bcm43xx_lock_irqsafe(bcm, flags);
	mutex_lock(&bcm->mutex);
	spin_lock_irqsave(&bcm->irq_lock, flags);
	if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
		fappend("Board not initialized.\n");
		goto out;
@@ -199,7 +204,8 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
		(unsigned int)(tsf & 0xFFFFFFFFULL));

out:
	bcm43xx_unlock_irqsafe(bcm, flags);
	spin_unlock_irqrestore(&bcm->irq_lock, flags);
	mutex_unlock(&bcm->mutex);
	res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
	up(&big_buffer_sem);
	return res;
@@ -221,7 +227,8 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
	        res = -EFAULT;
		goto out_up;
	}
	bcm43xx_lock_irqsafe(bcm, flags);
	mutex_lock(&bcm->mutex);
	spin_lock_irqsave(&bcm->irq_lock, flags);
	if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
		printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
		res = -EFAULT;
@@ -237,7 +244,8 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
	res = buf_size;
	
out_unlock:
	bcm43xx_unlock_irqsafe(bcm, flags);
	spin_unlock_irqrestore(&bcm->irq_lock, flags);
	mutex_unlock(&bcm->mutex);
out_up:
	up(&big_buffer_sem);
	return res;
@@ -258,7 +266,8 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
	int i, cnt, j = 0;

	down(&big_buffer_sem);
	bcm43xx_lock_irqsafe(bcm, flags);
	mutex_lock(&bcm->mutex);
	spin_lock_irqsave(&bcm->irq_lock, flags);

	fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
		BCM43xx_NR_LOGGED_XMITSTATUS);
@@ -294,14 +303,15 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
			i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
	}

	bcm43xx_unlock_irqsafe(bcm, flags);
	spin_unlock_irqrestore(&bcm->irq_lock, flags);
	res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
	bcm43xx_lock_irqsafe(bcm, flags);
	spin_lock_irqsave(&bcm->irq_lock, flags);
	if (*ppos == pos) {
		/* Done. Drop the copied data. */
		e->xmitstatus_printing = 0;
	}
	bcm43xx_unlock_irqsafe(bcm, flags);
	spin_unlock_irqrestore(&bcm->irq_lock, flags);
	mutex_unlock(&bcm->mutex);
	up(&big_buffer_sem);
	return res;
}
+8 −2
Original line number Diff line number Diff line
@@ -51,12 +51,12 @@ static void bcm43xx_led_blink(unsigned long d)
	struct bcm43xx_private *bcm = led->bcm;
	unsigned long flags;

	bcm43xx_lock_irqonly(bcm, flags);
	spin_lock_irqsave(&bcm->leds_lock, flags);
	if (led->blink_interval) {
		bcm43xx_led_changestate(led);
		mod_timer(&led->blink_timer, jiffies + led->blink_interval);
	}
	bcm43xx_unlock_irqonly(bcm, flags);
	spin_unlock_irqrestore(&bcm->leds_lock, flags);
}

static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
@@ -177,7 +177,9 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
	int i, turn_on;
	unsigned long interval = 0;
	u16 ledctl;
	unsigned long flags;

	spin_lock_irqsave(&bcm->leds_lock, flags);
	ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
	for (i = 0; i < BCM43xx_NR_LEDS; i++) {
		led = &(bcm->leds[i]);
@@ -266,6 +268,7 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
			ledctl &= ~(1 << i);
	}
	bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
	spin_unlock_irqrestore(&bcm->leds_lock, flags);
}

void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
@@ -274,7 +277,9 @@ void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
	u16 ledctl;
	int i;
	int bit_on;
	unsigned long flags;

	spin_lock_irqsave(&bcm->leds_lock, flags);
	ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
	for (i = 0; i < BCM43xx_NR_LEDS; i++) {
		led = &(bcm->leds[i]);
@@ -290,4 +295,5 @@ void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
			ledctl &= ~(1 << i);
	}
	bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
	spin_unlock_irqrestore(&bcm->leds_lock, flags);
}
+32 −32
Original line number Diff line number Diff line
@@ -514,13 +514,13 @@ static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *old
	unsigned long flags;
	u32 old;

	bcm43xx_lock_irqonly(bcm, flags);
	spin_lock_irqsave(&bcm->irq_lock, flags);
	if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) {
		bcm43xx_unlock_irqonly(bcm, flags);
		spin_unlock_irqrestore(&bcm->irq_lock, flags);
		return -EBUSY;
	}
	old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
	bcm43xx_unlock_irqonly(bcm, flags);
	spin_unlock_irqrestore(&bcm->irq_lock, flags);
	bcm43xx_synchronize_irq(bcm);

	if (oldstate)
@@ -1720,7 +1720,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
# define bcmirq_handled(irq)	do { /* nothing */ } while (0)
#endif /* CONFIG_BCM43XX_DEBUG*/

	bcm43xx_lock_irqonly(bcm, flags);
	spin_lock_irqsave(&bcm->irq_lock, flags);
	reason = bcm->irq_reason;
	dma_reason[0] = bcm->dma_reason[0];
	dma_reason[1] = bcm->dma_reason[1];
@@ -1746,7 +1746,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
			dma_reason[2], dma_reason[3]);
		bcm43xx_controller_restart(bcm, "DMA error");
		mmiowb();
		bcm43xx_unlock_irqonly(bcm, flags);
		spin_unlock_irqrestore(&bcm->irq_lock, flags);
		return;
	}
	if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
@@ -1834,7 +1834,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
		bcm43xx_leds_update(bcm, activity);
	bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
	mmiowb();
	bcm43xx_unlock_irqonly(bcm, flags);
	spin_unlock_irqrestore(&bcm->irq_lock, flags);
}

static void pio_irq_workaround(struct bcm43xx_private *bcm,
@@ -3182,25 +3182,26 @@ static void bcm43xx_periodic_work_handler(void *d)
		/* Periodic work will take a long time, so we want it to
		 * be preemtible.
		 */
		bcm43xx_lock_irqonly(bcm, flags);
		netif_stop_queue(bcm->net_dev);
		spin_lock_irqsave(&bcm->irq_lock, flags);
		if (bcm43xx_using_pio(bcm))
			bcm43xx_pio_freeze_txqueues(bcm);
		savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
		bcm43xx_unlock_irqonly(bcm, flags);
		bcm43xx_lock_noirq(bcm);
		spin_unlock_irqrestore(&bcm->irq_lock, flags);
		mutex_lock(&bcm->mutex);
		bcm43xx_synchronize_irq(bcm);
	} else {
		/* Periodic work should take short time, so we want low
		 * locking overhead.
		 */
		bcm43xx_lock_irqsafe(bcm, flags);
		mutex_lock(&bcm->mutex);
		spin_lock_irqsave(&bcm->irq_lock, flags);
	}

	do_periodic_work(bcm);

	if (badness > BADNESS_LIMIT) {
		bcm43xx_lock_irqonly(bcm, flags);
		spin_lock_irqsave(&bcm->irq_lock, flags);
		if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) {
			tasklet_enable(&bcm->isr_tasklet);
			bcm43xx_interrupt_enable(bcm, savedirqs);
@@ -3208,13 +3209,10 @@ static void bcm43xx_periodic_work_handler(void *d)
				bcm43xx_pio_thaw_txqueues(bcm);
		}
		netif_wake_queue(bcm->net_dev);
		mmiowb();
		bcm43xx_unlock_irqonly(bcm, flags);
		bcm43xx_unlock_noirq(bcm);
	} else {
		mmiowb();
		bcm43xx_unlock_irqsafe(bcm, flags);
	}
	mmiowb();
	spin_unlock_irqrestore(&bcm->irq_lock, flags);
	mutex_unlock(&bcm->mutex);
}

static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
@@ -3276,7 +3274,7 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm)
{
	int i, err;

	bcm43xx_lock_noirq(bcm);
	mutex_lock(&bcm->mutex);
	bcm43xx_sysfs_unregister(bcm);
	bcm43xx_periodic_tasks_delete(bcm);

@@ -3297,7 +3295,7 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm)
	bcm43xx_pctl_set_crystal(bcm, 0);

	bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
	bcm43xx_unlock_noirq(bcm);
	mutex_unlock(&bcm->mutex);
}

static int bcm43xx_init_board(struct bcm43xx_private *bcm)
@@ -3307,7 +3305,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)

	might_sleep();

	bcm43xx_lock_noirq(bcm);
	mutex_lock(&bcm->mutex);
	bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);

	err = bcm43xx_pctl_set_crystal(bcm, 1);
@@ -3389,7 +3387,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)

	assert(err == 0);
out:
	bcm43xx_unlock_noirq(bcm);
	mutex_unlock(&bcm->mutex);

	return err;

@@ -3647,7 +3645,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
	struct bcm43xx_radioinfo *radio;
	unsigned long flags;

	bcm43xx_lock_irqsafe(bcm, flags);
	mutex_lock(&bcm->mutex);
	spin_lock_irqsave(&bcm->irq_lock, flags);
	if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
		bcm43xx_mac_suspend(bcm);
		bcm43xx_radio_selectchannel(bcm, channel, 0);
@@ -3656,7 +3655,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
		radio = bcm43xx_current_radio(bcm);
		radio->initial_channel = channel;
	}
	bcm43xx_unlock_irqsafe(bcm, flags);
	spin_unlock_irqrestore(&bcm->irq_lock, flags);
	mutex_unlock(&bcm->mutex);
}

/* set_security() callback in struct ieee80211_device */
@@ -3670,7 +3670,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
	
	dprintk(KERN_INFO PFX "set security called");

	bcm43xx_lock_irqsafe(bcm, flags);
	mutex_lock(&bcm->mutex);
	spin_lock_irqsave(&bcm->irq_lock, flags);

	for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
		if (sec->flags & (1<<keyidx)) {
@@ -3739,7 +3740,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
		} else
				bcm43xx_clear_keys(bcm);
	}
	bcm43xx_unlock_irqsafe(bcm, flags);
	spin_unlock_irqrestore(&bcm->irq_lock, flags);
	mutex_unlock(&bcm->mutex);
}

/* hard_start_xmit() callback in struct ieee80211_device */
@@ -3751,10 +3753,10 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
	int err = -ENODEV;
	unsigned long flags;

	bcm43xx_lock_irqonly(bcm, flags);
	spin_lock_irqsave(&bcm->irq_lock, flags);
	if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED))
		err = bcm43xx_tx(bcm, txb);
	bcm43xx_unlock_irqonly(bcm, flags);
	spin_unlock_irqrestore(&bcm->irq_lock, flags);

	return err;
}
@@ -3769,9 +3771,9 @@ static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
	struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
	unsigned long flags;

	bcm43xx_lock_irqonly(bcm, flags);
	spin_lock_irqsave(&bcm->irq_lock, flags);
	bcm43xx_controller_restart(bcm, "TX timeout");
	bcm43xx_unlock_irqonly(bcm, flags);
	spin_unlock_irqrestore(&bcm->irq_lock, flags);
}

#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -3822,6 +3824,7 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
	bcm->net_dev = net_dev;
	bcm->bad_frames_preempt = modparam_bad_frames_preempt;
	spin_lock_init(&bcm->irq_lock);
	spin_lock_init(&bcm->leds_lock);
	mutex_init(&bcm->mutex);
	tasklet_init(&bcm->isr_tasklet,
		     (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
@@ -4002,16 +4005,13 @@ static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct net_device *net_dev = pci_get_drvdata(pdev);
	struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
	unsigned long flags;
	int try_to_shutdown = 0, err;

	dprintk(KERN_INFO PFX "Suspending...\n");

	bcm43xx_lock_irqsafe(bcm, flags);
	bcm->was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
	if (bcm->was_initialized)
		try_to_shutdown = 1;
	bcm43xx_unlock_irqsafe(bcm, flags);

	netif_device_detach(net_dev);
	if (try_to_shutdown) {
+18 −15
Original line number Diff line number Diff line
@@ -81,6 +81,16 @@ static const s8 bcm43xx_tssi2dbm_g_table[] = {
static void bcm43xx_phy_initg(struct bcm43xx_private *bcm);


static inline
void bcm43xx_voluntary_preempt(void)
{
	assert(!in_atomic() && !in_irq() &&
	       !in_interrupt() && !irqs_disabled());
#ifndef CONFIG_PREEMPT
	cond_resched();
#endif /* CONFIG_PREEMPT */
}

void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm)
{
	struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
@@ -133,22 +143,14 @@ void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm)
{
	struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
	unsigned long flags;

	bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* Dummy read. */
	if (phy->calibrated)
		return;
	if (phy->type == BCM43xx_PHYTYPE_G && phy->rev == 1) {
		/* We do not want to be preempted while calibrating
		 * the hardware.
		 */
		local_irq_save(flags);

		bcm43xx_wireless_core_reset(bcm, 0);
		bcm43xx_phy_initg(bcm);
		bcm43xx_wireless_core_reset(bcm, 1);

		local_irq_restore(flags);
	}
	phy->calibrated = 1;
}
@@ -1299,7 +1301,9 @@ static u16 bcm43xx_phy_lo_b_r15_loop(struct bcm43xx_private *bcm)
{
	int i;
	u16 ret = 0;
	unsigned long flags;

	local_irq_save(flags);
	for (i = 0; i < 10; i++){
		bcm43xx_phy_write(bcm, 0x0015, 0xAFA0);
		udelay(1);
@@ -1309,6 +1313,8 @@ static u16 bcm43xx_phy_lo_b_r15_loop(struct bcm43xx_private *bcm)
		udelay(40);
		ret += bcm43xx_phy_read(bcm, 0x002C);
	}
	local_irq_restore(flags);
	bcm43xx_voluntary_preempt();

	return ret;
}
@@ -1435,6 +1441,7 @@ u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control)
	}
	ret = bcm43xx_phy_read(bcm, 0x002D);
	local_irq_restore(flags);
	bcm43xx_voluntary_preempt();

	return ret;
}
@@ -1760,6 +1767,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
			bcm43xx_radio_write16(bcm, 0x43, i);
			bcm43xx_radio_write16(bcm, 0x52, radio->txctl2);
			udelay(10);
			bcm43xx_voluntary_preempt();

			bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);

@@ -1803,6 +1811,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
					      radio->txctl2
					      | (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above?
			udelay(10);
			bcm43xx_voluntary_preempt();

			bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);

@@ -1824,6 +1833,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
		bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA2);
		udelay(2);
		bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA3);
		bcm43xx_voluntary_preempt();
	} else
		bcm43xx_phy_write(bcm, 0x0015, r27 | 0xEFA0);
	bcm43xx_phy_lo_adjust(bcm, is_initializing);
@@ -2188,12 +2198,6 @@ int bcm43xx_phy_init(struct bcm43xx_private *bcm)
{
	struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
	int err = -ENODEV;
	unsigned long flags;

	/* We do not want to be preempted while calibrating
	 * the hardware.
	 */
	local_irq_save(flags);

	switch (phy->type) {
	case BCM43xx_PHYTYPE_A:
@@ -2227,7 +2231,6 @@ int bcm43xx_phy_init(struct bcm43xx_private *bcm)
		err = 0;
		break;
	}
	local_irq_restore(flags);
	if (err)
		printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n");

Loading