Commit baf26a7e authored by Ivo van Doorn's avatar Ivo van Doorn Committed by John W. Linville

rt2x00: Don't report driver generated frames to tx_status()

This adds a new flag for the skb_frame_desc structure which is used to tag
rts/cts frames that are generated by the driver. Through the tag we can
recognize frames we have generated ourselves, so we don't report their tx
status to mac80211.

This patch is based on the original patch by
Mattias Nissler <mattias.nissler@gmx.de>.
Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent ac1aa7e4
...@@ -1531,6 +1531,7 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, ...@@ -1531,6 +1531,7 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
*/ */
skbdesc = get_skb_frame_desc(skb); skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc)); memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
skbdesc->data = skb->data; skbdesc->data = skb->data;
skbdesc->data_len = skb->len; skbdesc->data_len = skb->len;
skbdesc->desc = priv_tx->desc; skbdesc->desc = priv_tx->desc;
......
...@@ -1843,6 +1843,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, ...@@ -1843,6 +1843,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
*/ */
skbdesc = get_skb_frame_desc(skb); skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc)); memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
skbdesc->data = skb->data; skbdesc->data = skb->data;
skbdesc->data_len = skb->len; skbdesc->data_len = skb->len;
skbdesc->desc = priv_tx->desc; skbdesc->desc = priv_tx->desc;
......
...@@ -1751,6 +1751,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, ...@@ -1751,6 +1751,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
*/ */
skbdesc = get_skb_frame_desc(skb); skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc)); memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
skbdesc->data = skb->data + intf->beacon->queue->desc_size; skbdesc->data = skb->data + intf->beacon->queue->desc_size;
skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
skbdesc->desc = skb->data; skbdesc->desc = skb->data;
......
...@@ -500,6 +500,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, ...@@ -500,6 +500,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc) struct txdone_entry_desc *txdesc)
{ {
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct skb_frame_desc *skbdesc;
struct ieee80211_tx_status tx_status; struct ieee80211_tx_status tx_status;
int success = !!(txdesc->status == TX_SUCCESS || int success = !!(txdesc->status == TX_SUCCESS ||
txdesc->status == TX_SUCCESS_RETRY); txdesc->status == TX_SUCCESS_RETRY);
...@@ -540,12 +541,23 @@ void rt2x00lib_txdone(struct queue_entry *entry, ...@@ -540,12 +541,23 @@ void rt2x00lib_txdone(struct queue_entry *entry,
} }
/* /*
* Send the tx_status to mac80211 & debugfs. * Send the tx_status to debugfs. Only send the status report
* mac80211 will clean up the skb structure. * 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); 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; entry->skb = NULL;
} }
EXPORT_SYMBOL_GPL(rt2x00lib_txdone); EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
......
...@@ -34,6 +34,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, ...@@ -34,6 +34,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
struct sk_buff *frag_skb, struct sk_buff *frag_skb,
struct ieee80211_tx_control *control) struct ieee80211_tx_control *control)
{ {
struct skb_frame_desc *skbdesc;
struct sk_buff *skb; struct sk_buff *skb;
int size; int size;
...@@ -60,6 +61,13 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, ...@@ -60,6 +61,13 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
frag_skb->data, frag_skb->len, control, frag_skb->data, frag_skb->len, control,
(struct ieee80211_rts *)(skb->data)); (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)) { if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) {
WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
...@@ -74,6 +82,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, ...@@ -74,6 +82,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
struct rt2x00_dev *rt2x00dev = hw->priv; struct rt2x00_dev *rt2x00dev = hw->priv;
struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
struct data_queue *queue; struct data_queue *queue;
struct skb_frame_desc *skbdesc;
u16 frame_control; u16 frame_control;
/* /*
...@@ -121,6 +130,12 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, ...@@ -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)) { if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) {
ieee80211_stop_queue(rt2x00dev->hw, control->queue); ieee80211_stop_queue(rt2x00dev->hw, control->queue);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
......
...@@ -61,7 +61,6 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, ...@@ -61,7 +61,6 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
* Fill in skb descriptor * Fill in skb descriptor
*/ */
skbdesc = get_skb_frame_desc(skb); skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->data = skb->data; skbdesc->data = skb->data;
skbdesc->data_len = skb->len; skbdesc->data_len = skb->len;
skbdesc->desc = priv_tx->desc; skbdesc->desc = priv_tx->desc;
......
...@@ -81,13 +81,23 @@ enum rt2x00_bcn_queue { ...@@ -81,13 +81,23 @@ enum rt2x00_bcn_queue {
RT2X00_BCN_QUEUE_ATIM = 101, 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 * struct skb_frame_desc: Descriptor information for the skb buffer
* *
* This structure is placed over the skb->cb array, this means that * This structure is placed over the skb->cb array, this means that
* this structure should not exceed the size of that array (48 bytes). * 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. * @frame_type: Frame type, see &enum rt2x00_dump_type.
* @data: Pointer to data part of frame (Start of ieee80211 header). * @data: Pointer to data part of frame (Start of ieee80211 header).
* @desc: Pointer to descriptor part of the frame. * @desc: Pointer to descriptor part of the frame.
......
...@@ -252,7 +252,6 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, ...@@ -252,7 +252,6 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
* Fill in skb descriptor * Fill in skb descriptor
*/ */
skbdesc = get_skb_frame_desc(skb); skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->data = skb->data + queue->desc_size; skbdesc->data = skb->data + queue->desc_size;
skbdesc->data_len = skb->len - queue->desc_size; skbdesc->data_len = skb->len - queue->desc_size;
skbdesc->desc = skb->data; skbdesc->desc = skb->data;
......
...@@ -2400,6 +2400,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, ...@@ -2400,6 +2400,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
*/ */
skbdesc = get_skb_frame_desc(skb); skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc)); memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
skbdesc->data = skb->data + intf->beacon->queue->desc_size; skbdesc->data = skb->data + intf->beacon->queue->desc_size;
skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
skbdesc->desc = skb->data; skbdesc->desc = skb->data;
......
...@@ -2002,6 +2002,7 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, ...@@ -2002,6 +2002,7 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
*/ */
skbdesc = get_skb_frame_desc(skb); skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc)); memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
skbdesc->data = skb->data + intf->beacon->queue->desc_size; skbdesc->data = skb->data + intf->beacon->queue->desc_size;
skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
skbdesc->desc = skb->data; skbdesc->desc = skb->data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment