P54_CONTROL_TYPE_BT_OPTIONS = 35
 };
 
+#define P54_HDR_FLAG_CONTROL           BIT(15)
+#define P54_HDR_FLAG_CONTROL_OPSET     (BIT(15) + BIT(0))
+
 struct p54_hdr {
        __le16 flags;
        __le16 len;
        u8 data[0];
 } __attribute__ ((packed));
 
+#define FREE_AFTER_TX(skb)                                             \
+       ((((struct p54_hdr *) ((struct sk_buff *) skb)->data)->         \
+       flags) == cpu_to_le16(P54_HDR_FLAG_CONTROL_OPSET))
+
 struct p54_edcf_queue_param {
        __le16 aifs;
        __le16 cwmin;
        u32 rx_start;
        u32 rx_end;
        struct sk_buff_head tx_queue;
-       void (*tx)(struct ieee80211_hw *dev, struct sk_buff *skb,
-                  int free_on_tx);
+       void (*tx)(struct ieee80211_hw *dev, struct sk_buff *skb);
        int (*open)(struct ieee80211_hw *dev);
        void (*stop)(struct ieee80211_hw *dev);
        int mode;
 
                freed = priv->rx_end - last_addr;
        __skb_unlink(skb, &priv->tx_queue);
        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
-       kfree_skb(skb);
+       dev_kfree_skb_any(skb);
 
        if (freed >= priv->headroom + sizeof(struct p54_hdr) + 48 +
                     IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
                        eeprom_hdr->v2.magic2 = 0xf;
                        memcpy(eeprom_hdr->v2.magic, (const char *)"LOCK", 4);
                }
-               priv->tx(dev, skb, 0);
+               priv->tx(dev, skb);
 
                if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) {
                        printk(KERN_ERR "%s: device does not respond!\n",
        tim = (struct p54_tim *) skb_put(skb, sizeof(*tim));
        tim->count = 1;
        tim->entry[0] = cpu_to_le16(set ? (sta->aid | 0x8000) : sta->aid);
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
 
        sta = (struct p54_sta_unlock *)skb_put(skb, sizeof(*sta));
        memcpy(sta->addr, addr, ETH_ALEN);
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
        hdr = (void *)entry->data;
        cancel = (struct p54_txcancel *)skb_put(skb, sizeof(*cancel));
        cancel->req_id = hdr->req_id;
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
        /* modifies skb->cb and with it info, so must be last! */
        if (unlikely(p54_assign_address(dev, skb, hdr, skb->len + tim_len)))
                goto err;
-       priv->tx(dev, skb, 0);
+       priv->tx(dev, skb);
 
        queue_delayed_work(dev->workqueue, &priv->work,
                           msecs_to_jiffies(P54_TX_FRAME_LIFETIME));
                setup->v2.lpf_bandwidth = cpu_to_le16(65535);
                setup->v2.osc_start_delay = cpu_to_le16(65535);
        }
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
                chan->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
                memset(chan->v2.rts_rates, 0, 8);
        }
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 
  err:
        led->led_permanent = cpu_to_le16(link);
        led->led_temporary = cpu_to_le16(act);
        led->duration = cpu_to_le16(1000);
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
        edcf->flags = 0;
        memset(edcf->mapping, 0, sizeof(edcf->mapping));
        memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue));
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
        xbow->magic2 = cpu_to_le16(0x2);
        xbow->freq = cpu_to_le16(5390);
        memset(xbow->padding, 0, sizeof(xbow->padding));
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
        if (!skb)
                return ;
 
-       priv->tx(dev, skb, 0);
+       priv->tx(dev, skb);
 }
 
 static int p54_get_stats(struct ieee80211_hw *dev,
                        [NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]), 8);
        }
 
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        mutex_unlock(&priv->conf_mutex);
        return 0;
 }
 
 #define BR_CODE_END_OF_BRA             0xFF0000FF
 #define LEGACY_BR_CODE_END_OF_BRA      0xFFFFFFFF
 
-#define P54_HDR_FLAG_CONTROL           BIT(15)
-#define P54_HDR_FLAG_CONTROL_OPSET     (BIT(15) + BIT(0))
-
 #define P54_HDR_FLAG_DATA_ALIGN                BIT(14)
 #define P54_HDR_FLAG_DATA_OUT_PROMISC  BIT(0)
 #define P54_HDR_FLAG_DATA_OUT_TIMESTAMP BIT(1)
 
 
        while (i != idx) {
                desc = &ring[i];
-               p54_free_skb(dev, tx_buf[i]);
+               if (tx_buf[i])
+                       if (FREE_AFTER_TX((struct sk_buff *) tx_buf[i]))
+                               p54_free_skb(dev, tx_buf[i]);
                tx_buf[i] = NULL;
 
                pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
        return reg ? IRQ_HANDLED : IRQ_NONE;
 }
 
-static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
-                   int free_on_tx)
+static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct p54p_priv *priv = dev->priv;
        struct p54p_ring_control *ring_control = priv->ring_control;
        idx = le32_to_cpu(ring_control->host_idx[1]);
        i = idx % ARRAY_SIZE(ring_control->tx_data);
 
+       priv->tx_buf_data[i] = skb;
        mapping = pci_map_single(priv->pdev, skb->data, skb->len,
                                 PCI_DMA_TODEVICE);
        desc = &ring_control->tx_data[i];
 
        wmb();
        ring_control->host_idx[1] = cpu_to_le32(idx + 1);
-
-       if (free_on_tx)
-               priv->tx_buf_data[i] = skb;
-
        spin_unlock_irqrestore(&priv->lock, flags);
 
        P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
 
        }
 }
 
-static void p54u_tx_reuse_skb_cb(struct urb *urb)
-{
-       struct sk_buff *skb = urb->context;
-       struct p54u_priv *priv = (struct p54u_priv *)((struct ieee80211_hw *)
-               usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)))->priv;
-
-       skb_pull(skb, priv->common.tx_hdr_len);
-}
-
-static void p54u_tx_free_skb_cb(struct urb *urb)
+static void p54u_tx_cb(struct urb *urb)
 {
        struct sk_buff *skb = urb->context;
        struct ieee80211_hw *dev = (struct ieee80211_hw *)
                usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+       struct p54u_priv *priv = dev->priv;
 
-       p54_free_skb(dev, skb);
+       skb_pull(skb, priv->common.tx_hdr_len);
+       if (FREE_AFTER_TX(skb))
+               p54_free_skb(dev, skb);
 }
 
 static void p54u_tx_dummy_cb(struct urb *urb) { }
        return ret;
 }
 
-static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb,
-                        int free_on_tx)
+static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct p54u_priv *priv = dev->priv;
        struct urb *addr_urb, *data_urb;
                          p54u_tx_dummy_cb, dev);
        usb_fill_bulk_urb(data_urb, priv->udev,
                          usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
-                         skb->data, skb->len,
-                         free_on_tx ? p54u_tx_free_skb_cb :
-                                      p54u_tx_reuse_skb_cb, skb);
+                         skb->data, skb->len, p54u_tx_cb, skb);
 
        usb_anchor_urb(addr_urb, &priv->submitted);
        err = usb_submit_urb(addr_urb, GFP_ATOMIC);
        return cpu_to_le32(chk);
 }
 
-static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb,
-                        int free_on_tx)
+static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct p54u_priv *priv = dev->priv;
        struct urb *data_urb;
 
        usb_fill_bulk_urb(data_urb, priv->udev,
                          usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
-                         skb->data, skb->len,
-                         free_on_tx ? p54u_tx_free_skb_cb :
-                                      p54u_tx_reuse_skb_cb, skb);
+                         skb->data, skb->len, p54u_tx_cb, skb);
 
        usb_anchor_urb(data_urb, &priv->submitted);
        if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
        usb_free_urb(data_urb);
 }
 
-static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb,
-                           int free_on_tx)
+static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct p54u_priv *priv = dev->priv;
        struct urb *int_urb, *data_urb;
 
        usb_fill_bulk_urb(data_urb, priv->udev,
                          usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
-                         skb->data, skb->len,
-                         free_on_tx ? p54u_tx_free_skb_cb :
-                                      p54u_tx_reuse_skb_cb, skb);
+                         skb->data, skb->len, p54u_tx_cb, skb);
 
        usb_anchor_urb(int_urb, &priv->submitted);
        err = usb_submit_urb(int_urb, GFP_ATOMIC);