*/
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;
*/
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;
*/
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;
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);
}
/*
- * 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);
struct sk_buff *frag_skb,
struct ieee80211_tx_control *control)
{
+ struct skb_frame_desc *skbdesc;
struct sk_buff *skb;
int size;
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;
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;
/*
}
}
+ /*
+ * 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;
* 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;
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.
* 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;
*/
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;
*/
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;