rt2x00: Don't report driver generated frames to tx_status()
authorIvo van Doorn <ivdoorn@gmail.com>
Sun, 17 Feb 2008 16:32:08 +0000 (17:32 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 29 Feb 2008 20:37:22 +0000 (15:37 -0500)
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: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00queue.h
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c

index 23bc51a96dbe023773059cfb4cedf3a71234d3e0..52ccb85fed659d109cdc71b317250151f38000fe 100644 (file)
@@ -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;
index 529b1841a0854cda81107ba8ee8482bc1d7a5b57..3bf85604ca698559fef87e75f3d229efb1e0eaba 100644 (file)
@@ -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;
index f9d6f539a80fbf04bcfb22267abddc16434f1a2c..f7dc06a74d1a4a1b95a3bc600ee46e761f09f1cd 100644 (file)
@@ -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;
index d69f7407b9729951ef0bc1ab3ef75d67a9989fee..6ccbfc7cbf91f61afc08a096c08bce4affa4f1e4 100644 (file)
@@ -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);
index 91b62ddbf9f040619e9a71c290b961c5400b0141..a54f6873e9ea2ff271853162e08c4e4494bdb699 100644 (file)
@@ -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;
index 8f88ca23c23a0840c427e34d294571d730bfbe45..7d2f406937cd8480fff73e333c95282242adc084 100644 (file)
@@ -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;
index 956e0be8aadd6d716998d85a55cd1b3c2f7c33f6..fbabf389b62269cdc01c7d153015354caedb09de 100644 (file)
@@ -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.
index 6cb4432e1ee0e040ae69cda57e183842e856bef6..89471b24a44385ee8393b5e9625721dc65ecaf82 100644 (file)
@@ -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;
index d10273b744e45f7975686aa1ea3d3c4948bc50c3..357f2c4183f6ed5f2e47f85b21a588b4967766e8 100644 (file)
@@ -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;
index badae9f18153381c123a7e3782233a84171f6e4a..afd8533267a77351e4d263c1c02e3b6cf60cab57 100644 (file)
@@ -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;