/*
* 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);
/*
* 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);
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++;
}
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);
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
*
* 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;
};
#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
*/
/*
* 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;
"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);
/*
* 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);