diff options
author | Felix Fietkau <nbd@openwrt.org> | 2008-10-05 12:05:48 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-10-06 18:14:57 -0400 |
commit | 2f7fe87034298d94301315ba4bb65c7284c709d0 (patch) | |
tree | e8583ae3686a243405b77d4ef6498bc4199ca3a2 /drivers/net/wireless/ath5k/desc.c | |
parent | 870abdf67170daa9f1022e55a35c469239fcc74c (diff) |
ath5k: implement multi-rate retry support, fix tx status reporting
Clean up the tx status reporting, fix retry counters (short retries are
virtual collisions, not actual retries). Implement multi-rate retry
support.
This also fixes strong throughput fluctuations with rc80211_pid
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath5k/desc.c')
-rw-r--r-- | drivers/net/wireless/ath5k/desc.c | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath5k/desc.c index d45b90a6e06c..dd1374052ba9 100644 --- a/drivers/net/wireless/ath5k/desc.c +++ b/drivers/net/wireless/ath5k/desc.c | |||
@@ -318,6 +318,15 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
318 | return 0; | 318 | return 0; |
319 | } | 319 | } |
320 | 320 | ||
321 | /* no mrr support for cards older than 5212 */ | ||
322 | static int | ||
323 | ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc, | ||
324 | unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, | ||
325 | u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3) | ||
326 | { | ||
327 | return 0; | ||
328 | } | ||
329 | |||
321 | /* | 330 | /* |
322 | * Proccess the tx status descriptor on 5210/5211 | 331 | * Proccess the tx status descriptor on 5210/5211 |
323 | */ | 332 | */ |
@@ -352,8 +361,10 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | |||
352 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | 361 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); |
353 | ts->ts_antenna = 1; | 362 | ts->ts_antenna = 1; |
354 | ts->ts_status = 0; | 363 | ts->ts_status = 0; |
355 | ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0, | 364 | ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0, |
356 | AR5K_2W_TX_DESC_CTL0_XMIT_RATE); | 365 | AR5K_2W_TX_DESC_CTL0_XMIT_RATE); |
366 | ts->ts_retry[0] = ts->ts_longretry; | ||
367 | ts->ts_final_idx = 0; | ||
357 | 368 | ||
358 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { | 369 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { |
359 | if (tx_status->tx_status_0 & | 370 | if (tx_status->tx_status_0 & |
@@ -405,29 +416,43 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, | |||
405 | AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; | 416 | AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; |
406 | ts->ts_status = 0; | 417 | ts->ts_status = 0; |
407 | 418 | ||
408 | switch (AR5K_REG_MS(tx_status->tx_status_1, | 419 | ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, |
409 | AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) { | 420 | AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX); |
410 | case 0: | 421 | |
411 | ts->ts_rate = tx_ctl->tx_control_3 & | 422 | /* The longretry counter has the number of un-acked retries |
412 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | 423 | * for the final rate. To get the total number of retries |
413 | break; | 424 | * we have to add the retry counters for the other rates |
425 | * as well | ||
426 | */ | ||
427 | ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry; | ||
428 | switch (ts->ts_final_idx) { | ||
429 | case 3: | ||
430 | ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
431 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); | ||
432 | |||
433 | ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
434 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); | ||
435 | ts->ts_longretry += ts->ts_retry[2]; | ||
436 | /* fall through */ | ||
437 | case 2: | ||
438 | ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
439 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); | ||
440 | |||
441 | ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
442 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | ||
443 | ts->ts_longretry += ts->ts_retry[1]; | ||
444 | /* fall through */ | ||
414 | case 1: | 445 | case 1: |
415 | ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3, | 446 | ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3, |
416 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); | 447 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); |
417 | ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2, | 448 | |
449 | ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
418 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | 450 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); |
419 | break; | 451 | ts->ts_longretry += ts->ts_retry[0]; |
420 | case 2: | 452 | /* fall through */ |
421 | ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3, | 453 | case 0: |
422 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); | 454 | ts->ts_rate[0] = tx_ctl->tx_control_3 & |
423 | ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2, | 455 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; |
424 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); | ||
425 | break; | ||
426 | case 3: | ||
427 | ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
428 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); | ||
429 | ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2, | ||
430 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3); | ||
431 | break; | 456 | break; |
432 | } | 457 | } |
433 | 458 | ||
@@ -653,7 +678,7 @@ int ath5k_hw_init_desc_functions(struct ath5k_hw *ah) | |||
653 | } else { | 678 | } else { |
654 | ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; | 679 | ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; |
655 | ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc; | 680 | ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc; |
656 | ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc; | 681 | ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr; |
657 | ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status; | 682 | ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status; |
658 | } | 683 | } |
659 | 684 | ||