diff options
author | Felix Fietkau <nbd@openwrt.org> | 2013-12-14 12:03:37 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-12-18 15:23:21 -0500 |
commit | 168c6f89a27b605fb7dc3e1572ee5b2a6f56c935 (patch) | |
tree | e57f485098bccac408eda99813b1fab377ba06d3 | |
parent | e45e91d8812c1cd4dac98efd6fb6d0dd27fa3d4a (diff) |
ath9k_hw: use a software timer for btcoex no_stomp_timer
TSF accuracy is not needed here, and there is only one usable generic
timer that is supported by all chips and uses the primary TSF counter.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/gpio.c | 53 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/mci.c | 2 |
3 files changed, 15 insertions, 47 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 5e5d5cb2458c..dbf2a97d4daa 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -477,20 +477,19 @@ enum bt_op_flags { | |||
477 | }; | 477 | }; |
478 | 478 | ||
479 | struct ath_btcoex { | 479 | struct ath_btcoex { |
480 | bool hw_timer_enabled; | ||
481 | spinlock_t btcoex_lock; | 480 | spinlock_t btcoex_lock; |
482 | struct timer_list period_timer; /* Timer for BT period */ | 481 | struct timer_list period_timer; /* Timer for BT period */ |
482 | struct timer_list no_stomp_timer; | ||
483 | u32 bt_priority_cnt; | 483 | u32 bt_priority_cnt; |
484 | unsigned long bt_priority_time; | 484 | unsigned long bt_priority_time; |
485 | unsigned long op_flags; | 485 | unsigned long op_flags; |
486 | int bt_stomp_type; /* Types of BT stomping */ | 486 | int bt_stomp_type; /* Types of BT stomping */ |
487 | u32 btcoex_no_stomp; /* in usec */ | 487 | u32 btcoex_no_stomp; /* in msec */ |
488 | u32 btcoex_period; /* in msec */ | 488 | u32 btcoex_period; /* in msec */ |
489 | u32 btscan_no_stomp; /* in usec */ | 489 | u32 btscan_no_stomp; /* in msec */ |
490 | u32 duty_cycle; | 490 | u32 duty_cycle; |
491 | u32 bt_wait_time; | 491 | u32 bt_wait_time; |
492 | int rssi_count; | 492 | int rssi_count; |
493 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ | ||
494 | struct ath_mci_profile mci; | 493 | struct ath_mci_profile mci; |
495 | u8 stomp_audio; | 494 | u8 stomp_audio; |
496 | }; | 495 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index c34f21241da9..a85e220c8d9c 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -257,19 +257,9 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
257 | 257 | ||
258 | spin_unlock_bh(&btcoex->btcoex_lock); | 258 | spin_unlock_bh(&btcoex->btcoex_lock); |
259 | 259 | ||
260 | /* | 260 | if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) |
261 | * btcoex_period is in msec while (btocex/btscan_)no_stomp are in usec, | 261 | mod_timer(&btcoex->no_stomp_timer, |
262 | * ensure that we properly convert btcoex_period to usec | 262 | jiffies + msecs_to_jiffies(timer_period)); |
263 | * for any comparision with (btcoex/btscan_)no_stomp. | ||
264 | */ | ||
265 | if (btcoex->btcoex_period * 1000 != btcoex->btcoex_no_stomp) { | ||
266 | if (btcoex->hw_timer_enabled) | ||
267 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | ||
268 | |||
269 | ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period, | ||
270 | timer_period * 10); | ||
271 | btcoex->hw_timer_enabled = true; | ||
272 | } | ||
273 | 263 | ||
274 | ath9k_ps_restore(sc); | 264 | ath9k_ps_restore(sc); |
275 | 265 | ||
@@ -282,7 +272,7 @@ skip_hw_wakeup: | |||
282 | * Generic tsf based hw timer which configures weight | 272 | * Generic tsf based hw timer which configures weight |
283 | * registers to time slice between wlan and bt traffic | 273 | * registers to time slice between wlan and bt traffic |
284 | */ | 274 | */ |
285 | static void ath_btcoex_no_stomp_timer(void *arg) | 275 | static void ath_btcoex_no_stomp_timer(unsigned long arg) |
286 | { | 276 | { |
287 | struct ath_softc *sc = (struct ath_softc *)arg; | 277 | struct ath_softc *sc = (struct ath_softc *)arg; |
288 | struct ath_hw *ah = sc->sc_ah; | 278 | struct ath_hw *ah = sc->sc_ah; |
@@ -311,24 +301,18 @@ static int ath_init_btcoex_timer(struct ath_softc *sc) | |||
311 | struct ath_btcoex *btcoex = &sc->btcoex; | 301 | struct ath_btcoex *btcoex = &sc->btcoex; |
312 | 302 | ||
313 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; | 303 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; |
314 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * 1000 * | 304 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * |
315 | btcoex->btcoex_period / 100; | 305 | btcoex->btcoex_period / 100; |
316 | btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * 1000 * | 306 | btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * |
317 | btcoex->btcoex_period / 100; | 307 | btcoex->btcoex_period / 100; |
318 | 308 | ||
319 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, | 309 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, |
320 | (unsigned long) sc); | 310 | (unsigned long) sc); |
311 | setup_timer(&btcoex->no_stomp_timer, ath_btcoex_no_stomp_timer, | ||
312 | (unsigned long) sc); | ||
321 | 313 | ||
322 | spin_lock_init(&btcoex->btcoex_lock); | 314 | spin_lock_init(&btcoex->btcoex_lock); |
323 | 315 | ||
324 | btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah, | ||
325 | ath_btcoex_no_stomp_timer, | ||
326 | ath_btcoex_no_stomp_timer, | ||
327 | (void *) sc, AR_FIRST_NDP_TIMER); | ||
328 | |||
329 | if (!btcoex->no_stomp_timer) | ||
330 | return -ENOMEM; | ||
331 | |||
332 | return 0; | 316 | return 0; |
333 | } | 317 | } |
334 | 318 | ||
@@ -343,10 +327,7 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) | |||
343 | ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n"); | 327 | ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n"); |
344 | 328 | ||
345 | /* make sure duty cycle timer is also stopped when resuming */ | 329 | /* make sure duty cycle timer is also stopped when resuming */ |
346 | if (btcoex->hw_timer_enabled) { | 330 | del_timer_sync(&btcoex->no_stomp_timer); |
347 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | ||
348 | btcoex->hw_timer_enabled = false; | ||
349 | } | ||
350 | 331 | ||
351 | btcoex->bt_priority_cnt = 0; | 332 | btcoex->bt_priority_cnt = 0; |
352 | btcoex->bt_priority_time = jiffies; | 333 | btcoex->bt_priority_time = jiffies; |
@@ -363,24 +344,16 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) | |||
363 | void ath9k_btcoex_timer_pause(struct ath_softc *sc) | 344 | void ath9k_btcoex_timer_pause(struct ath_softc *sc) |
364 | { | 345 | { |
365 | struct ath_btcoex *btcoex = &sc->btcoex; | 346 | struct ath_btcoex *btcoex = &sc->btcoex; |
366 | struct ath_hw *ah = sc->sc_ah; | ||
367 | 347 | ||
368 | del_timer_sync(&btcoex->period_timer); | 348 | del_timer_sync(&btcoex->period_timer); |
369 | 349 | del_timer_sync(&btcoex->no_stomp_timer); | |
370 | if (btcoex->hw_timer_enabled) { | ||
371 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | ||
372 | btcoex->hw_timer_enabled = false; | ||
373 | } | ||
374 | } | 350 | } |
375 | 351 | ||
376 | void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) | 352 | void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) |
377 | { | 353 | { |
378 | struct ath_btcoex *btcoex = &sc->btcoex; | 354 | struct ath_btcoex *btcoex = &sc->btcoex; |
379 | 355 | ||
380 | if (btcoex->hw_timer_enabled) { | 356 | del_timer_sync(&btcoex->no_stomp_timer); |
381 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | ||
382 | btcoex->hw_timer_enabled = false; | ||
383 | } | ||
384 | } | 357 | } |
385 | 358 | ||
386 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) | 359 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) |
@@ -447,10 +420,6 @@ void ath9k_deinit_btcoex(struct ath_softc *sc) | |||
447 | { | 420 | { |
448 | struct ath_hw *ah = sc->sc_ah; | 421 | struct ath_hw *ah = sc->sc_ah; |
449 | 422 | ||
450 | if ((sc->btcoex.no_stomp_timer) && | ||
451 | ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE) | ||
452 | ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); | ||
453 | |||
454 | if (ath9k_hw_mci_is_enabled(ah)) | 423 | if (ath9k_hw_mci_is_enabled(ah)) |
455 | ath_mci_cleanup(sc); | 424 | ath_mci_cleanup(sc); |
456 | } | 425 | } |
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 0ac1b5f04256..71799fcade54 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c | |||
@@ -200,7 +200,7 @@ skip_tuning: | |||
200 | if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE) | 200 | if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE) |
201 | btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE; | 201 | btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE; |
202 | 202 | ||
203 | btcoex->btcoex_no_stomp = btcoex->btcoex_period * 1000 * | 203 | btcoex->btcoex_no_stomp = btcoex->btcoex_period * |
204 | (100 - btcoex->duty_cycle) / 100; | 204 | (100 - btcoex->duty_cycle) / 100; |
205 | 205 | ||
206 | ath9k_hw_btcoex_enable(sc->sc_ah); | 206 | ath9k_hw_btcoex_enable(sc->sc_ah); |