[PATCH] bcm43xx: voluntary preemtion in the calibration loops
This patch adds voluntary preemption points into the PHY calibration loops to allow non-CONFIG_PREEMPT machines to not suffer from huge delays. CONFIG_PREEMPT machines are already fine, because all this code is run in non-atomic process context. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
efa6a37021
commit
2087da5dc1
@ -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…
x
Reference in New Issue
Block a user