diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/gpio.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/gpio.c | 95 |
1 files changed, 49 insertions, 46 deletions
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index da344b27326c..86d46c196966 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -202,17 +202,16 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
202 | } | 202 | } |
203 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 203 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
204 | 204 | ||
205 | ath9k_mci_update_rssi(sc); | ||
206 | |||
207 | ath9k_ps_wakeup(sc); | 205 | ath9k_ps_wakeup(sc); |
206 | spin_lock_bh(&btcoex->btcoex_lock); | ||
208 | 207 | ||
209 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) | 208 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) { |
210 | ath_detect_bt_priority(sc); | 209 | ath9k_mci_update_rssi(sc); |
211 | |||
212 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | ||
213 | ath_mci_ftp_adjust(sc); | 210 | ath_mci_ftp_adjust(sc); |
211 | } | ||
214 | 212 | ||
215 | spin_lock_bh(&btcoex->btcoex_lock); | 213 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) |
214 | ath_detect_bt_priority(sc); | ||
216 | 215 | ||
217 | stomp_type = btcoex->bt_stomp_type; | 216 | stomp_type = btcoex->bt_stomp_type; |
218 | timer_period = btcoex->btcoex_no_stomp; | 217 | timer_period = btcoex->btcoex_no_stomp; |
@@ -252,9 +251,6 @@ static void ath_btcoex_no_stomp_timer(unsigned long arg) | |||
252 | struct ath_softc *sc = (struct ath_softc *)arg; | 251 | struct ath_softc *sc = (struct ath_softc *)arg; |
253 | struct ath_hw *ah = sc->sc_ah; | 252 | struct ath_hw *ah = sc->sc_ah; |
254 | struct ath_btcoex *btcoex = &sc->btcoex; | 253 | struct ath_btcoex *btcoex = &sc->btcoex; |
255 | struct ath_common *common = ath9k_hw_common(ah); | ||
256 | |||
257 | ath_dbg(common, BTCOEX, "no stomp timer running\n"); | ||
258 | 254 | ||
259 | ath9k_ps_wakeup(sc); | 255 | ath9k_ps_wakeup(sc); |
260 | spin_lock_bh(&btcoex->btcoex_lock); | 256 | spin_lock_bh(&btcoex->btcoex_lock); |
@@ -271,7 +267,7 @@ static void ath_btcoex_no_stomp_timer(unsigned long arg) | |||
271 | ath9k_ps_restore(sc); | 267 | ath9k_ps_restore(sc); |
272 | } | 268 | } |
273 | 269 | ||
274 | static int ath_init_btcoex_timer(struct ath_softc *sc) | 270 | static void ath_init_btcoex_timer(struct ath_softc *sc) |
275 | { | 271 | { |
276 | struct ath_btcoex *btcoex = &sc->btcoex; | 272 | struct ath_btcoex *btcoex = &sc->btcoex; |
277 | 273 | ||
@@ -280,6 +276,7 @@ static int ath_init_btcoex_timer(struct ath_softc *sc) | |||
280 | btcoex->btcoex_period / 100; | 276 | btcoex->btcoex_period / 100; |
281 | btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * | 277 | btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * |
282 | btcoex->btcoex_period / 100; | 278 | btcoex->btcoex_period / 100; |
279 | btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | ||
283 | 280 | ||
284 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, | 281 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, |
285 | (unsigned long) sc); | 282 | (unsigned long) sc); |
@@ -287,8 +284,6 @@ static int ath_init_btcoex_timer(struct ath_softc *sc) | |||
287 | (unsigned long) sc); | 284 | (unsigned long) sc); |
288 | 285 | ||
289 | spin_lock_init(&btcoex->btcoex_lock); | 286 | spin_lock_init(&btcoex->btcoex_lock); |
290 | |||
291 | return 0; | ||
292 | } | 287 | } |
293 | 288 | ||
294 | /* | 289 | /* |
@@ -299,6 +294,10 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) | |||
299 | struct ath_btcoex *btcoex = &sc->btcoex; | 294 | struct ath_btcoex *btcoex = &sc->btcoex; |
300 | struct ath_hw *ah = sc->sc_ah; | 295 | struct ath_hw *ah = sc->sc_ah; |
301 | 296 | ||
297 | if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_3WIRE && | ||
298 | ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_MCI) | ||
299 | return; | ||
300 | |||
302 | ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n"); | 301 | ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n"); |
303 | 302 | ||
304 | /* make sure duty cycle timer is also stopped when resuming */ | 303 | /* make sure duty cycle timer is also stopped when resuming */ |
@@ -312,13 +311,19 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) | |||
312 | mod_timer(&btcoex->period_timer, jiffies); | 311 | mod_timer(&btcoex->period_timer, jiffies); |
313 | } | 312 | } |
314 | 313 | ||
315 | |||
316 | /* | 314 | /* |
317 | * Pause btcoex timer and bt duty cycle timer | 315 | * Pause btcoex timer and bt duty cycle timer |
318 | */ | 316 | */ |
319 | void ath9k_btcoex_timer_pause(struct ath_softc *sc) | 317 | void ath9k_btcoex_timer_pause(struct ath_softc *sc) |
320 | { | 318 | { |
321 | struct ath_btcoex *btcoex = &sc->btcoex; | 319 | struct ath_btcoex *btcoex = &sc->btcoex; |
320 | struct ath_hw *ah = sc->sc_ah; | ||
321 | |||
322 | if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_3WIRE && | ||
323 | ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_MCI) | ||
324 | return; | ||
325 | |||
326 | ath_dbg(ath9k_hw_common(ah), BTCOEX, "Stopping btcoex timers\n"); | ||
322 | 327 | ||
323 | del_timer_sync(&btcoex->period_timer); | 328 | del_timer_sync(&btcoex->period_timer); |
324 | del_timer_sync(&btcoex->no_stomp_timer); | 329 | del_timer_sync(&btcoex->no_stomp_timer); |
@@ -356,33 +361,33 @@ void ath9k_start_btcoex(struct ath_softc *sc) | |||
356 | { | 361 | { |
357 | struct ath_hw *ah = sc->sc_ah; | 362 | struct ath_hw *ah = sc->sc_ah; |
358 | 363 | ||
359 | if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) && | 364 | if (ah->btcoex_hw.enabled || |
360 | !ah->btcoex_hw.enabled) { | 365 | ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) |
361 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) | 366 | return; |
362 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
363 | AR_STOMP_LOW_WLAN_WGHT, 0); | ||
364 | else | ||
365 | ath9k_hw_btcoex_set_weight(ah, 0, 0, | ||
366 | ATH_BTCOEX_STOMP_NONE); | ||
367 | ath9k_hw_btcoex_enable(ah); | ||
368 | 367 | ||
369 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) | 368 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) |
370 | ath9k_btcoex_timer_resume(sc); | 369 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, |
371 | } | 370 | AR_STOMP_LOW_WLAN_WGHT, 0); |
371 | else | ||
372 | ath9k_hw_btcoex_set_weight(ah, 0, 0, | ||
373 | ATH_BTCOEX_STOMP_NONE); | ||
374 | ath9k_hw_btcoex_enable(ah); | ||
375 | ath9k_btcoex_timer_resume(sc); | ||
372 | } | 376 | } |
373 | 377 | ||
374 | void ath9k_stop_btcoex(struct ath_softc *sc) | 378 | void ath9k_stop_btcoex(struct ath_softc *sc) |
375 | { | 379 | { |
376 | struct ath_hw *ah = sc->sc_ah; | 380 | struct ath_hw *ah = sc->sc_ah; |
377 | 381 | ||
378 | if (ah->btcoex_hw.enabled && | 382 | if (!ah->btcoex_hw.enabled || |
379 | ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { | 383 | ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) |
380 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) | 384 | return; |
381 | ath9k_btcoex_timer_pause(sc); | 385 | |
382 | ath9k_hw_btcoex_disable(ah); | 386 | ath9k_btcoex_timer_pause(sc); |
383 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) | 387 | ath9k_hw_btcoex_disable(ah); |
384 | ath_mci_flush_profile(&sc->btcoex.mci); | 388 | |
385 | } | 389 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) |
390 | ath_mci_flush_profile(&sc->btcoex.mci); | ||
386 | } | 391 | } |
387 | 392 | ||
388 | void ath9k_deinit_btcoex(struct ath_softc *sc) | 393 | void ath9k_deinit_btcoex(struct ath_softc *sc) |
@@ -409,22 +414,20 @@ int ath9k_init_btcoex(struct ath_softc *sc) | |||
409 | break; | 414 | break; |
410 | case ATH_BTCOEX_CFG_3WIRE: | 415 | case ATH_BTCOEX_CFG_3WIRE: |
411 | ath9k_hw_btcoex_init_3wire(sc->sc_ah); | 416 | ath9k_hw_btcoex_init_3wire(sc->sc_ah); |
412 | r = ath_init_btcoex_timer(sc); | 417 | ath_init_btcoex_timer(sc); |
413 | if (r) | ||
414 | return -1; | ||
415 | txq = sc->tx.txq_map[IEEE80211_AC_BE]; | 418 | txq = sc->tx.txq_map[IEEE80211_AC_BE]; |
416 | ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); | 419 | ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); |
417 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | 420 | break; |
418 | if (ath9k_hw_mci_is_enabled(ah)) { | 421 | case ATH_BTCOEX_CFG_MCI: |
419 | sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; | 422 | ath_init_btcoex_timer(sc); |
420 | INIT_LIST_HEAD(&sc->btcoex.mci.info); | ||
421 | 423 | ||
422 | r = ath_mci_setup(sc); | 424 | sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; |
423 | if (r) | 425 | INIT_LIST_HEAD(&sc->btcoex.mci.info); |
424 | return r; | 426 | ath9k_hw_btcoex_init_mci(ah); |
425 | 427 | ||
426 | ath9k_hw_btcoex_init_mci(ah); | 428 | r = ath_mci_setup(sc); |
427 | } | 429 | if (r) |
430 | return r; | ||
428 | 431 | ||
429 | break; | 432 | break; |
430 | default: | 433 | default: |