diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.c | 41 |
1 files changed, 7 insertions, 34 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index c6bd86889f1b..b199d32c37ea 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -3209,55 +3209,27 @@ static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm) | |||
3209 | 3209 | ||
3210 | static void do_periodic_work(struct bcm43xx_private *bcm) | 3210 | static void do_periodic_work(struct bcm43xx_private *bcm) |
3211 | { | 3211 | { |
3212 | unsigned int state; | 3212 | if (bcm->periodic_state % 8 == 0) |
3213 | |||
3214 | state = bcm->periodic_state; | ||
3215 | if (state % 8 == 0) | ||
3216 | bcm43xx_periodic_every120sec(bcm); | 3213 | bcm43xx_periodic_every120sec(bcm); |
3217 | if (state % 4 == 0) | 3214 | if (bcm->periodic_state % 4 == 0) |
3218 | bcm43xx_periodic_every60sec(bcm); | 3215 | bcm43xx_periodic_every60sec(bcm); |
3219 | if (state % 2 == 0) | 3216 | if (bcm->periodic_state % 2 == 0) |
3220 | bcm43xx_periodic_every30sec(bcm); | 3217 | bcm43xx_periodic_every30sec(bcm); |
3221 | if (state % 1 == 0) | 3218 | bcm43xx_periodic_every15sec(bcm); |
3222 | bcm43xx_periodic_every15sec(bcm); | ||
3223 | bcm->periodic_state = state + 1; | ||
3224 | 3219 | ||
3225 | schedule_delayed_work(&bcm->periodic_work, HZ * 15); | 3220 | schedule_delayed_work(&bcm->periodic_work, HZ * 15); |
3226 | } | 3221 | } |
3227 | 3222 | ||
3228 | /* Estimate a "Badness" value based on the periodic work | ||
3229 | * state-machine state. "Badness" is worse (bigger), if the | ||
3230 | * periodic work will take longer. | ||
3231 | */ | ||
3232 | static int estimate_periodic_work_badness(unsigned int state) | ||
3233 | { | ||
3234 | int badness = 0; | ||
3235 | |||
3236 | if (state % 8 == 0) /* every 120 sec */ | ||
3237 | badness += 10; | ||
3238 | if (state % 4 == 0) /* every 60 sec */ | ||
3239 | badness += 5; | ||
3240 | if (state % 2 == 0) /* every 30 sec */ | ||
3241 | badness += 1; | ||
3242 | if (state % 1 == 0) /* every 15 sec */ | ||
3243 | badness += 1; | ||
3244 | |||
3245 | #define BADNESS_LIMIT 4 | ||
3246 | return badness; | ||
3247 | } | ||
3248 | |||
3249 | static void bcm43xx_periodic_work_handler(void *d) | 3223 | static void bcm43xx_periodic_work_handler(void *d) |
3250 | { | 3224 | { |
3251 | struct bcm43xx_private *bcm = d; | 3225 | struct bcm43xx_private *bcm = d; |
3252 | struct net_device *net_dev = bcm->net_dev; | 3226 | struct net_device *net_dev = bcm->net_dev; |
3253 | unsigned long flags; | 3227 | unsigned long flags; |
3254 | u32 savedirqs = 0; | 3228 | u32 savedirqs = 0; |
3255 | int badness; | ||
3256 | unsigned long orig_trans_start = 0; | 3229 | unsigned long orig_trans_start = 0; |
3257 | 3230 | ||
3258 | mutex_lock(&bcm->mutex); | 3231 | mutex_lock(&bcm->mutex); |
3259 | badness = estimate_periodic_work_badness(bcm->periodic_state); | 3232 | if (unlikely(bcm->periodic_state % 4 == 0)) { |
3260 | if (badness > BADNESS_LIMIT) { | ||
3261 | /* Periodic work will take a long time, so we want it to | 3233 | /* Periodic work will take a long time, so we want it to |
3262 | * be preemtible. | 3234 | * be preemtible. |
3263 | */ | 3235 | */ |
@@ -3289,7 +3261,7 @@ static void bcm43xx_periodic_work_handler(void *d) | |||
3289 | 3261 | ||
3290 | do_periodic_work(bcm); | 3262 | do_periodic_work(bcm); |
3291 | 3263 | ||
3292 | if (badness > BADNESS_LIMIT) { | 3264 | if (unlikely(bcm->periodic_state % 4 == 0)) { |
3293 | spin_lock_irqsave(&bcm->irq_lock, flags); | 3265 | spin_lock_irqsave(&bcm->irq_lock, flags); |
3294 | tasklet_enable(&bcm->isr_tasklet); | 3266 | tasklet_enable(&bcm->isr_tasklet); |
3295 | bcm43xx_interrupt_enable(bcm, savedirqs); | 3267 | bcm43xx_interrupt_enable(bcm, savedirqs); |
@@ -3300,6 +3272,7 @@ static void bcm43xx_periodic_work_handler(void *d) | |||
3300 | net_dev->trans_start = orig_trans_start; | 3272 | net_dev->trans_start = orig_trans_start; |
3301 | } | 3273 | } |
3302 | mmiowb(); | 3274 | mmiowb(); |
3275 | bcm->periodic_state++; | ||
3303 | spin_unlock_irqrestore(&bcm->irq_lock, flags); | 3276 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
3304 | mutex_unlock(&bcm->mutex); | 3277 | mutex_unlock(&bcm->mutex); |
3305 | } | 3278 | } |