diff options
author | Bob Copeland <me@bobcopeland.com> | 2010-01-20 23:51:04 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-22 16:11:31 -0500 |
commit | a951ae2176b982574ffa197455db6c89359fd5eb (patch) | |
tree | e2b821cf406a85541439b0eea2b0cc06a71381ce | |
parent | 5d6ce628f986d1a3c523cbb0a5a52095c48cc332 (diff) |
ath5k: fix setup for CAB queue
The beacon sent gating doesn't seem to work with any combination
of flags. Thus, buffered frames tend to stay buffered forever,
using up tx descriptors.
Instead, use the DBA gating and hold transmission of the buffered
frames until 80% of the beacon interval has elapsed using the ready
time. This fixes the following error in AP mode:
ath5k phy0: no further txbuf available, dropping packet
Add a comment to acknowledge that this isn't the best solution.
Signed-off-by: Bob Copeland <me@bobcopeland.com>
Acked-by: Nick Kossifidis <mickflemm@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ath5k.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/qcu.c | 5 |
3 files changed, 23 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 66bcb506a112..ad4d446f0264 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -535,7 +535,7 @@ struct ath5k_txq_info { | |||
535 | u32 tqi_cbr_period; /* Constant bit rate period */ | 535 | u32 tqi_cbr_period; /* Constant bit rate period */ |
536 | u32 tqi_cbr_overflow_limit; | 536 | u32 tqi_cbr_overflow_limit; |
537 | u32 tqi_burst_time; | 537 | u32 tqi_burst_time; |
538 | u32 tqi_ready_time; /* Not used */ | 538 | u32 tqi_ready_time; /* Time queue waits after an event */ |
539 | }; | 539 | }; |
540 | 540 | ||
541 | /* | 541 | /* |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index b5015376d4ba..535a6afb94e3 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1516,7 +1516,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1516 | 1516 | ||
1517 | ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); | 1517 | ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); |
1518 | if (ret) | 1518 | if (ret) |
1519 | return ret; | 1519 | goto err; |
1520 | |||
1520 | if (sc->opmode == NL80211_IFTYPE_AP || | 1521 | if (sc->opmode == NL80211_IFTYPE_AP || |
1521 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { | 1522 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { |
1522 | /* | 1523 | /* |
@@ -1543,10 +1544,25 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1543 | if (ret) { | 1544 | if (ret) { |
1544 | ATH5K_ERR(sc, "%s: unable to update parameters for beacon " | 1545 | ATH5K_ERR(sc, "%s: unable to update parameters for beacon " |
1545 | "hardware queue!\n", __func__); | 1546 | "hardware queue!\n", __func__); |
1546 | return ret; | 1547 | goto err; |
1547 | } | 1548 | } |
1549 | ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */ | ||
1550 | if (ret) | ||
1551 | goto err; | ||
1548 | 1552 | ||
1549 | return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */; | 1553 | /* reconfigure cabq with ready time to 80% of beacon_interval */ |
1554 | ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); | ||
1555 | if (ret) | ||
1556 | goto err; | ||
1557 | |||
1558 | qi.tqi_ready_time = (sc->bintval * 80) / 100; | ||
1559 | ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); | ||
1560 | if (ret) | ||
1561 | goto err; | ||
1562 | |||
1563 | ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB); | ||
1564 | err: | ||
1565 | return ret; | ||
1550 | } | 1566 | } |
1551 | 1567 | ||
1552 | static void | 1568 | static void |
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index abe36c0d139c..9122a8556f45 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c | |||
@@ -408,12 +408,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
408 | break; | 408 | break; |
409 | 409 | ||
410 | case AR5K_TX_QUEUE_CAB: | 410 | case AR5K_TX_QUEUE_CAB: |
411 | /* XXX: use BCN_SENT_GT, if we can figure out how */ | ||
411 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), | 412 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), |
412 | AR5K_QCU_MISC_FRSHED_BCN_SENT_GT | | 413 | AR5K_QCU_MISC_FRSHED_DBA_GT | |
413 | AR5K_QCU_MISC_CBREXP_DIS | | 414 | AR5K_QCU_MISC_CBREXP_DIS | |
414 | AR5K_QCU_MISC_CBREXP_BCN_DIS); | 415 | AR5K_QCU_MISC_CBREXP_BCN_DIS); |
415 | 416 | ||
416 | ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - | 417 | ath5k_hw_reg_write(ah, ((tq->tqi_ready_time - |
417 | (AR5K_TUNE_SW_BEACON_RESP - | 418 | (AR5K_TUNE_SW_BEACON_RESP - |
418 | AR5K_TUNE_DMA_BEACON_RESP) - | 419 | AR5K_TUNE_DMA_BEACON_RESP) - |
419 | AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | | 420 | AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | |