diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index afa565c63621455ce726aef92721a535938beb00..69b1dbd1adf0cc29818adce59f46e60ec45ce330 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1137,7 +1137,18 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, /* * Obtain the status about this packet. */ - txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT); + txdesc.flags = 0; + switch (rt2x00_get_field32(word, TXD_W0_RESULT)) { + case 0: /* Success */ + case 1: /* Success with retry */ + __set_bit(TXDONE_SUCCESS, &txdesc.flags); + break; + case 2: /* Failure, excessive retries */ + __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags); + /* Don't break, this is a failed frame! */ + default: /* Failure */ + __set_bit(TXDONE_FAILURE, &txdesc.flags); + } txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); rt2x00pci_txdone(rt2x00dev, entry, &txdesc); diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index c06f1b5e5887d310ede169c9e25b2664b85b6eda..aa195dab15541b3e7f11cfd3b4bf338e3ed0fc1f 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1292,7 +1292,18 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, /* * Obtain the status about this packet. */ - txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT); + txdesc.flags = 0; + switch (rt2x00_get_field32(word, TXD_W0_RESULT)) { + case 0: /* Success */ + case 1: /* Success with retry */ + __set_bit(TXDONE_SUCCESS, &txdesc.flags); + break; + case 2: /* Failure, excessive retries */ + __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags); + /* Don't break, this is a failed frame! */ + default: /* Failure */ + __set_bit(TXDONE_FAILURE, &txdesc.flags); + } txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); rt2x00pci_txdone(rt2x00dev, entry, &txdesc); diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index ea130f2eb008439180ae79c256eca1565eb67b31..69da22cf085c12bc3fb3b41d349f04b8bbb4186a 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, struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct skb_frame_desc *skbdesc; struct ieee80211_tx_status tx_status; - int success = !!(txdesc->status == TX_SUCCESS || - txdesc->status == TX_SUCCESS_RETRY); - int fail = !!(txdesc->status == TX_FAIL_RETRY || - txdesc->status == TX_FAIL_INVALID || - txdesc->status == TX_FAIL_OTHER); /* * Update TX statistics. */ - rt2x00dev->link.qual.tx_success += success; - rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; + rt2x00dev->link.qual.tx_success += + test_bit(TXDONE_SUCCESS, &txdesc->flags); + rt2x00dev->link.qual.tx_failed += + txdesc->retry + !!test_bit(TXDONE_FAILURE, &txdesc->flags); /* * Initialize TX status */ tx_status.flags = 0; tx_status.ack_signal = 0; - tx_status.excessive_retries = (txdesc->status == TX_FAIL_RETRY); + tx_status.excessive_retries = + test_bit(TXDONE_EXCESSIVE_RETRY, &txdesc->flags); tx_status.retry_count = txdesc->retry; memcpy(&tx_status.control, txdesc->control, sizeof(*txdesc->control)); if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) { - if (success) + if (test_bit(TXDONE_SUCCESS, &txdesc->flags)) tx_status.flags |= IEEE80211_TX_STATUS_ACK; - else + else if (test_bit(TXDONE_FAILURE, &txdesc->flags)) rt2x00dev->low_level_stats.dot11ACKFailureCount++; } if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { - if (success) + if (test_bit(TXDONE_SUCCESS, &txdesc->flags)) rt2x00dev->low_level_stats.dot11RTSSuccessCount++; - else + else if (test_bit(TXDONE_FAILURE, &txdesc->flags)) rt2x00dev->low_level_stats.dot11RTSFailureCount++; } @@ -546,7 +544,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb, &tx_status); else - dev_kfree_skb(entry->skb); + dev_kfree_skb_irq(entry->skb); entry->skb = NULL; } EXPORT_SYMBOL_GPL(rt2x00lib_txdone); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index c3493ed7f4c3afd7db38d2168d1b365cc0a7d22f..f361f784965edfa0754aa936ca7ba7c30e559a71 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -167,6 +167,22 @@ struct rxdone_entry_desc { int dev_flags; }; +/** + * enum txdone_entry_desc_flags: Flags for &struct txdone_entry_desc + * + * @TXDONE_UNKNOWN: Hardware could not determine success of transmission. + * @TXDONE_SUCCESS: Frame was successfully send + * @TXDONE_FAILURE: Frame was not successfully send + * @TXDONE_EXCESSIVE_RETRY: In addition to &TXDONE_FAILURE, the + * frame transmission failed due to excessive retries. + */ +enum txdone_entry_desc_flags { + TXDONE_UNKNOWN = 1 << 0, + TXDONE_SUCCESS = 1 << 1, + TXDONE_FAILURE = 1 << 2, + TXDONE_EXCESSIVE_RETRY = 1 << 3, +}; + /** * struct txdone_entry_desc: TX done entry descriptor * @@ -174,12 +190,12 @@ struct rxdone_entry_desc { * after the device is done with transmission. * * @control: Control structure which was used to transmit the frame. - * @status: TX status (See &enum tx_status). + * @flags: TX done flags (See &enum txdone_entry_desc_flags). * @retry: Retry count. */ struct txdone_entry_desc { struct ieee80211_tx_control *control; - int status; + unsigned long flags; int retry; }; diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index 0325bed2fbf599c7207efdd5ee44cf808aabecf4..3f255df58b781a2d5daed14ea18bc6db89916515 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h @@ -26,17 +26,6 @@ #ifndef RT2X00REG_H #define RT2X00REG_H -/* - * TX result flags. - */ -enum tx_status { - TX_SUCCESS = 0, - TX_SUCCESS_RETRY = 1, - TX_FAIL_RETRY = 2, - TX_FAIL_INVALID = 3, - TX_FAIL_OTHER = 4, -}; - /* * Antenna values */ diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 98aafc2d584a051c0a52df7c129f2f048c5cdf1f..caee65e821986ce4caebec5a71d4fb067f9f73b3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -147,8 +147,17 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) /* * Obtain the status about this packet. + * Note that when the status is 0 it does not mean the + * frame was send out correctly. It only means the frame + * was succesfully pushed to the hardware, we have no + * way to determine the transmission status right now. + * (Only indirectly by looking at the failed TX counters + * in the register). */ - txdesc.status = !urb->status ? TX_SUCCESS : TX_FAIL_RETRY; + if (!urb->status) + __set_bit(TXDONE_UNKNOWN, &txdesc.flags); + else + __set_bit(TXDONE_FAILURE, &txdesc.flags); txdesc.retry = 0; txdesc.control = &priv_tx->control; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index edddbf35bbaba6903149c9309ca2abdd394a819a..15191d6581b18466746af16e8b51ae66c9e37356 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1764,7 +1764,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) "TX status report missed for entry %d\n", entry_done->entry_idx); - txdesc.status = TX_FAIL_OTHER; + txdesc.flags = 0; + __set_bit(TXDONE_UNKNOWN, &txdesc.flags); txdesc.retry = 0; rt2x00pci_txdone(rt2x00dev, entry_done, &txdesc); @@ -1774,7 +1775,17 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) /* * Obtain the status about this packet. */ - txdesc.status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); + txdesc.flags = 0; + switch (rt2x00_get_field32(reg, STA_CSR4_TX_RESULT)) { + case 0: /* Success, maybe with retry */ + __set_bit(TXDONE_SUCCESS, &txdesc.flags); + break; + case 6: /* Failure, excessive retries */ + __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags); + /* Don't break, this is a failed frame! */ + default: /* Failure */ + __set_bit(TXDONE_FAILURE, &txdesc.flags); + } txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); rt2x00pci_txdone(rt2x00dev, entry, &txdesc);