diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2008-05-10 07:42:06 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-21 21:47:30 -0400 |
commit | fb55f4d1fa252ba1e479284b79da1049d658c371 (patch) | |
tree | 0922dcd4e12037026293dd41914d774f06955641 /drivers/net/wireless/rt2x00/rt2x00dev.c | |
parent | 5a6e59991b82580c3ca00115603b85762ec76104 (diff) |
rt2x00: Fix TX status reporting
The tx_status enumeration was broken since the introduction
of rt61pci. That driver uses different values to report the
status of the tx action.
This would lead to frames that were reported as success but
actually failed to be send out, or frames that were neither
successfull or failure which were reported as failure.
Fix this by change the TX status reporting and more explicitely
check for failure or success. Note that a third possibility is
added "unknown". Not all hardware (USB) can report the actual
TX status, for rt61pci some frames will receive this status
because the TXdone handler is never called for those frames.
This unknown will now be handled as neither success or failure,
so we no longer increment the failure counter while this conclusion
could not be determined from the real status of the frame.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index ea130f2eb008..69da22cf085c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -496,38 +496,36 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
496 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 496 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
497 | struct skb_frame_desc *skbdesc; | 497 | struct skb_frame_desc *skbdesc; |
498 | struct ieee80211_tx_status tx_status; | 498 | struct ieee80211_tx_status tx_status; |
499 | int success = !!(txdesc->status == TX_SUCCESS || | ||
500 | txdesc->status == TX_SUCCESS_RETRY); | ||
501 | int fail = !!(txdesc->status == TX_FAIL_RETRY || | ||
502 | txdesc->status == TX_FAIL_INVALID || | ||
503 | txdesc->status == TX_FAIL_OTHER); | ||
504 | 499 | ||
505 | /* | 500 | /* |
506 | * Update TX statistics. | 501 | * Update TX statistics. |
507 | */ | 502 | */ |
508 | rt2x00dev->link.qual.tx_success += success; | 503 | rt2x00dev->link.qual.tx_success += |
509 | rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; | 504 | test_bit(TXDONE_SUCCESS, &txdesc->flags); |
505 | rt2x00dev->link.qual.tx_failed += | ||
506 | txdesc->retry + !!test_bit(TXDONE_FAILURE, &txdesc->flags); | ||
510 | 507 | ||
511 | /* | 508 | /* |
512 | * Initialize TX status | 509 | * Initialize TX status |
513 | */ | 510 | */ |
514 | tx_status.flags = 0; | 511 | tx_status.flags = 0; |
515 | tx_status.ack_signal = 0; | 512 | tx_status.ack_signal = 0; |
516 | tx_status.excessive_retries = (txdesc->status == TX_FAIL_RETRY); | 513 | tx_status.excessive_retries = |
514 | test_bit(TXDONE_EXCESSIVE_RETRY, &txdesc->flags); | ||
517 | tx_status.retry_count = txdesc->retry; | 515 | tx_status.retry_count = txdesc->retry; |
518 | memcpy(&tx_status.control, txdesc->control, sizeof(*txdesc->control)); | 516 | memcpy(&tx_status.control, txdesc->control, sizeof(*txdesc->control)); |
519 | 517 | ||
520 | if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) { | 518 | if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) { |
521 | if (success) | 519 | if (test_bit(TXDONE_SUCCESS, &txdesc->flags)) |
522 | tx_status.flags |= IEEE80211_TX_STATUS_ACK; | 520 | tx_status.flags |= IEEE80211_TX_STATUS_ACK; |
523 | else | 521 | else if (test_bit(TXDONE_FAILURE, &txdesc->flags)) |
524 | rt2x00dev->low_level_stats.dot11ACKFailureCount++; | 522 | rt2x00dev->low_level_stats.dot11ACKFailureCount++; |
525 | } | 523 | } |
526 | 524 | ||
527 | if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { | 525 | if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { |
528 | if (success) | 526 | if (test_bit(TXDONE_SUCCESS, &txdesc->flags)) |
529 | rt2x00dev->low_level_stats.dot11RTSSuccessCount++; | 527 | rt2x00dev->low_level_stats.dot11RTSSuccessCount++; |
530 | else | 528 | else if (test_bit(TXDONE_FAILURE, &txdesc->flags)) |
531 | rt2x00dev->low_level_stats.dot11RTSFailureCount++; | 529 | rt2x00dev->low_level_stats.dot11RTSFailureCount++; |
532 | } | 530 | } |
533 | 531 | ||
@@ -546,7 +544,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
546 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, | 544 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, |
547 | entry->skb, &tx_status); | 545 | entry->skb, &tx_status); |
548 | else | 546 | else |
549 | dev_kfree_skb(entry->skb); | 547 | dev_kfree_skb_irq(entry->skb); |
550 | entry->skb = NULL; | 548 | entry->skb = NULL; |
551 | } | 549 | } |
552 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 550 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |