aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00dev.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-05-10 07:42:06 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:47:30 -0400
commitfb55f4d1fa252ba1e479284b79da1049d658c371 (patch)
tree0922dcd4e12037026293dd41914d774f06955641 /drivers/net/wireless/rt2x00/rt2x00dev.c
parent5a6e59991b82580c3ca00115603b85762ec76104 (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.c24
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}
552EXPORT_SYMBOL_GPL(rt2x00lib_txdone); 550EXPORT_SYMBOL_GPL(rt2x00lib_txdone);