diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 23bc51a96dbe023773059cfb4cedf3a71234d3e0..52ccb85fed659d109cdc71b317250151f38000fe 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1531,6 +1531,7 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 	 */
 	skbdesc = get_skb_frame_desc(skb);
 	memset(skbdesc, 0, sizeof(*skbdesc));
+	skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
 	skbdesc->data = skb->data;
 	skbdesc->data_len = skb->len;
 	skbdesc->desc = priv_tx->desc;
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 529b1841a0854cda81107ba8ee8482bc1d7a5b57..3bf85604ca698559fef87e75f3d229efb1e0eaba 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1843,6 +1843,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 	 */
 	skbdesc = get_skb_frame_desc(skb);
 	memset(skbdesc, 0, sizeof(*skbdesc));
+	skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
 	skbdesc->data = skb->data;
 	skbdesc->data_len = skb->len;
 	skbdesc->desc = priv_tx->desc;
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index f9d6f539a80fbf04bcfb22267abddc16434f1a2c..f7dc06a74d1a4a1b95a3bc600ee46e761f09f1cd 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1751,6 +1751,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
 	 */
 	skbdesc = get_skb_frame_desc(skb);
 	memset(skbdesc, 0, sizeof(*skbdesc));
+	skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
 	skbdesc->data = skb->data + intf->beacon->queue->desc_size;
 	skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
 	skbdesc->desc = skb->data;
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index d69f7407b9729951ef0bc1ab3ef75d67a9989fee..6ccbfc7cbf91f61afc08a096c08bce4affa4f1e4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -500,6 +500,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 		      struct txdone_entry_desc *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);
@@ -540,12 +541,23 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 	}
 
 	/*
-	 * Send the tx_status to mac80211 & debugfs.
-	 * mac80211 will clean up the skb structure.
+	 * Send the tx_status to debugfs. Only send the status report
+	 * to mac80211 when the frame originated from there. If this was
+	 * a extra frame coming through a mac80211 library call (RTS/CTS)
+	 * then we should not send the status report back.
+	 * If send to mac80211, mac80211 will clean up the skb structure,
+	 * otherwise we have to do it ourself.
 	 */
-	get_skb_frame_desc(entry->skb)->frame_type = DUMP_FRAME_TXDONE;
+	skbdesc = get_skb_frame_desc(entry->skb);
+	skbdesc->frame_type = DUMP_FRAME_TXDONE;
+
 	rt2x00debug_dump_frame(rt2x00dev, entry->skb);
-	ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb, &tx_status);
+
+	if (!(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED))
+		ieee80211_tx_status_irqsafe(rt2x00dev->hw,
+					    entry->skb, &tx_status);
+	else
+		dev_kfree_skb(entry->skb);
 	entry->skb = NULL;
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 91b62ddbf9f040619e9a71c290b961c5400b0141..a54f6873e9ea2ff271853162e08c4e4494bdb699 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -34,6 +34,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
 				struct sk_buff *frag_skb,
 				struct ieee80211_tx_control *control)
 {
+	struct skb_frame_desc *skbdesc;
 	struct sk_buff *skb;
 	int size;
 
@@ -60,6 +61,13 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
 				  frag_skb->data, frag_skb->len, control,
 				  (struct ieee80211_rts *)(skb->data));
 
+	/*
+	 * Initialize skb descriptor
+	 */
+	skbdesc = get_skb_frame_desc(skb);
+	memset(skbdesc, 0, sizeof(*skbdesc));
+	skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
+
 	if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) {
 		WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
 		return NETDEV_TX_BUSY;
@@ -74,6 +82,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
 	struct rt2x00_dev *rt2x00dev = hw->priv;
 	struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
 	struct data_queue *queue;
+	struct skb_frame_desc *skbdesc;
 	u16 frame_control;
 
 	/*
@@ -121,6 +130,12 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
 		}
 	}
 
+	/*
+	 * Initialize skb descriptor
+	 */
+	skbdesc = get_skb_frame_desc(skb);
+	memset(skbdesc, 0, sizeof(*skbdesc));
+
 	if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) {
 		ieee80211_stop_queue(rt2x00dev->hw, control->queue);
 		return NETDEV_TX_BUSY;
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 8f88ca23c23a0840c427e34d294571d730bfbe45..7d2f406937cd8480fff73e333c95282242adc084 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -61,7 +61,6 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
 	 * Fill in skb descriptor
 	 */
 	skbdesc = get_skb_frame_desc(skb);
-	memset(skbdesc, 0, sizeof(*skbdesc));
 	skbdesc->data = skb->data;
 	skbdesc->data_len = skb->len;
 	skbdesc->desc = priv_tx->desc;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 956e0be8aadd6d716998d85a55cd1b3c2f7c33f6..fbabf389b62269cdc01c7d153015354caedb09de 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -81,13 +81,23 @@ enum rt2x00_bcn_queue {
 	RT2X00_BCN_QUEUE_ATIM = 101,
 };
 
+/**
+ * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc
+ *
+ * @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver
+ *	and should not be reported back to mac80211 during txdone.
+ */
+enum skb_frame_desc_flags {
+	FRAME_DESC_DRIVER_GENERATED = 1 << 0,
+};
+
 /**
  * struct skb_frame_desc: Descriptor information for the skb buffer
  *
  * This structure is placed over the skb->cb array, this means that
  * this structure should not exceed the size of that array (48 bytes).
  *
- * @flags: Frame flags.
+ * @flags: Frame flags, see &enum skb_frame_desc_flags.
  * @frame_type: Frame type, see &enum rt2x00_dump_type.
  * @data: Pointer to data part of frame (Start of ieee80211 header).
  * @desc: Pointer to descriptor part of the frame.
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 6cb4432e1ee0e040ae69cda57e183842e856bef6..89471b24a44385ee8393b5e9625721dc65ecaf82 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -252,7 +252,6 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
 	 * Fill in skb descriptor
 	 */
 	skbdesc = get_skb_frame_desc(skb);
-	memset(skbdesc, 0, sizeof(*skbdesc));
 	skbdesc->data = skb->data + queue->desc_size;
 	skbdesc->data_len = skb->len - queue->desc_size;
 	skbdesc->desc = skb->data;
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index d10273b744e45f7975686aa1ea3d3c4948bc50c3..357f2c4183f6ed5f2e47f85b21a588b4967766e8 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2400,6 +2400,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 	 */
 	skbdesc = get_skb_frame_desc(skb);
 	memset(skbdesc, 0, sizeof(*skbdesc));
+	skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
 	skbdesc->data = skb->data + intf->beacon->queue->desc_size;
 	skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
 	skbdesc->desc = skb->data;
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index badae9f18153381c123a7e3782233a84171f6e4a..afd8533267a77351e4d263c1c02e3b6cf60cab57 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2002,6 +2002,7 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 	 */
 	skbdesc = get_skb_frame_desc(skb);
 	memset(skbdesc, 0, sizeof(*skbdesc));
+	skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
 	skbdesc->data = skb->data + intf->beacon->queue->desc_size;
 	skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
 	skbdesc->desc = skb->data;