p54: remove free_on_tx parameter

This patch simplifies the tx code a bit and will be necessary for
the upcoming stlc45xx<->p54 port.

In detail: we no longer have to tell all back-end drivers directly,
if we want to free a frame right after it was send to the firmware,
or if we do it in the library callback later.

Signed-off-by: Christian Lamparter <chunkeey@web.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index e0a6881..ab79e32 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -44,6 +44,9 @@
 	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;
@@ -54,6 +57,10 @@
 	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;
@@ -82,8 +89,7 @@
 	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;
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 05eb677..82354b9 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -683,7 +683,7 @@
 		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)
@@ -1088,7 +1088,7 @@
 			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",
@@ -1129,7 +1129,7 @@
 	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;
 }
 
@@ -1147,7 +1147,7 @@
 
 	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;
 }
 
@@ -1190,7 +1190,7 @@
 	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;
 }
 
@@ -1419,7 +1419,7 @@
 	/* 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));
@@ -1498,7 +1498,7 @@
 		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;
 }
 
@@ -1579,7 +1579,7 @@
 		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:
@@ -1605,7 +1605,7 @@
 	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;
 }
 
@@ -1645,7 +1645,7 @@
 	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;
 }
 
@@ -1936,7 +1936,7 @@
 	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;
 }
 
@@ -1962,7 +1962,7 @@
 	if (!skb)
 		return ;
 
-	priv->tx(dev, skb, 0);
+	priv->tx(dev, skb);
 }
 
 static int p54_get_stats(struct ieee80211_hw *dev,
@@ -2094,7 +2094,7 @@
 			[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]), 8);
 	}
 
-	priv->tx(dev, skb, 1);
+	priv->tx(dev, skb);
 	mutex_unlock(&priv->conf_mutex);
 	return 0;
 }
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
index 6c824e4..f5729de 100644
--- a/drivers/net/wireless/p54/p54common.h
+++ b/drivers/net/wireless/p54/p54common.h
@@ -84,9 +84,6 @@
 #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)
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index c28220e..aa367a0 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -227,7 +227,9 @@
 
 	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),
@@ -298,8 +300,7 @@
 	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;
@@ -314,6 +315,7 @@
 	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];
@@ -324,10 +326,6 @@
 
 	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));
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index c2789e5..17f89c7 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -138,22 +138,16 @@
 	}
 }
 
-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) { }
@@ -213,8 +207,7 @@
 	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;
@@ -236,9 +229,7 @@
 			  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);
@@ -273,8 +264,7 @@
 	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;
@@ -293,9 +283,7 @@
 
 	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)) {
@@ -306,8 +294,7 @@
 	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;
@@ -354,9 +341,7 @@
 
 	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);